Accumulating plot of data and fit in Matlab - matlab

I have a Matlab script that imports data from a file and creates an exponential fit. I want the script to plot the data points and the fit using the same colour. The legend should be the name of the data file. When I run this same script again for another input file I want the new data and fit to be displayed in the same plot window name of the new data file added to the legend.
What I have so far is this;
expfit = fit(x,y,'exp1')
figure(1)
hold all
plot(x,y,'*','DisplayName','fileName)
legend('Interpreter','none')
legend show
using
plot(expfit,x,y,'DisplayName','fileName')
does not work
How can I add the fitted line to each data using the same colour as the data and
adding the filenames to the legend ?

You're close...
An easy way is to get the colours up front
c = parula(7); % default colour map with 7 colours
figure(1); clf;
hold on
% filename is a variable e.g. filename = 'blah.csv'; from where the data was loaded
plot( x, y, '*', 'DisplayName', filename, 'color', c(1,:) );
plot( expfit, x, y, '-', 'HandleVisibility', 'off', 'color', c(1,:) );
legend('show');
Note by setting HandleVisibility off the fit will not show up in the legend. This is personal preference, I only like one entry for the data and the fit, you could instead use the DisplayName on the 2nd plot too.
Both plots use the same colour using the color input. I've used the first row of the colour map for both, if you plotted some other data you could use the 2nd row etc.
The alternative is to let MATLAB determine the colour automatically and just copy the colour over for the 2nd plot, you need to create a variable (p) of the first plot to get the colour
p = plot( x, y, '*', 'DisplayName', filename );
plot( expfit, x, y, '-', 'HandleVisibility', 'off', 'color', p.Color );
The other code would be the same.

Related

matlab : suppress legend entry without removing from Plot Browser

One can suppress a legend entry for a line object h by executing h.HandleVisibility='off' or h.Annotation.LegendInformation.IconDisplayStyle='off'. However, both actions also prevent the curve from appearing in Matlab's Plot Browser user interface, and thus display of the curve cannot be interactively toggled.
Is there any way to suppress a legend entry for a given curve without also removing the ability to toggle display of that curve in the Plot Browser user interface?
You can also turn off handle visibility. This is way easier than having to set every plot as h1 = ...
Example:
x1 = randperm(10);
y = randperm(10);
x2 = randperm(10);
plot(x1, y, '-', 'Color', 'black', 'HandleVisibility', 'off')
hold on
plot(x2, y, '-', 'Color', 'green', 'DisplayName', 'Put This In Legend')
lgd = legend;
set(lgd, 'Location', 'best')
MATLAB's legend function accepts an optional argument listing the handles to include in the legend:
figure, hold on
h1 = plot(1,1,'ro');
h2 = plot(1,2,'gx');
h3 = plot(2,1,'m*');
legend([h1,h3]); % don't make a legend for h2.

How to add an independent text in MATLAB plot legend

I need an additional text in the legend that is not related with graphical data together with the legend captions.
Something like this (it was made in OriginLab):
Following to this link Add custom legend without any relation to the graph
I can add some text using plot(NaN,NaN,'display','add info here2', 'linestyle', 'none'). But there is an indent in this text:
How to avoid this indent? And is there a more elegant method to add the text that is not associated with the legend together with the legend captions?
The legend function will return as its second output argument handles for all of the components that make up the symbols and text in the legend. You can therefore plot "dummy" lines as placeholders in the legend, reorder the handles when creating the legend to put the text where you want it, and modify the legend objects accordingly. Here's an example:
x = linspace(0, 2*pi, 100);
hl = plot(x, [sin(x); cos(x); tan(x); nan(size(x))].'); % Add a line of NaNs
axis([0 2*pi -4 4]);
[~, objH] = legend(hl([1 2 4 3]), 'sin', 'cos', 'junk', 'tan'); % Reorder handles
set(findobj(objH, 'Tag', 'junk'), 'Vis', 'off'); % Make "junk" lines invisible
pos = get(objH(3), 'Pos'); % Get text box position
set(objH(3), 'Pos', [0.1 pos(2:3)], 'String', 'also...'); % Stretch box and change text
You can use annotations. It's not perfect, but with few adjustments you'll get what you want. Here's an example:
% somthing to plot:
x = [0:0.1:5; 5:0.1:10].';
y = sin(x);
% plot the real data:
plot(x,y);
hold on
% make some space in the legend:
Spacing_lines = 3;
h = plot(nan(size(x,1),Spacing_lines));
hold off
set(h,{'Color'},{'w'}); % clear the dummy lines
% place the legend:
hl = legend([{'lable1','lable2'} repmat({''},1,Spacing_lines)]);
% add your text:
annotation('textbox',hl.Position,'String',{'Some info';'in 2 lines'},...
'VerticalAlignment','Bottom','Edgecolor','none');
And from this you get:
You can just add any text to any point of plot in this way:
txt1 = 'some information';
text(x1,y1,txt1)
where x1, y1 - coordinates.
By the way function text function has a lot of different properties (colors, font size, alignment etc.).
I think the easiest way is to just create some dummy function, plot it but set the color="none" - that way it will only show up in the legend (if that is where you wanted it).

Matlab legend for two plots only applies to second plot

I need to plot data of two vectors, and want the data points of each to be shown in a different colour that is explaned in a legend. However, the code below displays only the legend for the second one. What am I doing wrong?
for i_plot = 1 : plot_step : N
subplot(N, 1, i_plot)
h_A = plot(bookmarksA(i_plot, :),0,'b.','MarkerSize',24);
legend('a');
xlim ([0 pieceDuration])
set(gca, 'yTick', []);
title(subj_string(i_plot,:))
hold on
h_Z = plot(bookmarksZ(i_plot, :),0,'r.','MarkerSize',24);
legend(h_Z, 'z');
end
You're only passing one label / handle combination to the legend command at a time. For a given axes, each call to legend overrides previous calls to legend, deleting previous legends rather than adding to an existing legend. You'll want to call legend once with both plot handles and labels.
legend([h_A, h_Z], {'a', 'z'})
Update
Since in your case h_A and h_Z are arrays of plot handles with identical appearances, you can just pass the first item from h_A and h_Z to legend.
legend([h_A(1), h_Z(1)], {'a', 'z'})

Plot rows of a 2d matrix in matlab

I have a 2d matrix A (100 x 100) where each row contains a signal to be plot.
I want to plot all of the signals in the same figure with different color for each row. How can I do this easily?
If you actually look at the documentation for plot you'll see that if you pass it a matrix, it will plot each column as a separate plot object on the same axes. As such you can simply pass the transpose of your data to plot.
% Example data
A = magic(10);
% Create a plot for each row
hplot = plot(A.');
This will plot each signal using the next plot color.
If you want to ensure that you have all different colors, you can use a colormap (such as parula) to explicitly set a different color per plot.
set(hplot, {'Color'}, num2cell(parula(size(A, 1)), 2))
Update
If you want to label your plots you could simply use legend to do this.
displaynames = arrayfun(#(x)sprintf('Plot %d', x), 1:size(A, 1), 'uni', 0);
set(hplot, {'DisplayName'}, displaynames.');
legend(hplot)
Or if you have too many plots to reasonably fit within a legend you can create an interactive plot that highlights a given plot when you mouseover it. Here is an example of such a thing.
htitle = title('');
set(gcf, 'WindowButtonMotionFcn', #(s,e)motionCallback(hittest(s)))
motionCallback(hplot(1));
function motionCallback(plt)
% Don't do anything if not a line object
[tf, ind] = ismember(plt, hplot);
if ~tf; return; end
set(hplot, 'linewidth', 1)
set(plt, 'LineWidth', 3)
set(htitle, 'String', sprintf('SelectedPlot: %d', ind))
drawnow
end
And the result

MATLAB graph plotting: assigning legend labels during plot

I am plotting data in a typical MATLAB scatterplot format. Ordinarily when plotting multiple datasets, I would use the command 'hold on;', and then plot each of the data, followed by this to get my legend:
legend('DataSet1', 'DataSet2') % etcetera
However, the (multiple) datasets I am plotting on the same axes are not necessarily the same datasets each time. I am plotting up to six different sets of data on the same axes, and there could be any combination of these shown (depending on what the user chooses to display). Obviously that would be a lot of elseif's if I wanted to setup the legend the traditional way.
What I really would like to do is assign each DataSet a name as it is plotted so that afterwards I can just call up a legend of all the data being shown.
...Or, any other solution to this problem that anyone can think of..?
You should be able to set the DisplayName property for each plot:
figure
hold on
plot(...,'DisplayName','DataSet1')
plot(...,'DisplayName','DataSet2')
legend(gca,'show')
http://www.mathworks.com/help/matlab/ref/line_props.html
Side Note: I've found a lot of little tricks like this by getting the figure to look the way I want, then choosing the Figure's "File" menu option "Generate M-File..." and inspecting the generated output code.
One option is to take advantage of the 'UserData' property like so:
figure;
hold on
plot([0 1], [1 0], '-b', 'userdata', 'blue line')
plot([1 0], [1 0], '--r', 'userdata', 'red dashes')
% legend(get(get(gca, 'children'), 'userdata')) % wrong
legend(get(gca, 'children'), get(get(gca, 'children'), 'userdata')) % correct
Edit: As the questioner pointed out, the original version could get out of order. To fix this, specify which handle goes with which label (in the fixed version, it is in the correct order).
Use 'DisplayName' as a plot() property, and call your legend as
legend('-DynamicLegend');
My code looks like this:
x = 0:h:xmax; %// get an array of x-values
y = someFunction; %// function
plot(x, y, 'DisplayName', 'Function plot 1'); %// plot with 'DisplayName' property
legend('-DynamicLegend',2); %// '-DynamicLegend' legend
Source: http://undocumentedmatlab.com/blog/legend-semi-documented-feature/
You can try something like the following
for k = 1:10
h(k) = plot(...);
name{k} = ['condition ' num2str(k)];
end
legend(h, name);
Make a for loop. But Before the for loop, make an array.
%for example
legendset = {}
for i = 1:10
%blabla
%Then in the fore loop say:
legendset = [legendset;namedata(i)]
%It puts all names in a column of legendset.
%Make sure namedata are characters.
%foreloop ends
end
%Then after the foreloop say:
legend(legendset).