Matlab multiple stacked plots - matlab

I've never seen a plot like the following (the plot in (a) ). Is it even possible?

According to the profile page of #Ander Biguri
Matlab can even make your dinner, if you know how to use it.
Which answers the question, if this is even possible ;-)
All we need is basic knowledge of the axes command - the rest is just tweaking to make it look nice. Let's have a look at it:
We'll start off by creating some sample data:
t = 100:220;
x1 = -(10*(t-130)).^2;
x2 = -(10*(t-150)).^2;
x3 = -(10*(t-170)).^2;
Then we'll create an initial figure with a white background
fig = figure(1);
set(fig,'Color','w');
Now we can create a new axes object and plot x1 on it:
ax(1) = axes('Position',[0.1,0.1,0.6,0.6]);
plot(ax(1),t,x1+10^4*rand(size(x1)),'-k',t,x1,'-r');
We'll remove the box around the axes, so only the x- and y-axes remain. Further we resize the plot, so we'll have enough space for the other two plots. We also set the color to none, i.e. transparent.
set(ax(1),'Color','none');
set(ax(1),'Box','off');
set(ax(1),'Position',[0.1,0.1,0.6,0.6]);
Now we need to create the second graph. We'll just create another axes object at a position which we like:
ax(2) = axes('Position',[0.2,0.2,0.6,0.6]);
plot(ax(2),t,x2+10^4*rand(size(x2)),'-k',t,x2,'-r');
set(ax(2),'Color','none');
set(ax(2),'Box','off');
and so on:
ax(3) = axes('Position',[0.3,0.3,0.6,0.6]);
plot(ax(3),t,x3+10^4*rand(size(x3)),'-k',t,x3,'-r');
set(ax(3),'Color','none');
set(ax(3),'Box','off');
And simple as that, we get something that doesn't even look that bad:

