I have a piece of code in Matlab where I need to plot a graph including to lines depending on dates (x axis). I want then to add an horizontal line at y=0 to mimic the x axis as it is not shown due to negative value.
Here is the code:
figure1 = figure('Name','Historical Performance');
plot(QuarterEnd,perf(1,:),'b',QuarterEnd,perf(2,:),'r','DatetimeTickFormat','QQQ-y','LineWidth',2)
xlabel('Quarter');
ylabel('Performance');
ax = gca;
ax.XTickLabelRotation=45;
legend('Historical performance from prediction','Best Historical performance','LOcation','Southwest');
I have tried something like
line(QuarterEnd,[0 0],'Color','g')
But it does not span the right interval. I only need the line to be displayed over the interval where there are data points. Is there an easy way to do so?
Related
I have a scatterplot of data in Matlab, along with a horizontal linegraph which divides two sub groups of this data - all on the same plot. I have plotted these two entities separately using the hold on command.
Ideally, I want the plot window to automatically adjust to just the scatterplot data, and would prefer the horizontal line I plotted to simply extend off the screen in all cases. Is there a simple way to do this?
At the moment when I change the limits of the horizontal line, the graph window shifts to accommodate these points, skewing the view of the scatterplot data I'm actually interested in.
Example:
% central line segment
boundary_line = plot(csv_results.data(:,9),csv_results.data(:,10));
% negative extension of line segment off screen
line_negext = plot([-10,csv_results.data(1,9)],[csv_results.data(1,10),csv_results.data(1,10)]);
% positive extension of line segment off screen
line_posext = plot([10,csv_results.data(6,9)],[csv_results.data(6,10),csv_results.data(6,10)]);
% scatterplot data of interest
scatt_data = plot(csv_results.data(:,3),csv_results.data(:,4));
UPDATE: My problem is that, as seen in my code above, I need to plot two line segments at different y values that continue to positive and negative infinity, which link up to an existing plot in the middle. If I use yline I can simply draw one horizontal line - if I use xlim I risk cropping out data for subsequent runs..
If you want to adjust the axis to more restrictive portion (reduce), then xlim() and ylim() get the job done. Horizontal lines drawn by yline() will persist, as will vertical lines drawn by xline(). Note that xline() and yline() should work for releases including R2018b and later.
% MATLAB R2019a
% Sample Data
n = 10;
X1 = 5*rand(n,1);
Y1 = 5*rand(n,1);
X2 = 5 + 5*rand(n,1);
Y2 = 5 + 5*rand(n,1);
figure, hold on
yline(5)
scatter(X1,Y1,'bo')
scatter(X2,Y2,'rd')
scatter(X1,Y2,'ks')
xlim([0 5])
Notice that by calling xlim() for a larger x-axis range also expands the horizontal line.
xlim([-1,12])
If you plot new data after xlim() outside the range, the plot won't automatically adjust. However, if you do so before calling xlim(), then the horizontal line will expand. Try the example below.
figure, hold on
yline(5)
scatter(X1,Y1,'bo')
scatter(X2,Y2,'rd')
scatter(X1,Y2,'ks')
Then immediately execute
scatter(100*rand(n,1),Y1)
and see that the horizontal line has expanded to cover the new, much longer x-axis.
After posting this answer, I found: How to draw horizontal and vertical lines in MATLAB?
I'm trying to create a 24x366 heatmap using imagesc with the x-axis labelled at 13 evenly spaced points as {'jan 15','feb 15',...,'dec 15','jan 16'}, and the y-axis labelled at every row from 1 to 24, like this:
Desired imagesc axes
When I run the script, it displays the y-axis as I want it, but it only displays the first label on the x axis and ignores the others. I can get this to work for a plot, but I can't get it to work for an imagesc. I've included my script below. Does anyone know how to make the imagesc display all 13 labels on the x-axis at evenly spaced intervals?
mylabels = {'jan 15','feb 15','mar 15','apr 15','may 15','jun 15','jul 15','aug 15','sep 15','oct 15','nov 15','dec 15','jan 16'};
testspacing = (1:(60*24*30):528480);
figure
imagesc(rand(24,366))
set(gca,'XTick',testspacing,'XTickLabel',mylabels,'XTickLabelRotation',45,'YTick',1:24,'YTickLabel',1:24)
The problem with your code is that your only one of your ticks from testspacing falls in the range of the plot testspacing=[1 43201 ...]. You can check the range of your x-axis by running xlim without any arguments.
You can rescale testspacing to fit your x-axis e.g. like:
xmax = 366;
mylabels = {'jan 15','feb 15','mar 15','apr 15','may 15','jun 15','jul 15','aug 15','sep 15','oct 15','nov 15','dec 15','jan 16'};
testspacing = (1:(60*24*30):528480);
testspacing = testspacing/max(testspacing)*xmax;
figure
imagesc(rand(24,xmax))
set(gca,'XTick',testspacing,'XTickLabel',mylabels,'XTickLabelRotation',45,'YTick',1:24,'YTickLabel',1:24)
or you just generate testspacing properly. Since you are putting own labels on the axis anyway you might just choose use testspacing = [0:30.5:366] or testspacing = [0:30:366] depending on what you want. This will also help you debug your own code later on.
On another note you should think about reducing the number of labels in general and decide which of the labels are really helpful. Maybe every 2nd or 3rd month is enough. You can "remove" individual labels by setting them to empty strings ''.
I have two graphs, one is the exact graph of a solution, the other is a numerical approach. I have 4 specific points in my figure (t=0.25,0.5,0.75,1), where I want to illustrate the difference between the two graphs with a straight line. I found the errorbars function but i don't see any use there. Hope you can help me!
Edit:
this is the example figure:
t = [0:0.25:1];
y = t.*4;
x = t.^2+3;
plot(t,y,t,x)
I have 4 points now, t=0.25; t=0.5; t=0.75; t=1; At this points, I just want a vertical line between the two plots. I already have tried this: plot([t(1),y(1)],[t(1),x(1)])
but it just creates a line over the whole figure.
✶ It seems that you're not using hold on before using plot command the second time because otherwise you'd have got the desired result (which is actually not a correct way of plotting a vertical line).
✶ You're mixing up the values of x and y for plot(x,y). To plot a vertical line, it should be used like this: plot([x,x], [y1,y2])
For your case, you may not notice the difference between plot([t(1),y(1)],[t(1),x(1)]) (which is incorrect) and plot([t(1),t(1)],[x(1),y(1)]) (which is correct) because it is by chance that the values are same. Plot it for some other points and you'll realize the difference.
Fixed Code:
t = [0:0.25:1];
y = t.*4;
x = t.^2+3;
plot(t,y,t,x)
hold on
plot([t(1) t(1)],[x(1) y(1)])
% You have 't' on your horizontal axis and 'x'and 'y' values on the vertical axis
axis equal % just for better visualization
Output:
I'm the MatLab newbie and I need some help to create a linear and non-linear axis in one chart.
I need to make chart with 2 different X-axes. One X-axis displays 1000/T at the bottom and the second X-axis displays a T at the top of the chart.
Example figure:
Do you have any idea how to solve this problem in MatLab?
Thanks.
This can be done by simply creating a second axes object at the same place as the first. Let's first create some data:
x1 = 1:0.1:3.5;
x2 = 1./x1;
y = (0.5*(x1-2)).^3;
Now we can create a normal plot with the first axes, and get the axes handle:
plot(x1,y,'-r');
ax(1) = gca;
Then we create the second axes object, at the same position as the first, and make the color none so it is transparent and the plot from below is still visible. As this adds a second Y axis too, we simply remove the Y ticks of the second axis.
ax(2) = axes('Position',ax(1).Position,'XAxisLocation','top','Color','none');
set(ax(2),'YTick',[]);
Now lets just format the second X axis as we like. Let's set the limits to the minimum and maximum of the x2 vector, and make it logarithmic:
set(ax(2),'XLim',[min(x2),max(x2)]);
set(ax(2),'XScale','log');
Now we still have the problem that the XTicks of ax(1) are also displayed at the top, and the XTicks of ax(2) are displayed at the bottom. This can be fixed by removing the box around the existing axes and creating a third axis without any ticks but with a box.
box(ax(1),'off');
box(ax(2),'off');
ax(3) = axes('Position',ax(1).Position,'XTick',[],'YTick',[],'Box','on','Color','none');
Now finally we can link the axes to be able to zoom correctly
linkaxes(ax);
And that should be it...
There is documentation for having a graph with two y-axes on the Mathworks website . .
http://de.mathworks.com/help/matlab/creating_plots/plotting-with-two-y-axes.html
It should be trivial to covert the concepts to the x-axis.
I have plotted a figure with multiple lines on it, and I have noticed that the lines for the plot overlap the x-axis when they are zero. Is there a way that I can essentially get the x-axis to plot on the top, rather than the lines?
Here is a MWE that does the same thing (I haven't put my exact code up as my dataset is quite big).
xdata=1:1:10;
ydata=[1;0.8;0.6;0.4;0.2;0;0;0;0;0];
line(xdata,ydata)
After I plot the lines (multiple per plot in my case), I do various other things with the axes so I get what I need (including adding a secondary set of axes). None of this seems to make any difference as to whether the x-axis is plotted on top of the lines or not.
I did have a search online but couldn't find anything to do with this.
The answer given by Luis is a nice workaround, but the official way to solve this problem is to use the layer property of the axis object, see the manual. To plot the axis on top of the data you do
set(gca,'Layer','top')
To automatically do this for all your plots, you can put the following line in your startup.m:
set(0,'DefaultAxesLayer','top')
This kind of answers you do not make up yourself, I only discovered this trick after asking more or less the same question on comp.soft-sys.matlab many years ago. See also this SO question.
After having plotted all your lines, plot a line on the x axis with the same color as the axis:
hold on
a = axis; %// gives xmin xmax ymin ymax
cx = get(gca,'Xcolor'); %// color of x axis
plot([a(1) a(2)], [a(3) a(3)], 'color', cx)
If the lines also overlap with the y axis and you also want that axis to appear on top, add the following:
cy = get(gca,'Ycolor'); %// color of y axis
plot([a(1) a(1)], [a(3) a(4)], 'color', cy)