How to add new plots of different scale to an existing histogram? - matlab

I have a Matlab figure with two histograms on it
,
created with hist() function. Now I want to add two plots in the same figure (bell distribution actually:
,
but they have different scale. I thought I could use plotyy, but I already have my first plot-scale on the figure. How can I add the second plot-scale?

Generally, this is one way to do it:
%// example data
rng(0,'twister')
data = randn(1000,3);
x = linspace(-4,4,100);
y = 16 - x.^2;
%// generate two axes at same position
ax1 = axes;
ax2 = axes('Position', get(ax1, 'Position'),'Color','none');
%// move second axis to the right, remove x-ticks and labels
set(ax2,'YAxisLocation','right')
set(ax2,'XTick',[])
%// plot hist and line plot
hist(ax1,data); hold on
plot(ax2,x,y)
ylabel(ax1,'label of hist')
ylabel(ax2,'label of plot')
xlabel(ax1,'Hello World!')

Related

How do I reach first and second plots from bode()

I know how to create the Bode plots with bode() function. If I want to overlap two or more systems frequency responses, I use
bode(sys1,sys2,...)
or
hold on
When I want to reach the plot in order to put a legend with text(), for instance, is easy to reach the second plot. Something like the figure pointer always returns to the second plot (phase graph).
i.e., if try these lines:
G = tf([1],[1 6]); figure(1); bode(G); text(10,-20,'text');
G = tf([1],[1 6]); figure(2); bode(G); text(10,-20,'text');
when I return to the first figure, with figure(1), and try
figure(1); text(10,-20,'text')
legend is displayed in the second plot (Phase plot)
I try these other lines:
P = bodeoptions; % Set phase visiblity to off
P.PhaseVisible = 'off';
G = tf([1],[1 6]);
figure(1); bode(G,P); text(10,-20,'text');
figure(1); text(10,-20,'text');
As you can see, even I turn off the phase plot visiblity, the legend is not displayed.
Essentialy, my question is, how do I reach first and second plots, one by one? I tried with subplot(), but it is pretty clear this is not the way Matlab traces these plots.
Thanks in advance.
It all comes to getting into upper plot, since after bodeplot command the lower one is active. Intuitively one would want to call subplot(2,1,1), but this just creates new blank plot on top of if. Therefore we should do something like this:
% First, define arbitrary transfer function G(s), domain ww
% and function we want to plot on magnitude plot.
s = tf('s');
G = 50 / ( s*(1.6*s+1)*(0.23*s+1) );
ww = logspace(0,3,5000);
y = 10.^(-2*log10(ww)+log10(150));
hand = figure; % create a handle to new figure
h = bodeplot(G,ww);
hold on;
children = get(hand, 'Children') % use this handle to obtain list of figure's children
% We see that children has 3 objects:
% 1) Context Menu 2) Axis object to Phase Plot 3) Axis object to Magnitude Plot
magChild = children(3); % Pick a handle to axes of magnitude in bode diagram.
% magChild = childern(2) % This way you can add data to Phase Plot.
axes(magChild) % Make those axes current
loglog(ww,y,'r');
legend('transfer function','added curve')
you can get magnitude and phase data separately for each system using:
[mag,phase] = bode(sys,w)
now you can use subplot or plot to plot the diagram you want.
The only solution I was able to perform is taking into account axis position. It is not very clean but it works.
Here is the code to select mag plot:
ejes=findobj(get(gcf,'children'),'Type','axes','visible','on');
posicion=get(ejes,'pos');
tam=length(posicion);
for ii=1:tam
a=posicion{ii}(2);
vectorPos(ii)=a;
end
[valorMax,ind]=max(vectorPos); % min for choosing the phase plot
axes(ejes(ind))

Plotting two different plots(y axes), sharing the same x in matlab

Considering this question, I am trying to Tackling the issue with two separate plots using axes instead of plotyy which doesn't work well with 'boxplot' and 'plot':
%%% definition of my x=y line axes
y2 = 1:6;
x2 = 1:6;
% Plot the first data set using boxplot, that results in 6 boxes
load carsmall;
boxplot(MPG,Origin)
% 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 =plot(x2,y2,'Color','k','parent',ax2);
but still I dont get my final plot in a right way. Does anyone know why?
There is a hold on missing before the last line.

How to connect pick points of a histogram by a curve in Matlab?

I am beginner in Matlab.
I have a histogram of a set of data I need to do 2 things.
1) I need the vertical axes to be normalized.
2) To curve a fit that passes through all the pick points of my Histogram bars.
Thank you
You can do it along these lines:
data = randn(1,1000); %// example data
num_bars = 15; %// specify number of bars
[n x] = hist(data,num_bars); %// use two-output version of hist to get values
n_normalized = n/numel(data)/(x(2)-x(1)); %// normalize to unit area
bar(x, n_normalized, 1); %// plot histogram (with unit-width bars)
hold on
plot(x, n_normalized, 'r'); %// plot line, in red (or change color)
For (1) try axis([xmin xmax ymin ymax])
For (2) try first drawing the histogram, then call hold on, then use the plot command.

