Saving histograms without displaying them and adjust linewidth of plotted fit objects - matlab

I have a histogram with gaussians fitted in matlab. Here is my code:
dnbins = 100;
[counts,centers] = hist(data(:), nbins);
bar(centers, counts);
fitobject = fit(centers',counts','gauss2');hold on;
plot(fitobject,centers',counts');hold off;
How can I save the output, but without displaying it? Is it possible?
Also, I'd like to a have thicker red line, so I changed the following line:
plot(fitobject,centers',counts', 'LineWidth', 2.0);hold off;
I got the following error:
Error in color/linetype argument
Whereas this piece of code works well:
plot(centers',counts', 'LineWidth', 2.0);hold off;
Of course, it doesn't satisfy me, beacuse I want to see the fitted curve as well.
How can I change the line thickness?
Edit:
I got the following error:
This functionality is no longer supported under the -nojvm startup option.
And it makes sense, because I can't use the graphical output. I complie the code and then I run it under Linux.
How can I fix it?

First problem: you need the 'visible' property of the figure object.
...
fitobject = fit(centers',counts','gauss2'); hold on;
figure('visible','off')
plot(fitobject ,centers',counts'); hold off;
...
Second problem: using the plot function with fit-objects calls actually a different plot (cfit) function, which is part of the the Curve Fitting Toolbox. That's why the usual behavior does not apply. This little workaround however works almost always.
h = plot(fitobject, centers',counts'); hold off;
set(h, 'LineWidth',2)

Related

Individual line and axes styles with plotyy

I tried creating a plot with two YAxis like this:
x=linspace(0,20);
y1=linspace(10,10);
y2=x.^2;
y3=y2-y1;
[hAx,hLine1,hLine2]=plotyy([x',x'],[y1',y2'],x,y3);
Now i have two problem with this code:
I can change the Linestyles of the two hLines using hLine1.LineStyle = ':'; for example, but i can not change the styles of the two lines, that hLine1 consists of. Does anyone know how to do this?
I can't use hLine2.YLim = [0 100] to manually adjust the y-limits shown on the 2nd y-axis.
After I couldn't solve the problem using the plotyy, I searched the MATLAB documentation and found another way of implementing my plot, which I thought might be easier to handle:
x=linspace(0,20);
y1=linspace(10,10);
y2=x.^2;
y3=y2-y1;
figure
hold on;
line(x,y1,'Color','r')
line(x,y2,'Color','y')
ax1 = gca;
ax2 = axes('Position',ax1.Position,'YAxisLocation','right');
line(x,y3,'Parent',ax2,'Color','b')
The problem here is, that it doesn't even show the first and the second line, but only the third and i don't know why. I would prefer getting the problem solved using the plotyy, but if that's not possible I would appreciate a solution for the 2nd piece of code as well.
I think you haven't noticed that the outputs of plotyy are arrays of objects, and not single objects.
x=linspace(0,20);
y1=linspace(10,10);
y2=x.^2;
y3=y2-y1;
[hAx,hLine1,hLine2]=plotyy([x',x'],[y1',y2'],x,y3);
hLine1(1).LineStyle = '--';
hLine1(2).LineStyle = ':';
% either this
ylim( hAx(2), [0 110] );
% or alternatively
f=gcf; ylim( f.Children(2), [0 110] );
You're not seeing the first two lines because axes backgrounds are white by default. Setting the Color property of the second axes object to 'none' should give you what you're looking for:
x=linspace(0,20);
y1=linspace(10,10);
y2=x.^2;
y3=y2-y1;
figure
hold on;
line(x,y1,'Color','r')
line(x,y2,'Color','y')
ax1 = gca;
ax2 = axes('Position',ax1.Position,'YAxisLocation','right', 'Color', 'none');
line(x,y3,'Parent',ax2,'Color','b')
EDIT: I'd also recommend checking out linkaxes if you're going to be zooming/panning your axes and want to keep some or all of the axes synchronized.

Resizing of axes when plotting in the same figure

Please, create two functions to be able to reproduce what I mean:
First function:
function testPlot1()
pointData = rand(20000,3);
figure;
%hold on; % <- if commented out, does not work
plot3(pointData(:,1), pointData(:,2), pointData(:,3),'Marker', '.', 'MarkerEdgeColor', 'b','MarkerSize', 5, 'LineStyle', 'none');
axis equal;
xh = xlabel('X');
yh = ylabel('Y');
zh = zlabel('Z');
set([xh,yh, zh],...
'fontweight','bold',...
'fontsize',14,...
'color',[0,0,0]);
view(0,20);
end
Second function:
function testPlot2(fighandle)
axes(fighandle);
hold on;
plot3([0 3],[0 3],[0 3], 'r', 'LineWidth', 10);
end
If you now call
testPlot1();testPlot2(gca)
you will get the following:
If you however uncomment the "hold on" line in testPlot1() and call the above statement again, you will get:
To me this is unclear behavior. In the first case, testPlot1() creates a figure, draws the point cloud into it and modifies the axes properties. Then the call to testPlot2(gca) adds the line to the figure, but the line is clipped.
In the second case however the line is not clipped anymore. Why is it now not clipped and previously it was?
It seems to be related to the changes I make in the axes properties in testPlot1(). Could somebody explain this behavior to me? (why does it work with hold on, what do my changes in the axes properties cause)
hold on is a Matlab command (hold off turns it off again), where you can draw multiple elements on a single figure without the previous elements being erased.
What happens
If you call the plot function, a figure is created (or an already exisiting figure is used!) and Matlab draws a new plot into that figure. The previous plot that was in that figure is gone.
If you want to add more points to your plot, you can call hold on and then call plot again, this time with different numbers and maybe a different colour or so.
However, if you forget to turn hold off again for the active figure, any drawing activity you do (like plot) will be added to the figure. This is what happens in your second image in your question. You drew some points in the range 0 to 1, and then in the second function, you add some more but in the range 2 to 3. As a result, the axes expand to the range of 0 to 3.
Alternatively, you can call figure, which will cause a new figure to appear. figure_handle = figure(); will return a figure handle, which you can pass to your function, in case you have multiple figures and want to change one of them after a while.

