Graphs is not plotting properly in the subplot in MATLAB - matlab

I have I have a data file which has 3 columns, 1st column is the field for the data, or you can say different index. 2nd column is the x-axis data, and the 3rd column is the y-axis data. Now I have similar data files for different variables like 8 files. I want to plot all the graph in one figure in MATLAB. For my problem, I am showing only one subplot. This subplot data file should plot 5 "line plots" for 5 indexes (1st column). But when I plot it as subplot it shows only 1 plot. here is my code in the below:
% open Zdiff Odd Mode data file
fid = fopen('Data_test.txt');
% Read data in from csv file
readData = textscan(fid,'%f %f %f','Headerlines',1,'Delimiter',',');
fclose(fid);
% Extract data from readData
index_Data = readData{1,1}(:,1);
% Identify the unique indices
uni_idx=unique(index_Data);
xData = readData{1,2}(:,1);
yData = readData{1,3}(:,1);
% Plot Data
f = figure;
%Top Title for all the subplots
p = uipanel('Parent',f,'BorderType','none');
p.Title = 'Electrical Characteristics';
p.TitlePosition = 'centertop';
p.FontSize = 14;
p.FontWeight = 'bold';
cla; hold on; grid on, box on;
ax1 = subplot(2,4,1,'Parent',p);
% Loop over the indices to plot the corresponding data
for i=1:length(uni_idx)
idx=find(index_Data == uni_idx(i));
plot(xData(idx,1),yData(idx,1))
end
The plot results like below:
When I plot the data as a full figure, the plot is perfect. But as I have lots of data to plot in one figure as subplots, I need to know what is wrong in my subplot code.
Here is my code for the whole figure of the data without the subplot
Before plotting code it is same as before:
% Plot Data
f1 = figure(1);
cla; hold on; grid on;
% Loop over the indices to plot the corresponding data
for i=1:length(uni_idx)
idx=find(index_Data == uni_idx(i));
plot(xData(idx,1),yData(idx,1))
end
The resulting figure is below:
What is wrong with my plotting code in the subplot? Can anyone help me out?

This is your sequence of commands, and what they do:
f = figure;
Creates an empty figure, there are no axes yet defined here.
cla
Clears the current axes, since there is no current axes, it creates one.
hold on
Sets the "hold" property on the current axes
grid on, box on
Sets some other properties of the current axes
ax1 = subplot(2,4,1,'Parent',p);
Creates new axes. Because it overlays the previously created axes, those are deleted.
plot(xData(idx,1),yData(idx,1))
Plots to the current axes (i.e. the one created by subplot). These axes don't have the "hold" property set, so subsequent plot commands will overwrite the data plotted here.
The solution, as suggested by Ander in a comment, is to set the "hold" property of the axes created by subplot. Replace:
cla; hold on; grid on, box on;
ax1 = subplot(2,4,1,'Parent',p);
with:
ax1 = subplot(2,4,1,'Parent',p);
hold on; grid on, box on;
(note that cla is not necessary, since you're drawing to a new, empty figure).

Related

matlab plots as movie with legend

i have a question regarding legend for movies.
This is my code:
fig = figure();
for i = 1: 70000
plot(signal1)
hold on;
plot([i,i],[-5,5])
plot(signal2,'r')
hold off;
title('\fontsize{14} my data');
legend('signal1','signal2');
axis tight;
f(i) = getframe(fig);
end
The legend shows the same colors for the first two things I plot. if I plot more it works for the other plots. Is there a trick I don't know?
The strings defined in the legend command are assigned in order of the plots being generated. This means that your first string 'signal1' is assigned to the plot for signal1 and the second string 'signal2' is assigned to the vertical line.
You have two possibilities to fix this problem.
Execute plot for the vertical line after the plot for the two signals.
Use handles to the plots to assign the legends directly.
Here is an example of changing the order:
plot(signal1)
hold on;
plot(signal2,'r')
plot([i,i],[-5,5],'k')
hold off;
legend('signal1','signal2');
Here is an example that uses handles (sp1 and sp2):
sp1 = plot(signal1)
hold on;
plot([i,i],[-5,5],'k')
sp2 = plot(signal2,'r')
hold off;
title('\fontsize{14} my data');
legend([sp1,sp2],'signal1','signal2');

MATLAB candles plot: layers order

I try to put a marker on a candle plot of Matlab.
But the marker is placed under the candle, and the marker can't be seen if it is too small.
I tried to use uistack to reorder the layers, but the marker is still placed behind the candle body.
load disney;
candle(dis_HIGH(end-20:end), dis_LOW(end-20:end), dis_CLOSE(end-20:end),...
dis_OPEN(end-20:end), 'b');
hold on;
markers = plot(2,20.4,'r^','MarkerFaceColor','r', 'MarkerSize',15);
uistack(markers,'top');
hold off;
How to make the marker to be in front of the candle?
You can circumvent this issue by doing the following:
1) Add a new transparent axes at the same position than the existing one.
2) Make its NextPlot property set to add.
3) Adjust its limits to fit with that of the axes generated by the candle plot.
So in code this looks like this:
clear all
clc
close all
load disney;
candle(dis_HIGH(end-20:end), dis_LOW(end-20:end), dis_CLOSE(end-20:end),...
dis_OPEN(end-20:end), 'b');
%//======================
%// Get current axes
Axes1 = gca;
%// Get the current limits
Axes1XLim = get(gca,'XLim');
Axes1YLim = get(gca,'YLim');
%// Create new axes
hold on
NewAxes = axes('Position',get(gca,'Position'),'Color','none','XTick',get(Axes1,'XTick'),'YTick',get(Axes1,'YTick'),'NextPlot','add')
%// Plot your data on new axes
m = plot(NewAxes,2,20.4,'r^','MarkerFaceColor','r', 'MarkerSize',15);
%// Adjust its limits
xlim(Axes1XLim)
ylim(Axes1YLim)
And the output:

Matlab - Legend does not match my graph

I am having trouble matching my graph with my axis. The first two plots work and the second two do not. I am trying to plot Temperature versus Pressure for two Argo floats and then Salinity versus Pressure. Here is my code:
% First Plot
subplot(221);
plot(float1winter.T,float1winter.P,'b');
hold on;
plot(float1summer.T,float1summer.P,'r');
hold on;
tempAdiff = abs(float1summer.T-float1winter.T)
plot(tempAdiff,float1summer.P,'--k');
hold on;
set(gca,'ydir','reverse');
title('Argo Float #1901440 Temp Profiles');
legend(['float1winter','float1summer','tempAdiff'],{'11-29-2013','07-01-2013','Temperature Difference'},'location','southwest');
xlabel('Temperature (°C)');
ylabel('Pressure');
shg;
% Second Plot
subplot(222);
plot(float2winter.S,float2winter.P,'m');
hold on;
plot(float2summer.S,float2summer.P,'c');
hold on;
set(gca,'ydir','reverse');
title('Argo Float #1901440 Salinity Profiles');
legend(['float2winter','float2summer'],{'11-29-2013','06-02-2013'},'location','southwest');
xlabel('Salinity (psu)');
ylabel('Presure');
shg;
% Third Plot
subplot(223);
% Matrix demensions did not agree bewteen winter and summer profiles. The summer profile was 71 x 2 and the winter was 70 x 2. I tried "reshape"
% and that didn't work. So I changed the vector of float3summer.T to
% float3bsummer.T with an array of 70 x 2
float3bsummer.T = float3summer.T(1:70,1:2);
float3bsummer.P = float3summer.P(1:70,1:2);
plot(float3winter.T,float3winter.P,'Linewidth',1,'color','blue');
hold on;
plot(float3bsummer.T,float3bsummer.P,'Linewidth',1,'color','red');
hold on;
tempdiff = abs(float3bsummer.T-float3winter.T)
plot(tempdiff,float3bsummer.P,'--k');
hold on;
set(gca,'ydir','reverse'); % this line reverses the y-axis so that depth increases downward
title('Argo Float #1901415 Tempearture Profiles');
hold on;
summerfloat = plot(float3bsummer.T,float3bsummer.P,'r');
legend(['float3winter.T','summerfloat','tempdiff'],{'12-03-2013','07-03-2013','Temp Diff'},'location','southeast');
xlabel('Temperature (°C)');
ylabel('Pressure');
axis ([-1,4,0,2000]);
shg;
% Fourth Plot
subplot(224);
plot(float3winter.S,float3winter.P,'g');
% Changed matrix dimensions for Salinity of Summer
float3bsummer.S = float3summer.S(1:70,1:2);
float3bsummer.P = float3summer.P(1:70,1:2);
plot(float3bsummer.S,float3bsummer.P,'.b');
hold on;
set(gca,'ydir','reverse');
title('Argo Float #1901415 Salinity Profiles');
h4 = plot(float3winter.S,float3winter.P,'g');
hold on;
h5 = plot(float3bsummer.S,float3bsummer.P,'.b');
hold on;
legend(['float3winter','float3bsummer.T'],{'12-03-2013','07-03-2013'},'location','southwest');
xlabel('Salinity (psu)');
ylabel('Pressure');
axis ([33.8,34.8,0,2000]);
shg;
% Save File to Desktop
set(gcf,'color','w');
saveas(gcf,'~/Desktop/hw1_figure1.pdf','pdf');![enter image description here][1]
I guess that you're trying to associate the set of strings for your legend, {'11-29-2013','07-01-2013','Temperature Difference'}, with the plots made from the variables ['float1winter','float1summer','tempAdiff'].
However, this isn't how legend works. MATLAB has no way of associating the plot produced by plot(float1winter.T,float1winter.P,'b'); to the string float1winter. If you want to specify which plots go with which legend entries, you need to pass the object handles of the plots to legend, which is easiest done by returning the handles when you plot originally:
h(1) = plot(float1winter.T,float1winter.P,'b');
hold on;
h(2) = plot(float1summer.T,float1summer.P,'r');
h(3) = plot(tempAdiff,float1summer.P,'--k');
legend(h,{'11-29-2013','07-01-2013','Temperature Difference'});
Side note: you only need to call hold on once per axis - so once for each subplot but not after every plot call.
Alternatively, you can not give handles at all; legend will assign the text to the plots in the order that they were plotted:
legend({'11-29-2013','07-01-2013','Temperature Difference'})
Understanding graphics handles allows you a lot more control over plots, especially if you might want to make small adjustments to them. For example, if I decide that I want the first plot to be green rather than blue, then I can just do:
set(h(1),'Color','g');
This will change the plot color and the legend changes to match automagically. To see a list of all the properties of an object, use get with only the handle. You can set more than one property at a time. For example:
get(h(1))
set(h(1),'DisplayName','Winter','LineWidth',3,'Marker','x')

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

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!')

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))