Using multiple waterfall plots, as Horchler suggested:
%// create some sample data
t=10:20:110;
x=0:1:200;
Y=bsxfun(#(x,t) normpdf(x,t,20),x,t.'); %//' fix the code formatting on SO!!
%// Make a colormap to to set the colour of the lines
colormap([1 0 0;0 0 0]);caxis=[0 1];
%// Plot the first set of lines (red ones)
h1=waterfall(x,t,Y,zeros(size(Y)));
set(h1,'FaceColor','none','LineWidth',2) %// tweak the properties
hold on
%// Plot the second set of lines (black lines), just the red lines with some noise
h2=waterfall(x,t,Y+0.002*(rand(size(Y))-0.5),ones(size(Y)));
set(h2,'LineWidth',2)
hold off
view([16 28])
we can get this:

Related

How to set x and y values when using bar3 in Matlab?

Quick version
How can I control the x- and y-values for a 3-d bar plot in Matlab?
Details
Say we have an 10 x 20 data matrix and we plot it using bar3, and we want to set the x- and y-values. For instance:
foodat = rand(10,20);
xVals = [5:14];
yVals = [-3:16];
bar3(xVals, foodat);
xlabel('x'); ylabel('y');
Is there a way to feed it the yVals as well? Otherwise the y axes always defaults to [1:N].
Note I don't just want to change the labels using XTickLabel and YTickLabel. I need to change the actual values on the axes, because I am plotting multiple things in the same figure. It isn't enough to just change how the (wrong) axis ticks are labeled. So this is different from issues like this:
How can I adjust 3-D bar grouping and y-axis labeling in MATLAB?
Other things I have tried
When I try changing the xvals with:
set(gca,'XTick', xVals)
set(gca,'YTick', yVals)
The values are taken in, but actually show up on the wrong axes, so it seems x and y axes are switched using bar3. Plus, it is too late anyway as the bar graph was already plotted with the wrong x- and y-values, so we would end up giving ticks to empty values.
Note added
Matlab tech support just emailed me to let me know about the user contributed function scatterbar3, which does what I want, in a different way than the accepted answer:
http://www.mathworks.com/matlabcentral/fileexchange/1420-scatterbar3
I found a way of doing it. Ill give you a piece of code, then you'll need to "tidy up" , mainly the axis limits and the Xticks, as bar3 does set up the Xticks inside, so if you want others you'll need to set them manually yourself.
So the trick here is to get the Xdata from the bar3 handle. The thing here is that it seems that there is a handle for each row of the data, so you need to iterate for each of them. Here is the code with the current output:
foodat = rand(20,10);
xVals = [5:14];
yVals = [-3:16];
% The values of Y are OK if called like this.
subplot(121)
bar3(yVals, foodat);
subplot(122)
h=bar3(yVals, foodat);
Xdat=get(h,'XData');
axis tight
% Widdth of barplots is 0.8
for ii=1:length(Xdat)
Xdat{ii}=Xdat{ii}+(min(xVals(:))-1)*ones(size(Xdat{ii}));
set(h(ii),'XData',Xdat{ii});
end
axis([(min(xVals(:))-0.5) (max(xVals(:))+0.5) min(yVals(:))-0.5, max(yVals(:))+0.5])
Note: Y looks different but is not.
As you can see now the X values are the ones you wanted. If you'd want other size than 1 for the intervals between them you'd need to change the code, but you can guess how probably!

Paint each graph trace the same color in MATLAB

I have the following MATLAB code and I'm trying to make all of the plot traces black:
x = 20:0.01:30;
m1 = 25;
s1 = 2.5;
pdfNormal_1 = normpdf(x, m1, s1);
m2 = 25.478;
s2 = 0.1637;
pdfNormal_2 = normpdf(x, m2, s2);
m3 = 25.478;
s3 = 0.189;
pdfNormal_3 = normpdf(x, m3, s3);
set(gcf,'color','w');
g=findobj(gca,'Type','patch');
%set(g(1),'FaceColor',[0 .5 .5],'EdgeColor','w')
%set(g(2),'FaceColor',[0 1 1],'EdgeColor','w')
%set(g(3),'FaceColor',[0 1 1],'EdgeColor','w')
set(gca,'Fontsize',12,'Fontname','euclid')
xlabel(' ') %título eixo xx
hold all;
%plot(x, pdfNormal_1, x, pdfNormal_2, x, pdfNormal_3);
%set(gcf,'Color',[0 0 0])
plot(x,pdfNormal_1,'-.')
plot(x,pdfNormal_2,':')
plot(x,pdfNormal_3,'-','LineWidth',2)
Can someone help me? I removed the % from set(...);, but it plots nothing.
I don't quite know what exactly you want. You can either interpret this as:
You wanting all of your lines to be black
You wanting the background pane to be black.
Let's answer each question anyway so we have our bases covered.
Wanting all lines black
For the third parameter in plot, you can use a single letter that specifies what colour you want for your lines within your plot. Therefore, if you want all three of your plots black, use k after each invocation to plot. b is actually reserved for blue. Also, because you are calling plot more than once, each call to plot by default will overwrite the contents of the current figure with the latest invocation to plot, and so if you want all three plots to appear at the same time, you need to use hold on. Therefore, place this at the end of your code:
hold on;
plot(x,pdfNormal_1,'k-.')
plot(x,pdfNormal_2,'k:')
plot(x,pdfNormal_3,'k-','LineWidth',2);
You can also get rid of any set commands as these aren't useful. What you're actually doing is setting the background of the figure to white, which is probably not what you want to do. By background, I mean the area where the axes appear, not the drawing area of the plot itself.
Wanting the background pane black
If you want the background of where the plot appears to be black, it's a very simple one line statement. You need to set the current axes colour, not the current figure. Therefore, replace your set(gcf...) statement with set(gca...). Therefore:
set(gca,'Color',[0 0 0])
Now, if this is what you want, it'll be up to you to figure out what colours will appear on this plot nicely. Red certainly appears nice here!
For more information about how plot works, check out the documentation page on MathWorks: http://www.mathworks.com/help/matlab/ref/plot.html. It's actually very well explained!

How to specify the axis size when plotting figures in Matlab?

Suppose that I have 2 figures in MATLAB both of which plot data of size (512x512), however one figure is being plotted by an external program which is sets the axis parameters. The other is being plotted by me (using imagesc). Currently the figures, or rather, the axes are different sizes and my question is, how do I make them equal?.
The reason for my question, is that I would like to export them to pdf format for inclusion in a latex document, and I would like to have them be the same size without further processing.
Thanks in Advance, N
Edit: link to figures
figure 1: (big)
link to smaller figure (i.e. the one whose properties I would like to copy and apply to figure 1)
For this purpose use linkaxes():
% Load some data included with MATLAB
load clown
% Plot a histogram in the first subplot
figure
ax(1) = subplot(211);
hist(X(:),100)
% Create second subplot
ax(2) = subplot(212);
Now link the axes of the two subplots:
linkaxes(ax)
By plotting on the second subplot, the first one will adapt
imagesc(X)
First, you have the following:
Then:
Extending the example to images only:
load clown
figure
imagesc(X)
h(1) = gca;
I = imread('eight.tif');
figure
imagesc(I)
h(2) = gca;
Note that the configurations of the the first handle prevail:
linkaxes(h)
1.Get the handle of your figure and the axes, like this:
%perhaps the easiest way, if you have just this one figure:
myFigHandle=gcf;
myAxHandle=gca;
%if not possible, you have to search for the handles:
myFigHandle=findobj('PropertyName',PropertyValue,...)
%you have to know some property to identify it of course...
%same for the axes!
2.Set the properties, like this:
%set units to pixels (or whatever you prefer to make it easier to compare to the other plot)
set(myFigHandle, 'Units','pixels')
set(myAxHandle, 'Units','pixels')
%set the size:
set(myFigHandle,'Position',[x_0 y_0 width height]) %coordinates on screen!
%set the size of the axes:
set(myAxHandle,'Position',[x_0 y_0 width height]) %coordinates within the figure!
Ok, based on the answer of #Lucius Domitius Ahenoba here is what I came up with:
hgload('fig1.fig'); % figure whose axis properties I would like to copy
hgload('fig2.fig');
figHandles = get(0,'Children');
figHandles = sort(figHandles,1);
ax(1) = findobj(figHandles(1),'type','axes','-not','Tag','legend','-not','Tag','Colorbar');
ax(2) = findobj(figHandles(2),'type','axes','-not','Tag','legend','-not','Tag','Colorbar');
screen_pos1 = get(figHandles(1),'Position');
axis_pos1 = get(ax(1),'Position');
set(figHandles(2),'Position',screen_pos1);
set(ax(2),'Position',axis_pos1);
This is the 'before' result:
and this is the 'after' result:
Almost correct, except that the aspect ratios are still off. Does anybody know how to equalize everything related to the axes? (I realize that I'm not supposed to ask questions when posting answers, however adding the above as a comment was proving a little unwieldy!)

How to plot graphs above each other in Matlab?

I want to plot two (or more) graphs in Matlab. I want them to be aligned one above the second one above the third and so on. However subplot is not the case for me. I also don't want them both to be on the same graph in different colors, just to be one above the other. Is it possible? I'm searching for such a command but without any success.
Thanks in advance for hints!
If what you mean by "one above the other" is one "on top of another" then I think what You need to use is the axes command. Having said that, in order to have your plot be readable, I think more than two scales in the same plot makes it pretty hard to read.
This Matlab's help page shows you how to do it, the gist of it is shown in the following script:
y2 = 1000.*rand(100,1);
x2 = 0:99;
% Plot the first data set
hl1 = line(x1,y1,'Color','r');
% Get the axes and configure it
ax1 = gca;
set(ax1,'XColor','r','YColor','r')
%Create the new axes
ax2 = axes('Position',get(ax1,'Position'),...
'XAxisLocation','top',...
'YAxisLocation','right',...
'Color','none',...
'XColor','k','YColor','k');
% Plot the second data set with the new axes
hl2 = line(x2,y2,'Color','k','Parent',ax2);
The above script creates the following plot with one set of axes in red and another in black.
Hope this helps.

Matlab - plot two pcolors on top of each other, with different colormaps

I'm plotting two pcolors on top of each other (using the m_map algorithm m_pcolor). The reason for this is that the second pcolor has transparency in it, and so shows the pcolor underneath. The first plot consists of just ones and zeroes, and I would like it to be just black and white. I would like the second to use the colormap jet, but I can't work out how to set one colormap without changing the other. My code at the moment is:
h1 = m_pcolor(Lon', Lat', black_background);
hold on;
h = m_pcolor(Lon', Lat', input_matrix);
Thanks in advance,
Adam
For this limited application, the easiest way is probably to append a row of zeros onto the colormap, deal with scaling (the clim property) yourself so that each plot takes advantage of the appropriate part of the colormap.
cm=colormap('jet'); %# Nx3
cm = [cm; 0 0 0]; %# append black row: (N+1)x3
h1 = m_pcolor(Lon',Lat',black_background);
set(h1,'clim',[length(colormap),length(colormap)])
hold on
h2 = m_pcolor(Lon', Lat', input_matrix);
set(h2,'clim',[length(colormap)-1, length(colormap)-1])
This should get you close, but I haven't tested it since I'm not on my matlab machine.
Another option is freezeColors from the file exchange (but this may only work for different axes within the same figure window, I'm not sure about different plots in the same axes object).