Matlab draw 'subaxis' based subplots on specified 'axes'

I am coding some GUI staff using Matlab. And I want to plot a figure with subfigures in one specified 'axes' using 'subaxis' method (which can be download on Matlab FX subaxis.m).
The program behaves quite right at first. As the subfigures are updating by one click button. Then the error pops-up. I simplify the problem and write some testing codes as following:
% Specify an 'axes' in my GUI (here is an example of axes handle called 'ax')
ax = axes;
axes(ax);
cla(ax, 'reset');
% Plot something using 'subaxis' with multiple subfigures
x = 0:0.1:10;
spacing = 0.0;
subaxis(3,1,1,'Spacing',spacing);
plot(x,rand(size(x)),'k')
legend('D','Location','NorthWest')
ylim([-0.2 1])
set(gca, 'box','off')
set(gca,'XAxisLocation','top')
subaxis(2,'Spacing',spacing);
plot(x,rand(size(x)),'r')
legend('C','Location','NorthWest')
ylim([-0.2 1])
set(gca,'xtick',[],'box','off','xcolor','w')
subaxis(3,'Spacing',spacing);
plot(x,rand(size(x)),'b')
legend('B','Location','NorthWest')
set(gca, 'box','off')
The program is fine at this point and did what I expected. Now I press a button to update these subfigures, but still want to plot the subfigures in the specified axes called 'ax':
axes(ax);
cla(ax, 'reset');
x = 0:0.1:10;
spacing = 0.0;
subaxis(3,1,1,'Spacing',spacing);
plot(x,rand(size(x)),'k')
legend('D','Location','NorthWest')
ylim([-0.2 1])
set(gca, 'box','off')
set(gca,'XAxisLocation','top')
subaxis(2,'Spacing',spacing);
plot(x,rand(size(x)),'r')
legend('C','Location','NorthWest')
ylim([-0.2 1])
set(gca,'xtick',[],'box','off','xcolor','w')
subaxis(3,'Spacing',spacing);
plot(x,rand(size(x)),'b')
legend('B','Location','NorthWest')
set(gca, 'box','off')
Error shows up!!!
Error using axes
Invalid object handle
Not sure what to do as the error info is so brief. It seems the subaxis can only be plot to a specific 'axes' once.
Any help would be appreciated. Thanks very much. A.
Remove these two lines from the top of your second piece of code:
axes(ax);
cla(ax, 'reset');
Now matlab will update the graph in the current plot. I have tested this in a normal (non-GUI) matlab file and it works fine. If it doesn't work for you, post details of the GUI as there may be some related problem within.

matlab: plot area continues after data ends

I have a simple plot in Matlab but as you can see from the screenshot. There is a lot of white space on the right side of the graph after the end of the data series.
Any idea how to get rid of this white space and make the plot go right to the edge of the figure? Here is my code:
Plotx = plot(x);
hold on
PlotState = plot(Y);
set(Plotx,'Color','black','LineWidth',2.5);
set(PlotState,'Color','red','LineWidth',2.5);
set(gca, 'XTick',(1:3:62))
labels = time;
set(gca,'XTickLabel',labels(1:3:62))
grid on
This usually works for me:
axis tight;
xlim('auto');
You must select your figure, go back to the console and use those commands so they affect the last active figure.
EDIT: The above line should automatically make your graph axis very tight on your data. For more fine control, you may want to define the axis limits manually:
axis([xmin,xmax,ymin,ymax])
I found a solution. I manually adjust the limit of the x-axis, using:
set(gca,'XLim',[0 63])

Plotting an existing MATLAB plot into another figure

I used the plot command to plot a figure and then changed lots of its properties using set command. I also store the handle of the plot (say h1).
What I need is to use the handle to plot the same figure again later in my code. I checked the plot command and did not find any version that accepts handle. I also thought of getting the Xdata and Ydata and use them to re-plot the same figure.
What is the simplest solution?
Edit 1: A working sample code based on copyobj that PeterM suggested.
hf(1) = figure(1);
plot(peaks);
hf(2) = figure(2);
plot(membrane);
hf(3) = figure(3);
ha(1) = subplot(1,2,1);
ha(2) = subplot(1,2,2);
for i = 1:2
hc = get(hf(i),'children');
hgc = get(hc, 'children');
copyobj(hgc,ha(i));
end
Edit 2: I also found this function that can copy figures (including legend) into a subplot.
I have run into this situation before. Depending on what you are trying to do the function copyobj may be appropriate. This function lets you take the contents of one axes and copy it to a new figure.
Improving #PeterM nice answer, one easier way would be:
fig2H=copy(gcf) % or change gcf to your figure handle
But it depends on what you want, if you want only the axes, or the whole figureā€¦ (btw, it doesn't seem to copy the legend handle).
You can use saveas to save the figure in a file, and the open to load the exact same figure from this file.
This would be the laziest way to accomplish what you want.
% Sample plot
f1 = figure(1);
plot(0:0.1:2*pi, sin(0:0.1:2*pi));
f2 = figure(2);
% The code you need
saveas(f1, 'temp.fig')
f2 = hgload('temp.fig')
delete('temp.fig')
I have used the function figs2subplots (given in Edit2 in the original question) - it does the work and is very easy to use.