I'm trying to position MATLAB's ticks to line up with my grid, but I can't find a good way to offset the labels.
Also, if I run set(gca,'XTickLabel',1:10), my x tick labels end up ranging from 1 to 5. What gives?
You need to move the ticks, but get the labels before and write them back after moving:
f = figure(1)
X = randi(10,10,10);
surf(X)
view(0,90)
ax = gca;
XTick = get(ax, 'XTick')
XTickLabel = get(ax, 'XTickLabel')
set(ax,'XTick',XTick+0.5)
set(ax,'XTickLabel',XTickLabel)
YTick = get(ax, 'YTick')
YTickLabel = get(ax, 'YTickLabel')
set(ax,'YTick',YTick+0.5)
set(ax,'YTickLabel',YTickLabel)
Or if you know everything before, do it manually from the beginning:
[N,M] = size(X)
set(ax,'XTick',0.5+1:N)
set(ax,'XTickLabel',1:N)
set(ax,'YTick',0.5+1:M)
set(ax,'YTickLabel',1:M)
The marked answer works with a surf or mesh plot, however, I needed a solution which worked for a 2d plot.
This can be done by creating two axes, one to display the grid and the other to display the labels as follows
xlabels=1:1:10; %define where we want to see the labels
xgrid=0.5:1:10.5; %define where we want to see the grid
plot(xlabels,xlabels.^2); %plot a parabola as an example
set(gca,'xlim',[min(xgrid) max(xgrid)]); %set axis limits so we can see all the grid lines
set(gca,'XTickLabel',xlabels); %print the labels on this axis
axis2=copyobj(gca,gcf); %make an identical copy of the current axis and add it to the current figure
set(axis2,'Color','none'); %make the new axis transparent so we can see the plot
set(axis2,'xtick',xgrid,'XTickLabel',''); %set the tick marks to the grid, turning off labels
grid(axis2,'on'); %turn on the grid
This script displays the following figure :
Related
Is there a way to remove only the axis lines in the Matlab figure, without affecting ticks and tick labels.
I know that box toggles the upper and right axes lines and ticks and that works perfectly for me.
But my problem is that I want eliminate the bottom and left lines (only lines!) but keeping the ticks and tick labels.
Any tricks?
Yair Altman's Undocumented Matlab demonstrates a cleaner way to do this using the undocumented axes rulers:
plot(x,y);
ax1 = gca;
yruler = ax1.YRuler;
yruler.Axle.Visible = 'off';
xruler = ax1.XRuler;
xruler.Axle.Visible = 'off'; %// note you can do different formatting too such as xruler.Axle.LineWidth = 1.5;
A nice feature of this approach is that you can separately format the x and y axis lines.
Solution for Matlab versions prior to R2014b
You can introduce a new white bounding box and put it on top.
// example data
x = linspace(-4,4,100);
y = 16 - x.^2;
plot(x,y); hold on
ax1 = gca;
set(ax1,'box','off') %// here you can basically decide whether you like ticks on
%// top and on the right side or not
%// new white bounding box on top
ax2 = axes('Position', get(ax1, 'Position'),'Color','none');
set(ax2,'XTick',[],'YTick',[],'XColor','w','YColor','w','box','on','layer','top')
%// you can plot more afterwards and it doesn't effect the white box.
plot(ax1,x,-y); hold on
ylim(ax1,[-30,30])
Important is to deactivate the ticks of the second axes, to keep the ticks of the f rist one.
In Luis Mendo's solution, the plotted lines are fixed and stay at their initial position if you change the axes properties afterwards. That won't happen here, they get adjusted to the new limits. Use the correct handle for every command and there won't be much problems.
Dan's solution is easier, but does not apply for Matlab versions before R2014b.
There is another undocumented way (applicable to MATLAB R2014b and later versions) of removing the lines by changing the 'LineStyle' of rulers to 'none'.
Example:
figure;
plot(1:4,'o-'); %Plotting some data
pause(0.1); %Just to make sure that the plot is made before the next step
hAxes = gca; %Axis handle
%Changing 'LineStyle' to 'none'
hAxes.XRuler.Axle.LineStyle = 'none';
hAxes.YRuler.Axle.LineStyle = 'none';
%Default 'LineStyle': 'solid', Other possibilities: 'dashed', 'dotted', 'dashdot'
This is different from Dan's answer which uses the 'visible' property of rulers.
You could "erase" the axis lines by plotting a white line over them:
plot(1:4,1:4) %// example plot
box off %// remove outer border
hold on
a = axis; %// get axis size
plot([a(1) a(2)],[a(3) a(3)],'w'); %// plot white line over x axis
plot([a(1) a(1)],[a(3) a(4)],'w'); %// plot white line over y axis
Result:
As noted by #SardarUsama, in recent Matlab versions you may need to adjust the line width to cover the axes:
plot(1:4,1:4) %// example plot
box off %// remove outer border
hold on
a = axis; %// get axis size
plot([a(1) a(2)],[a(3) a(3)],'w', 'linewidth', 1.5); %// plot white line over x axis.
%// Set width manually
plot([a(1) a(1)],[a(3) a(4)],'w', 'linewidth', 1.5);
Based code from here, I wrote a function which plots a figure and puts x-axis labels on both the top and bottom of the figure, as well as y-axis labels on the left and right side. My problem is that I need to run the code multiple times and each time the labels get written over, and for some reason the y-axis labels get overwritten in a weird way as shown,
first run:
second run:
The following is an mwe:
% sample data, plot
x=[1:168];
y=x;
plot(x, y, 'r', 'LineWidth', 1);
set(gca, 'XTick', [], 'YTick', []);
% set left yaxis label
ylabel(directions{1,1},'Rotation',-360);
% Adjust position - this seems to be what's causing the issue!
ylabelh = get(gca,'YLabel');
rpos = get(ylabelh,'Position');
set(ylabelh,'Position',rpos + [1.5*rpos(1) 0 0])
% do stuff... as per link above
axesPosition = get(gca,'Position');
hNewAxes = axes('Position',axesPosition,... %# Place a new axes on top...
'Color','none',... %# ... with no background color
'YAxisLocation','right',... %# ... located on the right
'XTick',[],'YTick',[],... %# ... with no x tick marks
'Box','off');
ylabel(hNewAxes,directions{2,1},'Rotation',-360); % yaxis label right
% Adjust position
ylabelh = get(gca,'YLabel');
Lpos = get(ylabelh,'Position');
set(gca,'YTick',[]);
set(ylabelh,'Position',Lpos+ [+Lpos(1)*0.02 0.05 0])
% -- And repeat for x axis -- %
% x axis labels
xlabel(directions{3,1},'Rotation',-360); % xaxis label bottom
% Adjust position
xlabelh = get(gca,'XLabel');
xlabpos = get(xlabelh,'Position');
set(gca,'XTick',[]);
rpos = get(xlabelh,'Position');
% do stuff ... as above
axesPosition = get(gca,'Position');
hNewAxes = axes('Position',axesPosition,... %# Place a new axes on top...
'Color','none',... %# ... with no background color
'XAxisLocation','top',... %# ... located on the right
'XTick',[],'YTick',[], ... %# ... with no x tick marks
'Box','off');
% xaxis label top
xlabel(hNewAxes,directions{4,1},'Rotation',-360);
Weirdly, if I run the code as a script it's fine (well, the labels get written over but I don't see the issue with the y axis labels) but if I run as a function multiple times in debug mode (which is currently the primary way I'm using it) then I see the above artefacts.
If you run your code then check at the end you will see that you have created 3 axes in your script. Run it once and they type get(gcf,'Children'). If you run it again you are adding another 2 axes, this continues everytime you run it.
Why does this happen?
Well your code creates 2 new axes handles (which you call the same name -> which you shouldn't do) - but only after you have already used gca -> i.e. the current axes (if none exists one is created).
I would advise you to completly reconfigure you code. Start by creating 2 axes before you do any plotting/labeling etc.. store the 2 axes variables independently which will allow you to refer to them as and when you need to.
Also it good practice to never rely on gca or gcf to get the currently axes or figure -> as it will eventually come back to bite you. Store the axes/figure handles and refer to them explicitly.
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.
How can I align an inset of a MATLAB plot to the top right edge of the box, like in the picture?
The example was generated with GNU R as explained in How to add an inset (subplot) to "topright" of an R plot?
Here is a way to do it:
Basically create a figure with an axes, and then add a new axis that you place to a specific position and to which you give the size you want.
Code:
clc
clear
close all
%// Dummy data
x = -20:0;
x2 = x(5:10);
%// Zoomed region to put into inset.
y = x.^2;
y2 = y(5:10);
%// Create a figure
hFig = figure(1);
%// Plot the original data
hP1 = plot(x,y);
xlabel('Original x','FontSize',18)
ylabel('Original y','FontSize',18)
hold on
%// Add an axes and set its position to where you want. Its in normalized
%// units
hAxes2 = axes('Parent',hFig,'Position',[.58 .6 .3 .3]);
%// Plot the zommed region
plot(x2,y2,'Parent',hAxes2)
%// Set the axis limits and labels
set(gca,'Xlim',[x(5) x(10)])
xlabel('Zoomed x','FontSize',16)
ylabel('Zommed y','FontSize',16)
And output:
To be fancy you could play around with the new axes position so that the outer borders coincide with the large one, but that should get you going :)
I can add 2 y-axis to a octave/matlab plot but when I try and add the x-axis at the bottom of the plot with xlabel('Frequency in Hz') it doesn't show up
[ax h1 h2]=plotyy(xx,yy,xx,yy2); %plot two y axes and 1 x-axis
axes(ax(1)); ylabel('Phase Angle in degrees');
axes(ax(2)); ylabel('Amplitude');
Anybody know how to fix this so the x-axis will also show up
I'm using octave 3.2.4 / matlab
Make sure to call xlabel() after referencing one of the specific axes on the plot. You just need to do it once, but because of the double axis, invoking x-label outside of a specific axis context won't work. The following works for me just fine in Octave 3.2.4.
xx = [1,2,3];
yy = [10,11,12];
yy2 = [-10,-11,-12];
[ax h1 h2]=plotyy(xx,yy,xx,yy2);
axes(ax(1)); xlabel('Frequency in Hz'); ylabel('Phase Angle in degrees');
axes(ax(2)); ylabel('Amplitude');
In order to add a label (either xlabel or ylabel) to certain axes you can also pass this axes reference as first argument of the command call. This way you will also guarantee that you are on the right context as #EMS pointed out.
xx = [1,2,3];
yy = [10,11,12];
yy2 = [-10,-11,-12];
[ax h1 h2]=plotyy(xx,yy,xx,yy2);
xlabel(ax(1),'Frequency in Hz'); ylabel(ax(1),'Phase Angle in degrees');
ylabel(ax(2),'Amplitude');
This is also better in terms of performance, as in case you call axes several times, you will see how everything slows considerably down.