How to augment two Matlab plots? - matlab

I would like to plot two graphs with the same x-axis but with different y-axies, one stacked above the other. There is a similar question asked below BUT it doesn't account for changes of dimensions in the y-axes. I have edited this code to do so but hope there would be a more elegant approach (maybe using a "hold on" type code).
How to plot graphs above each other in Matlab?

Here is some code which might do what you want...if I understood right. Basically you create 2 different axes in the same figure, one on top of the other, and you play around with XTick and YTick. You can start from this I guess.:
clear
close all
clc
x = 1:10;
y1 = -(x.^2);
y2 = sin(x);
figure('Units','Normalized');
hAxes1 = axes('Position',[0.1 0.1 .8 .4]);
yLim = get(hAxes1,'YLim');
Axes1Position = get(hAxes1,'Position');
NewAxesPosition = [Axes1Position(1) Axes1Position(2)+0.4 Axes1Position(3) Axes1Position(4)];
hAxes2 = axes('Position',NewAxesPosition);
plot(x,y1,'b','Parent',hAxes1);
TICK = get(hAxes1,'YTick')
set(hAxes1,'XTick',2:1:10,'YTick',TICK(1:end-1))
hold on
plot(x,y2,'r','parent',hAxes2)
set(gca,'XTick',[],'XTickLabel',[])
hold off
Giving this:
This is not optimal but due to lack of time I have to stop here :) Of course you can alter the display of the axis or the tick marks as you wish. Moreover you could use text annotations to customize the YTicks even more nicely.Hope that helps!

Example:
A = 1000;
a = 0.005;
b = 0.005;
t = 0:900;
z1 = A*exp(-a*t);
z2 = sin(b*t);
[ax,p1,p2] = plotyy(t,z1,t,z2,'semilogy','plot');
ylabel(ax(1),'Semilog Plot') % label left y-axis
ylabel(ax(2),'Linear Plot') % label right y-axis
xlabel(ax(2),'Time') % label x-axis
With reference to: http://www.mathworks.com/help/matlab/creating_plots/plotting-with-two-y-axes.html

Related

Specifying different colour schemes for different orientations of Polarhistogram in MATLAB

Question
When using polarhistogram(theta) to plot a dataset containing azimuths from 0-360 degrees. Is it possible to specify colours for given segments?
Example
In the plot bellow for example would it be possible to specify that all bars between 0 and 90 degrees (and thus 180-270 degrees also) are red? whilst the rest remains blue?
Reference material
I think if it exists it will be within here somewhere but I am unable to figure out which part exactly:
https://www.mathworks.com/help/matlab/ref/polaraxes-properties.html
If you use rose, you can extract the edges of the histogram and plot each bar one by one. It's a bit of a hack but it works, looks pretty and does not require Matlab 2016b.
theta = atan2(rand(1e3,1)-0.5,2*(rand(1e3,1)-0.5));
n = 25;
colours = hsv(n);
figure;
rose(theta,n); cla; % Use this to initialise polar axes
[theta,rho] = rose(theta,n); % Get the histogram edges
theta(end+1) = theta(1); % Wrap around for easy interation
rho(end+1) = rho(1);
hold on;
for j = 1:floor(length(theta)/4)
k = #(j) 4*(j-1)+1; % Change of iterator
h = polar(theta(k(j):k(j)+3),rho(k(j):k(j)+3));
set(h,'color',colours(j,:)); % Set the color
[x,y] = pol2cart(theta(k(j):k(j)+3),rho(k(j):k(j)+3));
h = patch(x,y,'');
set(h,'FaceColor',colours(j,:),'FaceAlpha',0.2);
uistack(h,'down');
end
grid on; axis equal;
title('Coloured polar histogram')
Result

How to align colorbar tick labels and lines in Matlab

I need to make a plot with a discrete colorbar in Matlab. I do this in the following way:
data = randi(10, 20);
imagesc(data)
my_colormap = rand(10, 3);
colormap(my_colormap)
cb = colorbar
set(cb,'YTickLabel',{'A';'B';'C';'D';'E';'F';'G';'H';'I';'J';})
Now my problem is that the colorbar tick labels and the small lines in the colorbar don't align nicely. How can I even the colorbar tick labels and the small lines better as illustrated in the following pic:
The TickLabel on the colorbar each correspond to a value (a Tick). To place the TickLabels in the middle, you need to place the tick in the middle. To make this dynamic (so that It does not change when resizing the image) was I bit tricky I recall and I do not really recall. To set the ticks just once is not so hard though,
set(hCbar,'YTicks',RightYTicks);
EDIT:
On request I will post an example. This should give a hint of what to do.
x = 1:10;
y = 1:10;
cmap = jet(10);
[x, y] = meshgrid(x,y); %x and y grid
c = x-0.1; %Set color code to increase to the right
hFig = figure;
scatter(x(:),y(:),10,c(:),'filled'); % Simpler for the example
set(gca(hFig),'CLim',[0,10]);
colormap(cmap);
hCbar = colorbar;
set(hCbar,'YTicks',0.5:9.5);
set(hCbar,'YTickLabels',{'A','B','C','D','E','F','G','H','I','J'});
For newer matlab version, the YTicks may have changed name to Ticks And YTickLabels may be called TickLabels.

