Related
I'm trying to make a stack plot from a table, to present several variables with the same x-axis. however, I want the x-axis to be logarithmic. I couldn't find any way in stackplot documentation. Does anyone have any suggestions on how I can solve this?
I have tried using subplots instead, however, that way my graphs would not fit all on one page and I would have a lot of white space between the subplots. Therefore, I chose stackplot to make it more nice and less space-consuming.
tbl = readtable('usage.csv');
newYlabels = {'Heating (kWh/year)','Cooling (kWh/year)','Electricity (kWh/year)'};
stackedplot(tbl,[{2:16},{17:27},{28:35}],'XVariable',[1],'DisplayLabels',newYlabels);
Here is the output of the code:
Here is an image of what I'm trying to make, but the x-axis needs to be the real variable (\beta) in logarithmic scale
stackedplot has unfortunately no logarithmic axes option, and since it creates a StackedAxes instead of a normal Axes object, there is no way to changes this.
If the only reason you want to use stackedplot is to have less white-space, you might want to check out tight_subplot on the Matlab FEX. This would allow you to just do: set(ax, 'XScale', 'log').
You can however take the log of your x-data, and add that to the table:
tbl = readtable('outages.csv'); % sample data
tbl = sortrows(tbl, 'OutageTime'); % sort by date
% make x vector; for example just row numbers
x = (1:size(tbl,1)).';
xlog = log10(x);
% add x to table
tbl.Xlog = xlog;
tbl.X = x;
% plot normal x
f = figure(1); clf;
s = stackedplot(tbl, {'Loss'}, 'XVariable', 'X');
xlabel('rows');
% plot log(x)
f = figure(2); clf;
s = stackedplot(tbl, {'Loss'}, 'XVariable', 'Xlog');
xlabel('log(rows)')
Normal:
Log:
I have two vectors that contain the average temperatures of two cities. I am plotting those vectors to a graph. I have 398 temperatures in both vectors so my xticklables are naturally from 1 to 398. I am trying to change my xticklables so they would show the month and the year like this: 01/2017. however I seem to be unable to write anything to my xtick. Here is my code for xtickmodification:
ax.XTick=[1,32,62,93,124,154,185,215,246,277,305,336,366,397];
ax.XTicklabels={'05/2014','06/2014','07/2014','08/2014','09/2014',
'10/2014','11/2014','12/2014','01/2015','02/2015','03/2015','04/2015','05/2015','06/2015'};
ax.XTick contains the vector element that starts a new month. So how can i get the ax.XTicklabels-line to my graph?
use XTickLabel property instead of XTicklabels. in addition, you can set XTickLabelRotation property if the labels are long strings:
x = rand(398,1);
h = plot(x);
ax = gca;
ax.XTick=[1,32,62,93,124,154,185,215,246,277,305,336,366,397];
ax.XTickLabel={'05/2014','06/2014','07/2014','08/2014','09/2014',...
'10/2014','11/2014','12/2014','01/2015','02/2015','03/2015','04/2015','05/2015','06/2015'};
ax.XTickLabelRotation = 45;
Have you tried the following
set(gca, 'xtick', ax.XTick);
set(gca, 'xticklabels', ax.XTicklabels);
I have matrices x1, x2, ... containing variable number of row vectors.
I do successive plots
figure
hold all % or hold on
plot(x1')
plot(x2')
plot(x3')
Matlab or octave normally iterates through ColorOrder and plot each line in different color. But I want each plot command to start again with the first color in colororder, so in default case the first vector from matrix should be blue, second in green, third in red etc.
Unfortunately I cannot find any property related to the color index niether another method to reset it.
Starting from R2014b there's a simple way to restart your color order.
Insert this line every time you need to reset the color order.
set(gca,'ColorOrderIndex',1)
or
ax = gca;
ax.ColorOrderIndex = 1;
see:
http://au.mathworks.com/help/matlab/graphics_transition/why-are-plot-lines-different-colors.html
You can shift the original ColorOrder in current axes so that the new plot starts from the same color:
h=plot(x1');
set(gca, 'ColorOrder', circshift(get(gca, 'ColorOrder'), numel(h)))
plot(x2');
You can wrap it in a function:
function h=plotc(X, varargin)
h=plot(X, varargin{:});
set(gca, 'ColorOrder', circshift(get(gca, 'ColorOrder'), numel(h)));
if nargout==0,
clear h
end
end
and call
hold all
plotc(x1')
plotc(x2')
plotc(x3')
Define a function that intercepts the call to plot and sets 'ColorOrderIndex' to 1 before doing the actual plot.
function plot(varargin)
if strcmp(class(varargin{1}), 'matlab.graphics.axis.Axes')
h = varargin{1}; %// axes are specified
else
h = gca; %// axes are not specified: use current axes
end
set(h, 'ColorOrderIndex', 1) %// reset color index
builtin('plot', (varargin{:})) %// call builtin plot function
I have tested this in Matlab R2014b.
I found a link where a guy eventually solves this. He uses this code:
t = linspace(0,1,lineCount)';
s = 1/2 + zeros(lineCount,1);
v = 0.8*ones(lineCount,1);
lineColors = colormap(squeeze(hsv2rgb(t,s,v)))
ax=gca
ax.ColorOrder = lineColors;
Which should work for you assuming each of your matrices has the same number of lines. If they don't, then I have a feeling you're going to have to loop and plot each line separately using lineColors above to specify an RBG triple for the 'Color' linespec property of plot. So you could maybe use a function like this:
function h = plot_colors(X, lineCount, varargin)
%// For more control - move these four lines outside of the function and make replace lineCount as a parameter with lineColors
t = linspace(0,1,lineCount)'; %//'
s = 1/2 + zeros(lineCount,1);
v = 0.8*ones(lineCount,1);
lineColors = colormap(squeeze(hsv2rgb(t,s,v)));
for row = 1:size(X,1)
h = plot(X(row, :), 'Color', lineColors(row,:), varargin{:}); %// Assuming I've remembered how to use it correctly, varargin should mean you can still pass in all the normal plot parameters like line width and '-' etc
hold on;
end
end
where lineCount is the largest number of lines amongst your x matrices
If you want a slightly hacky, minimal lines-of-code approach perhaps you could plot an appropriate number of (0,0) dots at the end of each matrix plot to nudge your colourorder back to the beginning - it's like Mohsen Nosratinia's solution but less elegant...
Assuming there are seven colours to cycle through like in matlab you could do something like this
% number of colours in ColorOrder
nco = 7;
% plot matrix 1
plot(x1');
% work out how many empty plots are needed and plot them
nep = nco - mod(size(x1,1), nco); plot(zeros(nep,nep));
% plot matrix 2
plot(x2');
...
% cover up the coloured dots with a black one at the end
plot(0,0,'k');
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]);
I have made a plot in Matlab, using:
hold on
plot(t1,Dx1,'r')
xlabel('t (ps)')
ylabel('Deviation of coordinate from initial coordinate (Å)')
plot(t1,Dy1,'g')
plot(t1,Dz1,'b')
hold off
However, the tick labels on the y axis are generated in scientific notation:
Is there any way I can remove the scientific notation and just have the y labels range from -0.0025 to 0.0005? Thanks!
You could try to manually set the tick labels yourself using sprintf:
yt = get(gca,'YTick');
set(gca,'YTickLabel', sprintf('%.4f|',yt))
Try adding this after creating the axes:
ax = gca;
ax.YAxis.Exponent = 0;
Here is an example:
x = 0:0.1:10;
y = 1000*x.^2;
%Plot with default notation:
subplot(1,2,1)
plot(x,y)
%Plot without exponent:
subplot(1,2,2)
plot(x,y)
ax = gca
ax.YAxis.Exponent = 0;
I also fought with getting my plot axes to display in fixed notion instead of scientific notation. The most frustrating part for me was that the "x10^4" label would remain on the edge of the plot box even after I reassigned the tick labels manually to fixed notation. Finally, thanks to the post above I tracked the problem down the figure renderer. I was using 'OpenGL'. When I changed to 'zbuffer' the "x10^4" label would properly disappear when I manually reset the tick labels.
Here's an example code that apples the format '###,###.0’ to the y-axis labels, and even dynamically updates the y-labels when you zoom/pan etc, thanks to two helpful functions I found on the Matlab File Exchange. The place to find the other two functions is included as comments below example function.
function []=TickFixExample()
figure %this one works
myRenderer='zbuffer';
set(gcf,'Renderer', myRenderer);
axesh = axes();
set(gca,'YLim',[20000 20100]);
title(myRenderer)
ticklabelformat(gca,'y','###,###.0');
figure %this one doesn’t work
myRenderer='OpenGL';
set(gcf,'Renderer', myRenderer);
axesh = axes();
set(gca,'YLim',[20000 20100]);
title(myRenderer)
ticklabelformat(gca,'y','###,###.0');
function ticklabelformat(hAxes,axName,format) by Y. Altman, can be found at:
http://www.mathworks.com/matlabcentral/fileexchange/36254-ticklabelformat-set-a-dynamic-format-of-axes-tick-labels
or by googling 'ticklabelformat matlab'
I modified it slightly by changing line 105 as follows:
tickLabels = arrayfun(#(x)(FormatNumberScalarInputStrOutput`(x,format)),tickValues,'UniformOutput',false);`
in lieu of Altman's version:
tickLabels = arrayfun(#(x)(sprintf(format,x)),tickValues,'UniformOutput',false);
that change provides for the thousands comma separator functionality by
function y = NumberFormatter( Numbers , FormatPattern ) by S. Lienhard,
also on Matlab File Exchange. My modified version of Lienhard code is
given in full below:
function y = FormatNumberScalarInputStrOutput(Number ,FormatPattern)
% adapted 12-2012 by D. Bourgoyne from NUMBERFORMATTER by S. Lienhard
%
% The pound sign (#) denotes a digit, the comma is a placeholder for the
% grouping separator, and the period is a placeholder for the decimal
% separator.
% The pattern specifies leading and trailing zeros, because the 0
% character is used instead of the pound sign (#).
%
% Examples:
% NumberFormatter(rand(5),'0.000')
% NumberFormatter(rand(5)*100,'###,###.000')
import java.text.*
v = DecimalFormat(FormatPattern);
y = char(v.format(Number));
You can use this code to control the format of tick labels of y axis. This code originates from ticks_format.m .
% Set the preferred tick format here.
y_formatstring = '%3.4f';
% Here's the code.
ytick = get(gca, 'ytick');
for i = 1:length(ytick)
yticklabel{i} = sprintf(y_formatstring, ytick(i));
end
set(gca, 'yticklabel', yticklabel)
You have to write the following:
set(gcf, 'renderer', 'zbuffer')
On newer versions of matlab (2016b) you can use the functions ytickformat and xtickformat to easily change the format of the labels.