I'm using the following code:
x = linspace(0, 9, 10);
y1 = x;
y2 = x.^2;
y3 = x.^4;
myfig = figure('Position', [500 500 400 320]); %[left, bottom, width, height]:
ax1 = gca;
hold on
p1 = plot(x,y1,'x--r');
p2 = plot(x,y2,'*-b');
xlabel('blaaa');
ylabel('fooo');
xlim([0 max(x)]);
ax2 = axes('Position',get(ax1,'Position'),...
'XAxisLocation','top',...
'YAxisLocation','right',...
'Color','none',...
'XTickLabel', [],...
'XColor','k','YColor','k');
ylabel(ax2, 'asdasd');
linkaxes([ax1 ax2],'x');
hold on
p3 = plot(x,y3,'s:g','Parent',ax2);
legend([p1 p2 p3], {'one', 'two', 'three'}, 'Location', 'NorthWest');
whereas the right y-label isnt shown: Is there a way to show it by decreasing either the margin between the left-edge and the left y-label or by decreasing the width of the actual plotted data without resizing the figure window?
Thanks
Edit: Added an image:
Either decrease the red margin or the 'green' size, because wherre the blue arrow is, the y-label is now shown anymore since it doesn't fit!
Try replacing the line:
ax1 = gca;
with:
ax1 = axes('Position',[0.11 0.11 0.75 0.812]);
To manually set the axis position/size in normalized units.
Related
I can't seem to get linkaxes to work (code is below). I am trying to get the subplots to line up, such that visually the x-axis is has the same range and width for both subplots. The misalignment is in both the pop-up figure window and the saved JPG. Using Matlab R2018a.
Here is my code, and below is what the figure looks like:
x1 = [27247 26973 27265 28924 27182 27430 26534 26839 7876 26484 29787 26934 27218 25777 27801 8250 34820 7980 26927 34639];
y1 = [-2350 -3334 -2948 -2336 -2778 -2813 -3383 -3635 -31 -3334 -4216 -3284 -2271 -2477 -2058 375 -821 351 -3441 -1108];
ax1 = subplot(2,1,1);
scatter(x1, y1)
box on
grid on
axis equal
xlims = get(gca, 'XLim')
ax = gca;
ax.XRuler.Exponent = 0;
ax.YRuler.Exponent = 0;
xlims = get(gca, 'XLim')
ax2 = subplot(2,1,2);
scatter(x1, y1)
xlim(xlims)
box on
grid on
ax = gca;
ax.XRuler.Exponent = 0;
linkaxes([ax1,ax2],'x')
I've also tried this (below), but it doesn't change the plot.
% adding this to the first subplot:
xlims = get(gca, 'XLim')
positioning = get(gca,'position');
% adding this to the second subplot:
xlim(xlims)
set(gca, 'position', [positioning(1) positioning(2)/5 positioning(3) positioning(4)]) %x y width height
And here is what the figure looks like:
This was solved on the Matlab forums, and here is a summary/application of the solution:
x1 = [27247 26973 27265 28924 27182 27430 26534 26839 7876 26484 29787 26934 27218 25777 27801 8250 34820 7980 26927 34639];
y1 = [-2350 -3334 -2948 -2336 -2778 -2813 -3383 -3635 -31 -3334 -4216 -3284 -2271 -2477 -2058 375 -821 351 -3441 -1108];
ax1 = subplot(2,1,1);
scatter(x1, y1)
box on
grid on
axis equal
xlims = get(gca, 'XLim')
ax = gca;
ax.XRuler.Exponent = 0;
ax.YRuler.Exponent = 0;
xlims = get(gca, 'XLim')
ax2 = subplot(2,1,2);
scatter(x1, y1)
xlim(xlims)
box on
grid on
ax = gca;
ax.XRuler.Exponent = 0;
set(gcf,'Resize','off') %%%%%%%% this line fixes it for some reason!
linkaxes([ax1,ax2],'x') % want to link x-axis only
%figOut = 'test';
%print(figOut, '-r300', '-djpeg')
I get the following figure with a bar plot :
I would like to remove the XTick with red circles but keep Xtick for the middle of each group of bars (i.e 1024, 10240, 102400, 1024000, 10240000).
I generate this image with the Matlab script below :
x = load('performances.txt');
% Get Runtimes
for i = 1:6
time_seq(1:5,i) = x((i-1)*5+1:i*5,3);
time_gpu(1:5,i) = x((i-1)*5+1:i*5,4);
speedup(1:5,i) = time_seq(1:5,i)./time_gpu(1:5,i);
end
% X axis
sizeArray = [1024 10240 102400 1024000 10240000 102400000]
figure(1);
% Get Histogram
h = bar(log10(sizeArray),log10(speedup(1:5,:)')); % get histogram
% Log10 for x-axis and xtick
set(gca,'Xtick',log10(1024):1:log10(1.024*10^8))
set(gca,'Xticklabel',10.^get(gca,'Xtick'));
set(h(1),'facecolor',[0.5 0.5 1]);
set(h(2),'facecolor',[1 0.5 0.5]);
set(h(3),'facecolor',[0.5 1 0.5]);
set(h(4),'facecolor',[0.5 0.5 0.5]);
set(h(5),'facecolor',[1 0.5 1]);
hPatch = findobj(h,'Type','patch');
set(hPatch,'facealpha',1);
grid on;
title('Benchmark GPU vs CPU');
% Size of WorkGroup
h = legend('N=16','N=32','N=64','N=128','N=256');
v = get(h,'title');
set(v,'string','WorkGroup size');
% Place legend
rect = [0.6,0.25,0.2,0.2];
set(h,'Position',rect,'color','w');
hPatch = findobj(h,'Type','patch');
set(hPatch,'facealpha',1);
xlabel('log(Array size)');
ylabel('log(Speedup)');
% Make right y-axis visible
ax1 = gca;
ax2 = axes('Position', get(ax1, 'Position'));
set(ax2, 'YAxisLocation', 'right', 'Color', 'none', 'XTickLabel', []);
set(ax2, 'YLim', get(ax1, 'YLim'));
I tried different things but couldn't make them disappear, anyone would have an idea or a clue ?
Thanks
It happens because of the last 3 lines in your code where you add the Y-axis from the right side. You need to add the following line at the end:
set(ax2,'XTick',[]);
Here is my result (with fake data):
I am having trouble getting my title to show when I have a figure with two x-axis.
The plot looks good and the axis scales are as I would like them to be but the second axis label and the title end up outside my figure.
How do I get the plot and axis to have the same size and change the size of the figure to include labels and title?
Here is a minimal example:
x1 = linspace(0, 5);
y11 = sin(x1);
y12 = cos(x1);
x2 = linspace(4, 12);
figure(1)
plot(x1, y11, 'r');
hold on
grid on
plot(x1, y12, 'k');
axis([0 5 -1 1.8]);
legend('sin(x)', 'cos(x)');
xlabel('x')
ylabel('y-label');
ax1 = gca;
ax1_pos = ax1.Position;
ax2 = axes('Position', ax1_pos,...
'XAxisLocation', 'top',...
'YAxisLocation', 'right',...
'Color', 'none');
ax2.YColor = 'w';
title('2:nd Harmonics');
line(x2,0,'Parent',ax2,'Color','k')
xlabel('n');
As a workaround you could pre-define the Position property (i.e. size) of the 1st axes before generating the plot so that the title appears correctly even if you add a 2nd axes. For example, right after the call to figure(1) add something like this:
ax1 = axes('Position',[0.11 0.11 0.75 0.75]);
Also, if you wish to print exponent values in the title you can use Latex formatting as follows:
title('2^{nd} Harmonics');
Here is the whole code with output:
clear
clc
close all
x1 = linspace(0, 5);
y11 = sin(x1);
y12 = cos(x1);
x2 = linspace(4, 12);
figure(1)
%// Set axes position manually
ax1 = axes('Position',[0.11 0.11 0.75 0.75]);
plot(x1, y11, 'r');
hold on
grid on
plot(x1, y12, 'k');
axis([0 5 -1 1.8]);
legend('sin(x)', 'cos(x)');
xlabel('x')
ylabel('y-label');
%ax1 = gca;
ax1_pos = get(ax1,'Position');
ax2 = axes('Position', ax1_pos,...
'XAxisLocation', 'top',...
'YAxisLocation', 'right',...
'Color', 'none');
set(ax2,'YColor','w');
%// Notice the Latex formatting to print the exponent
title('2^{nd} Harmonics');
line(x2,0,'Parent',ax2,'Color','k')
xlabel('n');
Then you can resize as you wish; the title stays visible.
The following code shows my problem. plotyy completely fails if the ticks are not at the same positions on both sides (which is rather the normal case...)
I require a plot with two y axis but the ticks only on one side. I was suggested to use addaxis, but I do not see how that helps me, since I do not want separated axis.
clf;
clc;
xaxis = 0:0.1:25;
ydata1 = linspace(12.1712,12.7679, length(xaxis));
ydata2 = linspace(0.3597,-28.7745, length(xaxis));
[AX,H1,H2] = plotyy(xaxis, ydata1, xaxis, ydata2);
% axis limits - x axis (min to max)
xlimits(1) = min(xaxis); xlimits(2) = max(xaxis);
set(AX, 'XLim', xlimits);
set(AX(2),'XTick',[]);
% y1 axis limits
ylimits(1) = min(ydata1); ylimits(2) = max(ydata1);
ylimits(2) = ylimits(2) + (ylimits(2)-ylimits(1))*0.05;
set(AX(1), 'YLim', ylimits);
% y2 axis limits
ylimits(1) = min(ydata2); ylimits(2) = max(ydata2);
ylimits(2) = ylimits(2) + (ylimits(2)-ylimits(1))*0.05;
set(AX(2), 'YLim', ylimits);
% y1 ticks
set(AX(1),'YTick',[12.0:0.1:12.8]);
% y2 ticks
set(AX(2),'YTick',[-25:5:0]);
print(gcf, ['-r' num2str(400)], ['test' '.png' ], ['-d' 'png']);
to Matthias,
set the XAxisLocation to top, and disable the XTickLabel. the upper line is back now :)
set(AX(2),'XAxisLocation','top', 'XTickLabel',[])
Try setting the ticks to empty set:
set(AX(2),'YTick',[]);
or
set(AX(1),'YTick',[]);
Edit(1): You can manually create the labels for left side and set the right side to []:
clf;
clc;
xaxis = 0:0.1:25;
ydata1 = linspace(12.1712,12.7679, length(xaxis));
ydata2 = linspace(0.3597,-28.7745, length(xaxis));
[AX,H1,H2] = plotyy(xaxis, ydata1, xaxis, ydata2);
% axis limits - x axis (min to max)
xlimits(1) = min(xaxis); xlimits(2) = max(xaxis);
set(AX, 'XLim', xlimits);
set(AX(2),'XTick',[]);
% y1 axis limits
ylimits(1) = min(ydata1); ylimits(2) = max(ydata1);
ylimits(2) = ylimits(2) + (ylimits(2)-ylimits(1))*0.05;
set(AX(1), 'YLim', ylimits);
x = linspace(ylimits(1),ylimits(2),10);
ticks1 = arrayfun(#(t){sprintf('%2.2f',t)},x);
% y2 axis limits
ylimits(1) = min(ydata2); ylimits(2) = max(ydata2);
ylimits(2) = ylimits(2) + (ylimits(2)-ylimits(1))*0.05;
x = linspace(ylimits(1),ylimits(2),10);
ticks2 = arrayfun(#(t){sprintf('%2.2f',t)},x);
set(AX(2), 'YLim', ylimits);
ticks = cell(size(ticks1));
for i=1:numel(ticks1)
ticks{i} = sprintf('%s / %s',ticks1{i},ticks2{i});
end
% y1 ticks
set(AX(1),'YTickLabel',ticks);
% % y2 ticks
set(AX(2),'YTick',[]);
Here is an approach that I got from the mathworks forum. The idea is to remove the box property, which creates the tics on the opposite side.
set(AX(1),'Box','off') % Turn off box of axis 1, which removes its right-hand ticks
set(AX(2),'Box','off') % Turn off box of axis 2, which removes its left-hand ticks
The downside is, that the upper line disappears. If someone knows how to get it back that would be great. Mybe with an empty plot over the current plot with the same dimensions??
Here is a solution using a third axis. For this solution first turn boxes of as suggested
set(ax(1),'Box','off') % Turn off box of axis 1, which removes its right-hand ticks
set(ax(2),'Box','off') % Turn off box of axis 2, which removes its left-hand ticks
Now, additionally add a third axis at the same position.
ax3 = axes( 'Position', get(ax(1), 'Position'),...
'XAxisLocation', 'top',...
'XTickLabel', my_XTickLabels_on_top,...
'YColor', 'none',...
'YTick', [],...
'YTickLabel', [],...
'Color', 'none', ...
cell_with_further_pValPairs{:});
One can also link the 'x' axis of all axes objects. The limits and ticks will then get updated accordingly.
linkaxes([ax ax3], 'x')
This will, however, not properly update the ticks of the third axis, unless you write a proper callback, which got even more tricky to do in MATLAB 2014b and above
To make the 'real' axes the current axes, it is possible to use
axes(ax)
Example:
with help of the community in this thread: Minor grid with solid lines & grey-color
I got it to work to set minor grid lines as solid and coloured style. But when adding a second y-axes it just messes up the y-ticks on the right axis! heres the example code:
x = linspace(0, 10, 11);
y1 = x.^3+1;
y2 = x+1;
y3 = y1./y2+5;
% plotte: http://www.mathworks.com/help/techdoc/ref/linespec.html
myfig = figure('Position', [500 500 445 356]); %[left, bottom, width, height]:
ax1 = axes('Position',[0.13 0.18 0.75 0.75]);
hold on
p1 = plot(x,y1,'x--r');
p2 = plot(x,y2,'*-b');
xlim([0 max(x)]);
ylim([0 max([max(y1) max(y2)])]);
col=.85*[1 1 1];
%# create a second transparent axis, same position/extents, same ticks and labels
ax2 = axes('Position',get(ax1,'Position'), ...
'Color','none', 'Box','on', ...
'XTickLabel',get(ax1,'XTickLabel'), 'YTickLabel',get(ax1,'YTickLabel'), ...
'XTick',get(ax1,'XTick'), 'YTick',get(ax1,'YTick'), ...
'XLim',get(ax1,'XLim'), 'YLim',get(ax1,'YLim'));
%# show grid-lines of first axis, give them desired color, but hide text labels
set(ax1, 'XColor',col, 'YColor',col, ...
'XMinorGrid','on', 'YMinorGrid','on', ...
'MinorGridLineStyle','-', ...
'XTickLabel',[], 'YTickLabel',[]);
%# link the two axes to share the same limits on pan/zoom
linkaxes([ax1 ax2],'xy');
ax3 = axes('Position',get(ax1,'Position'),...
'XAxisLocation','top',...
'YAxisLocation','right',...
'Color','none',...
'XTickLabel', [],...
'XColor','k','YColor','k');
%# link the two axes to share the same limits on pan/zoom
linkaxes([ax1 ax2 ax3], 'x');
ylabel(ax3, 'Speedup []');
ylim(ax3, [0 max(y3)]);
hold on
p3 = plot(x,y3,'s-.m','Parent',ax3);
hleg = legend([p1 p2 p3], {'CPU', 'GPU', 'Speedup'}, 'Location', 'NorthWest');
xlabel(ax2, 'N_{Funcs}');
ylabel(ax2, 't [s]');
set(hleg, 'FontAngle', 'italic')
and how it looks like:
Its simpler than you think: when you create the second axis ax2, set the 'Box' property to 'off' instead of 'on'.
Even more, you can simplify that part and create it as:
ax2 = copyobj(ax1,myfig);
delete( get(ax2,'Children') )
set(ax2, 'Color','none', 'Box','off')
The 2nd y-axis is "messed up" because the automatically generated YTick from y3 does not agree with the YTick from y1 and y2.
If this view is final (meaning you don't have to zoom in/zoom out or move the plot), you can manually define the YTick of ax3 to match those of ax1
ax3 = axes('Position',get(ax1,'Position'),...
'XAxisLocation','top',...
'YAxisLocation','right',...
'Color','none',...
'XTickLabel', [],...
'YTick', [0:max(y3)/5:max(y3)], ... %% Define 6 YTick (including 0) like ax1
'XColor','k','YColor','k');