Matlab 2014b Tick Label Between Tick Marks

I'm creating a bar plot in Matlab 2014b and would like to center the x-axis labels in between the tick marks. For example, in the following graph, the bars are correctly segmented by year using datetick and a slight adjustment I make. However, I would like the labels to appear half way in between the tick marks that are currently specified.
clear; close all;
a = rand(12, 1)-0.1;
x = linspace(datenum('03-31-2012'), datenum('12-31-2014'), 12);
b1 = bar(x, a);
datetick('x', 'yyyy');
display(datestr(x))
ax1 = gca;
bGapWidth = (x(2)-x(1));
bWidth = b1.BarWidth;
ax1.XLim = [x(1)-bGapWidth*bWidth x(end)+bGapWidth*bWidth];
initTick = ax1.XTick;
ax1.XTick = initTick + (bWidth*bGapWidth)/2 + (bGapWidth*(1-bWidth)/2);
I've seen a few similar questions but nothing quite the same. I've also seen suggestions of creating a dummy axis (one for labels, one for tick marks), but I've had some trouble here too - simply setting a new variable equal to the current axes object and making modifications changes the whole plot. Feel free to help me out on this part, or suggest a better solution in general.
clear; close all;
a = rand(12, 1)-0.1;
x = linspace(datenum('03-31-2012'), datenum('12-31-2014'), 12);
b1 = bar(x, a);
datetick('x', 'yyyy');
display(datestr(x))
h1=get(gca,'XTick');
h2=get(gca,'XTickLabel');
h3=length(h1);
xdiff=h1(2)-h1(1); % assuming uniform step interval in x-axis
h1=h1+0.4*xdiff; % this factor of 0.4 can be adjusted
ylim([0 1]);
for i=1:h3-1
text(h1(i),-0.05,num2str(h2(i,:)));
end
% instead of -0.05 relative to y put the labels where you like
set(gca,'XTickLabel',{});

Matlab plot of several digital signals