Overlaying two axes in a Matlab plot

I am looking for a way to overlay an x-y time series, say created with 'plot', on top of a display generated by 'contourf', with different scaling on the y-axes.
It seems that the typical way to do this in the case of two x-y plots is to use the built-in function 'plotyy', which can even be driven by functions other than 'plot' (such as 'loglog') as long as the input arguments remain the same (x,y). However, since in my case contourf requires three input arguments, 'plotyy' seems to not be applicable. Here is some sample code describing what I would like to do:
x1 = 1:1:50;
y1 = 1:1:10;
temp_data = rand(10,50);
y2 = rand(50,1)*20;
figure; hold on;
contourf(x1,y1,temp_data);
colormap('gray');
plot(x1,y2,'r-');
Ideally, I would like the timeseries (x1,y2) to have its own y-axes displayed on the right, and be scaled to the same vertical extent as the contourf plot.
Thanks for your time.
I don't think there's a "clean" way to do this, but you can fake it by overlaying two axes over each other.
x1 = 1:1:50;
y1 = 1:1:10;
temp_data = rand(10,50);
y2 = rand(50,1)*20;
figure;
contourf(x1, y1, temp_data);
colormap('gray');
h_ax = gca;
h_ax_line = axes('position', get(h_ax, 'position')); % Create a new axes in the same position as the first one, overlaid on top
plot(x1,y2,'r-');
set(h_ax_line, 'YAxisLocation', 'right', 'xlim', get(h_ax, 'xlim'), 'color', 'none'); % Put the new axes' y labels on the right, set the x limits the same as the original axes', and make the background transparent
ylabel(h_ax, 'Contour y-values');
ylabel(h_ax_line, 'Line y-values');
In fact, this "plot overlay" is almost definitely what the plotyy function does internally.
Here's example output (I increased the font size for legibility):

plotting two yaxis with different markers and colors

If I have two y vectors and one x vector:
y1 = [0.1,0.2,0.5,0.6];
y2 = [0.3,0.4,0.7,0.8];
x = 1:length(y1);
How can I plot all of the information on the same plot using different markers and different colors. I have tried the following:
cols = {'k','r','b',[0,0.5,0]};
markers = {'s','o','d','v'};
for i = 1:4;
plot(x(i),y1(i),markers{i},'color',cols{i},'MarkerEdgeColor',...
cols{i},'MarkerFaceColor','w');
hold on
end
ax1 = gca;
ax2 = axes('Position',get(ax1,'Position'),...
'YAxisLocation','right','XColor','k','YColor','k');
linkaxes([ax1,ax2],'x');
for i = 1:4;
plot(x(i),y2(i),markers{i},'color',cols{i},'MarkerEdgeColor',...
cols{i},'MarkerFaceColor',cols{i},'Parent',ax2);
hold on;
end
But this seems to overwrite the first plot. My aim here it to draw the first four points (y1) with the markers and colors defined, but with the maker faces in white. I then hope to include on the same figure, a second yaxis (on the right) with the values from y2, but this time with the marker faces colored according to 'cols'. How can I do this?
Addition:
When I use plotyy
for i = 1:4;
[ax,h1,h2] = plotyy(x(i),y1(i),x(i),y2(i));
hold on
set(h1,'linestyle','none','marker',markers{i},'MarkerEdgeColor',...
cols{i},'MarkerFaceColor',cols{i});
set(h2,'linestyle','none','marker',markers{i},'MarkerEdgeColor',...
cols{i},'MarkerFaceColor','w');
set(ax,{'ycolor'},{'k';'k'},{'xcolor'},{'k';'k'});
end
The xaxis values do not show up correctly, where although they are identical, they do not line up on the plot.
You can use the embedded function of Matlab , plotyy
plotyy(X1,Y1,X2,Y2) plots X1 versus Y1 with y-axis labeling on the left and plots X2 versus Y2 with y-axis labeling on the right.
check more options here.
This example graphs two mathematical functions using plot as the plotting function. The two y-axes enable you to display both sets of data on one graph even though relative values of the data are quite different.
figure
x = 0:0.01:20;
y1 = 200*exp(-0.05*x).*sin(x);
y2 = 0.8*exp(-0.5*x).*sin(10*x);
[AX,H1,H2] = plotyy(x,y1,x,y2,'plot');
If you are trying with 'hold on' this solves the a-synchronized axes:
set(ax, 'XLim', [min(xaxis) max(xaxis)]);
set(ax(2),'XTick',[]);
The problem is that the background color on the overlayed plot is set to white (and opaqueness to max) so that everything underneath is invisible. Substituting the ax2 = ... statement with
ax2 = axes('Position',get(ax1,'Position'),...
'YAxisLocation','right','XColor','k','YColor','k','color','none');
should fix things.