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 :)
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);
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.
I am trying to create area plots with 2 y-axis using plotyy by using 'area' function. I don't want to have any tick marks or labels or titles but I just want the outside box. I would also like to save just the plot (not the entire figure window) as a png file.
When I turn off the x and y-axis ticks and labels, the box looks thin on the bottom and left, thick on the top and right. What am I doing wrong?
Also, if I try to make the box 'LineWidth' fat, I see two tick marks at the bottom left and bottom right - which ruin the plot and I am unable to remove. Can someone help?
My test code is below:
x = 1:100;
y1 = rand(size(x));
y2 = 100*rand(size(x));
fig_handle = figure('units','inches','position',[1 1 9 3]);
[a,p1,p2] = plotyy(x,y1,x,y2,'area');
c1 = get(p1,'child');
c2 = get(p2,'child');
set(c1,'facea',0.5,'FaceColor','b','EdgeColor',[0 0 0]);
set(c2,'facea',0.5,'FaceColor','r','EdgeColor',[0 0 0]);
set(c1,'Line','None');
set(c2,'Line','None');
set(a,'Layer','top')
set(a,'XTick',[]);
set(a(1),'YTick',[]);
set(a(2),'YTick',[]);
set(a,'TickDir','in')
set(a,'LineWidth',5);
Also, notice how the left Y-axis has red area on it, while the right Y-axis doesn't. Is this fix-able?
Any help would be appreciated! Also, I am new to StackOverflow - so, if these are too many questions in one post, please pardon me and I will post them as separate requests/questions.
Here is a workaround for the red appearing on the left Y-axis.
Since the axes line is quite thick, the data displayed close to it is drawn over it. To avoid this, you can slightly shift the x limits of the axes to make more room for the data. Do so by changing the XLim property of either axes since they share the same x limit:
XL = get(a,'Xlim');
xl = XL{1}; %// here XL{1} and XL{2} are the same...[1 100]
set(a(:),'Xlim',[xl(1)-.5 xl(2)+.5])
As for the annoying tick marks at the bottom of the plot, I must say that I don't know how to remove them while keeping the axes visible.
As an alternative solution to plotyy, here is a way to obtain a good result (I think) without plotyy. The trick is to superimpose 2 axes and make both of them not visible, then set the figure's color to white and add a black rectangle surrounding the plot.
Here is the code:
clear
clc
close all
x = 1:100;
y1 = rand(size(x));
y2 = 100*rand(size(x));
H1 = area(x,y1);
%// Set the figure color to white
set(gcf,'Color','w')
%// Plot data and set different properties for each axes
A1 = gca;
A2 = axes('Position',get(A1,'Position'));
H2 = area(x,y2);
set(A2,'YAxisLocation','right','Color','none','XTickLabel',[]);
set(A2,'XLim',get(A1,'XLim'),'XTick',[],'YTick',[]);
set(A1,'XTick',[],'YTick',[]);
%// Make both axes not visible.
set(A2,'Visible','off')
set(A1,'Visible','off')
axes(A1)
%// Get axes limits
XL = get(gca,'XLim');
YL= get(gca,'YLim');
%// Create rectangle as a bounding box
rectangle('Position',[XL(1) YL(1) XL(2)-1 YL(2)],'LineWidth',5)
%//===
%// Change the data color/properties
hP = findobj('Type','patch');
set(hP(1),'FaceColor','b','FaceAlpha',.5,'EdgeColor',[0 0 0],'line','none')
set(hP(2),'FaceColor','r','FaceAlpha',.5,'EdgeColor',[0 0 0],'line','none')
And the output:
It's not perfect but hope that helps!
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 :
I have a curve in which the minimum point is not obvious to the naked eye. For that reason I'm looking to highlight the minimum point using a marker.
Ideally I would highlight the point with a marker and also have its coordinates displayed in text on the figure.
You can do it this way:
%// Example plot
x = 1:10;
y = randn(1,10);
plot(x,y)
%// Marker at minimum
[ymin imin] = min(y);
xmin = x(imin);
hold on
style = 'ro'; %// red circle. Change as needed
markersize = 10; %// change as needed
plot(x(imin), ymin, style, 'markersize', markersize)
%// Text with coordinates of minimum
offset = -.05; %// vertical offset as a fraction of y-axis span. Change as needed.
text(x(imin),ymin+diff(ylim)*offset,['(' num2str(x(imin)) ',' num2str(ymin) ')'])
%// Enlarge y axis so that text is properly seen, if offset is negative
ylim(ylim+[diff(ylim)*offset*(offset<0) 0])
You might also want to enlarge the x axis if the text is close to the left or to the right. It could be done with xlim in a similar way.
Assuming you know the coordinates of that point, you can do something like:
hold on; % add things to the current figure
plot(x_coord, y_coord, '+r')
This will put a red plus sign at that point.
This should plot the minimum point(s), assuming you have data like y and x,
plot(x(y==min(y)),min(y),'o')
adding the text could be trickier depending on what you want, but at least these are the coordinates.