I'm trying to find a way to nicely plot my measurement data of digital signals.
So I have my data available as csv and mat file, exported from an Agilent Oscilloscope. The reason I'm not just taking a screen shot of the Oscilloscope screen is that I need to be more flexible (make several plots with one set of data, only showing some of the lines). Also I need to be able to change the plot in a month or two so my only option is creating a plot from the data with a computer.
What I'm trying to achieve is something similar to this picture:
The only thing missing on that pic is a yaxis with 0 and 1 lines.
My first try was to make a similar plot with Matlab. Here's what I got:
What's definitely missing is that the signal names are right next to the actual line and also 0 and 1 ticks on the y-axis.
I'm not even sure if Matlab is the right tool for this and I hope you guys can give me some hints/a solution on how to make my plots :-)
Here's my Matlab code:
clear;
close all;
clc;
MD.RAW = load('Daten/UVLOT1 debounced 0.mat'); % get MeasurementData
MD.N(1) = {'INIT\_DONE'};
MD.N(2) = {'CONF\_DONE'};
MD.N(3) = {'NSDN'};
MD.N(4) = {'NRST'};
MD.N(5) = {'1V2GD'};
MD.N(6) = {'2V5GD'};
MD.N(7) = {'3V3GD'};
MD.N(8) = {'5VGD'};
MD.N(9) = {'NERR'};
MD.N(10) = {'PGD'};
MD.N(11) = {'FGD'};
MD.N(12) = {'IGAGD'};
MD.N(13) = {'GT1'};
MD.N(14) = {'NERRA'};
MD.N(15) = {'GT1D'};
MD.N(16) = {'GB1D'};
% concat vectors into one matrix
MD.D = [MD.RAW.Trace_D0, MD.RAW.Trace_D1(:,2), MD.RAW.Trace_D2(:,2), MD.RAW.Trace_D3(:,2), ...
MD.RAW.Trace_D4(:,2), MD.RAW.Trace_D5(:,2), MD.RAW.Trace_D6(:,2), MD.RAW.Trace_D7(:,2), ...
MD.RAW.Trace_D8(:,2), MD.RAW.Trace_D9(:,2), MD.RAW.Trace_D10(:,2), MD.RAW.Trace_D11(:,2), ...
MD.RAW.Trace_D12(:,2), MD.RAW.Trace_D13(:,2), MD.RAW.Trace_D14(:,2), MD.RAW.Trace_D15(:,2)];
cm = hsv(size(MD.D,2)); % make colormap for plot
figure;
hold on;
% change timebase to ns
MD.D(:,1) = MD.D(:,1) * 1e9;
% plot lines
for i=2:1:size(MD.D,2)
plot(MD.D(:,1), MD.D(:,i)+(i-2)*1.5, 'color', cm(i-1,:));
end
hold off;
legend(MD.N, 'Location', 'EastOutside');
xlabel('Zeit [ns]'); % x axis label
title('Messwerte'); % title
set(gca, 'ytick', []); % hide y axis
Thank you guys for your help!
Dan
EDIT:
Here's a pic what I basically want. I added the signal names via text now the only thing that's missing are the 0, 1 ticks. They are correct for the init done signal. Now I just need them repeated instead of the other numbers on the y axis (sorry, kinda hard to explain :-)
So as written in my comment to the question. For appending Names to each signal I would recommend searching the documentation of how to append text to graph. There you get many different ways how to do it. You can change the position (above, below) and the exact point of data. As an example you could use:
text(x_data, y_data, Var_Name,'VerticalAlignment','top');
Here (x_data, y_data) is the data point where you want to append the text and Var_Name is the name you want to append.
For the second question of how to get a y-data which contains 0 and 1 values for each signal. I would do it by creating your signal the way, that your first signal has values of 0 and 1. The next signal is drawn about 2 higher. Thus it changes from 2 to 3 and so on. That way when you turn on y-axis (grid on) you get values at each integer (obviously you can change that to other values if you prefer less distance between 2 signals). Then you can relabel the y-axis using the documentation of axes (check the last part, because the documentation is quite long) and the set() function:
set(gca, 'YTick',0:1:last_entry, 'YTickLabel',new_y_label(0:1:last_entry))
Here last_entry is 2*No_Signals-1 and new_y_label is an array which is constructed of 0,1,0,1,0,....
For viewing y axis, you can turn the grid('on') option. However, you cannot chage the way the legends appear unless you resize it in the matlab figure. If you really want you can insert separate textboxes below each of the signal plots by using the insert ->Textbox option and then change the property (linestyle) of the textbox to none to get the exact same plot as above.
This is the end result and all my code, in case anybody else wants to use the good old ctrl-v ;-)
Code:
clear;
close all;
clc;
MD.RAW = load('Daten/UVLOT1 debounced 0.mat'); % get MeasurementData
MD.N(1) = {'INIT\_DONE'};
MD.N(2) = {'CONF\_DONE'};
MD.N(3) = {'NSDN'};
MD.N(4) = {'NRST'};
MD.N(5) = {'1V2GD'};
MD.N(6) = {'2V5GD'};
MD.N(7) = {'3V3GD'};
MD.N(8) = {'5VGD'};
MD.N(9) = {'NERR'};
MD.N(10) = {'PGD'};
MD.N(11) = {'FGD'};
MD.N(12) = {'IGAGD'};
MD.N(13) = {'GT1'};
MD.N(14) = {'NERRA'};
MD.N(15) = {'GT1D'};
MD.N(16) = {'GB1D'};
% concat vectors into one matrix
MD.D = [MD.RAW.Trace_D0, MD.RAW.Trace_D1(:,2), MD.RAW.Trace_D2(:,2), MD.RAW.Trace_D3(:,2), ...
MD.RAW.Trace_D4(:,2), MD.RAW.Trace_D5(:,2), MD.RAW.Trace_D6(:,2), MD.RAW.Trace_D7(:,2), ...
MD.RAW.Trace_D8(:,2), MD.RAW.Trace_D9(:,2), MD.RAW.Trace_D10(:,2), MD.RAW.Trace_D11(:,2), ...
MD.RAW.Trace_D12(:,2), MD.RAW.Trace_D13(:,2), MD.RAW.Trace_D14(:,2), MD.RAW.Trace_D15(:,2)];
cm = hsv(size(MD.D,2)); % make colormap for plot
figure;
hold on;
% change timebase to ns
MD.D(:,1) = MD.D(:,1) * 1e9;
% plot lines
for i=2:1:size(MD.D,2)
plot(MD.D(:,1), MD.D(:,i)+(i-2)*2, 'color', cm(i-1,:));
text(MD.D(2,1), (i-2)*2+.5, MD.N(i-1));
end
hold off;
%legend(MD.N, 'Location', 'EastOutside');
xlabel('Zeit [ns]'); % x axis label
title('Messwerte'); % title
% make y axis and grid the way I want it
set(gca, 'ytick', 0:size(MD.D,2)*2-3);
grid off;
set(gca,'ygrid','on');
set(gca, 'YTickLabel', {'0'; '1'});
ylim([-1,(size(MD.D,2)-1)*2]);

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.