No effect of activating BOX in axes properties in MATLAB - matlab

I want a box (Border) outside of my pie3 figure in MATLAB but when I activate (On) Box property in axes, noting will appear. I changed AmbientLightColor to black but I have same problem.
How can I draw a black line border for my pie3 figure in gui(GUIDE)?
Thanks.
Ps.
Luis Mendo Idea has this effect :
We have a 3D cube here, not a 2D normal box.

The axes are invisible after using pie3. You should make them visible:
set(gca,'Visible','on')
Optionally,
set(gca,'Box','on')
will add the "outer part" of the axes.

As I mentioned in the comments, another option to get a 2D border is to make two axes, one for the box & background and the other for your pie3 call:
x = [1,3,0.5,2.5,2]; % Sample data
mainfig = figure;
h_overlayaxes = axes( ...
'Box','on', ... % Turn on border
'Color',[1 1 1], ... % Set your background color
'Xtick',[], ... % Turn off x ticks
'Ytick',[] ... % Turn off y ticks
);
h_plotaxes = axes( ...
'Parent',get(h_overlayaxes,'Parent'), ... % Match parent figure
'Position',get(h_overlayaxes,'Position'), ... % Match overlay size & position
'Color','none' ... % Turn off background
);
pie3(x);

Related

Remove border around axes but keep the grid and ticklabels [duplicate]

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);

Placing ticks in the middle of each grid in matlab

I am trying to create a figure with axes on matlab. But I want the ticks on the y-axis to be in the middle of each grid. How do I do that?
An example is like this:
As a workaround, you could turn on both major and minor gridlines, but set the major ones to the back color like this:
ax = axes;
grid(ax,'on');
grid(ax,'Minor');
set(ax,'GridColor',get(ax,'Color'))
set(ax,'MinorGridLineStyle','-')
set(ax,'TickLength',[0;0]);
Which gives:
I'm not aware of a specific matlab function to accomplish this.
As a solution, you can draw the grid yourself with vertical and horizontal lines at 0.5, 1.5, 2.5, ...
I have also found another way by drawing my own minor gridlines and not showing the major gridlines.
figure1 = figure;
axes1 = axes('Parent',figure1,'ZGrid','on','XGrid','on',...
'YTickLabel',{'','1','2','3', ''},...
'YTick',[0 1 2 3 4 ],...
'YGrid', 'off')
ylim([0.5 3.5]);
xlim([0 20]);
% gridlines ---------------------------
hold on
g_y=[0.5:1:4]; % user defined grid Y [start:spaces:end]
g_x=[0:2:20]; % user defined grid X [start:spaces:end]
for i=1:length(g_y)
plot([g_x(1) g_x(end)],[g_y(i) g_y(i)],'k-') %x grid lines
end
Output:
Credit goes to https://au.mathworks.com/matlabcentral/answers/95511-in-matlab-is-there-a-way-to-set-the-grid-at-a-spacing-different-from-the-ticks-on-the-axes

How to have an image in background of plot in matlab

I have a plot from a network of lines in 3D space and I have one image from the object as well. Now I want to put the image file in the background of my plot as a fixed background and then the network should be plotted on that background. By the way, since the Network is in 3D space I can rotate it easily and it is important for me rotate the network on the my combined plot as well.
this is my code that I have written but it shows my plot separately! if I put imshow inside the figure then image will be ploted on the top of my network and I can see only one point of my network. Here is the link of Network and the background image from background
Here is my code: the first line plot the image and the rest of the code plot my network of lines:
Img1 = imshow('STP1.png');
figure('name','Distance');
hold on;
labels = cellstr( num2str([1:SIFT_Length]') );
text(SIFT_3D(:,1), SIFT_3D(:,2),SIFT_3D(:,3),labels,'FontWeight','bold','FontSize', 12,...
'VerticalAlignment','bottom','HorizontalAlignment','right')
title('Distances Network with colorized lines based on Uncertainty','FontWeight','bold');
hold on
for k = 1:Num_Line_SIFTS
plot3([SIFT_3D(Line_among_2_Sifts(k,1),1),SIFT_3D(Line_among_2_Sifts(k,2),1)],...
[SIFT_3D(Line_among_2_Sifts(k,1),2),SIFT_3D(Line_among_2_Sifts(k,2),2)],...
[SIFT_3D(Line_among_2_Sifts(k,1),3),SIFT_3D(Line_among_2_Sifts(k,2),3)],...
'o-','Color',[RGB_0_1(k,1) RGB_0_1(k,2) RGB_0_1(k,3)],'MarkerFaceColor',[RGB_0_1(k,1) RGB_0_1(k,2) RGB_0_1(k,3)],'MarkerEdgeColor',...
'k', 'LineWidth',2)
end
hold off;
Please help me how can I solve this issue.
What about this:
clear
clc
close all
%// Read image
Im=flipud(imread('STP1_low.png'));
%// Dummy surface to plot.
Z = peaks(25);
%// Prepare image position
shift = 20;
xIm=zeros(size(Z))-shift;
hold on
surface(xIm,Im,'FaceColor','texturemap','EdgeColor','none','CDataMapping','direct')
surface(Z,'FaceAlpha',0.8,'LineStyle','none','FaceColor','interp');
axis on
view(-35,45)
box on
rotate3d on
Output:
You can rotate it and the image stays as the background.
I'm not sure I understood your need, nevertheless ...
figure('name','Distance','unit','normalized');
a=axes('position',[0 0 1 1])
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% UPDATED CODE STARTS HERE
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Disable zoom
h=zoom;
setAllowAxesZoom(h,a,false);
% Disable rotation
h = rotate3d;
setAllowAxesRotate(h,a,false)
%
%%%%%%%%%%%%%%%%%%%%%%%%%%
% UPDATED CODE ENDS HERE
%%%%%%%%%%%%%%%%%%%%%%%%%%
%
hold on
imshow('Jupiter_New_Horizons.jpg','parent',a)
t=0:.01:2*pi;
z=sin(t).*cos(t)
a1=axes('position',[0.3 0.3 .5 .5])
plot3(cos(t),sin(t),z,'r','linewidth',3)
grid on
set(gca,'color','none')
This script generates the following graph:
Hope this helps.

Rotate MATLAB legend

Is there a way to rotate the MATLAB legend inside a plot? The image below should clarify my requirement.
the legend function can return serval of args:
[leg,labelhandles,outH,outM] = legend(varargin)
When you ask for the 2nd argument you get a list of all the Children and then you can use what phil's answer:
set(hc(3),'Position',[0.5 0.6 0],'Rotation',90); % Relocate and rotate text
set(hc(2),'Xdata',[0.5 0.5],'YData',[0.1 0.5]); % rotate the line
set(hc(1),'XData',0.5,'YData',0.3); % R
This is correct for matlab 2021b
You'll need to play around with the positioning, and need to do more work if you have more than one line plotted, but the following does it for your example.
plot(1:10); % create a dummy line
ha = legend('Plot'); %create a legend
set(ha,'Units','pixels'); % set axes unit to pixels
pos = get(ha,'Position'); % get the axes position
set(ha,'Position',[pos(1) pos(2)-pos(3) pos(4) pos(3)]); % Set the new position
hc = get(ha,'Children'); % Get the legend contents
set(hc(3),'Position',[0.5 0.6 0],'Rotation',90); % Relocate and rotate text
set(hc(2),'Xdata',[0.5 0.5],'YData',[0.1 0.5]); % rotate the line
set(hc(1),'XData',0.5,'YData',0.3); % Rotate the Marker
The example is not fully automated but should set you on the right route. You need to rotate the box containing the legend, and the label with the text./
% Example plot
plot(1:10)
h = legend('something')
% Rotate legend
set(h,'CameraUpVector', [1 0 0], 'Units','pixels','position',[460 230 25 150])
% Rotate text label
txt = findobj(h,'type','text');
set(txt,'rotation',90)
Unfortunately, the save as function restores the 'CameraUpVector'.

Minor grid with solid lines & grey-color

I'm using the following to display the minor grid in my plot:
grid(gca,'minor')
set(gca,'MinorGridLineStyle','-')
but I'd like to change the color of the grid lines to a nice greyscale. I can't find any option 'grid color' in matlab... Do you know any or any workaround?
I found this: http://www.mathworks.com/matlabcentral/fileexchange/9815-gridcolor but as I read of the comments, it doesn't work very well and further it only changes gridcolor, not the color of the minor grid...
Thanks!
EDIT:
Problem with semilogx as posting here now:
x = [1e-9 1e-8 1e-7 1e-6 1e-5 1e-4 1e-3 1e-2]';
y1 = linspace(20, 90, 8);
y2 = y1.^2;
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]:
p1 = semilogx(x,y1,'x--r',x,y2,'*-b');
ax1 = gca;
set(ax1, 'Position',[0.13 0.18 0.75 0.75]);
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'),...
'XScale', 'log');
%# 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',[],'XScale', 'log');
%# link the two axes to share the same limits on pan/zoom
linkaxes([ax1 ax2],'xy');
Displaying like this:
EDIT2: A problem occurs when adding a second y-axes as in the following picture, look at the ticks of the right y-axes:
this will be discussed here to have a better overview!
Matlab: Problem with ticks when setting minor grid style and two y-axis
Set the 'XColor','YColor' axes properties. Note that these properties determine the color of the axis lines, tick marks, tick mark labels, and the axis grid lines, so AFAIK you can't assign those different colors than that of the entire axis..
Example:
plot(rand(10,1))
set(gca, 'XMinorGrid','on', 'YMinorGrid','on', 'XColor','r', 'YColor','g')
EDIT1:
You can always create a second transparent axis with the desired grid colors, but with no ticks or labels, stacked on top of the current axis. Here is an example:
%# create plot as usual
plot(rand(10,1))
hAx1 = gca;
%# create a second axis, same position/extents, no tick or labels, colored grid-lines
hAx2 = axes('Position',get(hAx1,'Position'), ...
'Color','none', 'TickLength',[1e-100 1e-100], ...
'XMinorGrid','on', 'YMinorGrid','on', ...
'Box','off', 'XColor','g', 'YColor','r', ...
'XTickLabel',[], 'YTickLabel',[], ...
'XTick',get(hAx1,'XTick'), 'YTick',get(hAx1,'YTick'), ...
'XLim',get(hAx1,'XLim'), 'YLim',get(hAx1,'YLim'));
%# position it on top
%#uistack(hAx2,'top')
%# redraw the enclosing box in the original axis colors
x = get(hAx1,'XLim');
y = get(hAx1,'YLim');
line([x([1 2]) nan x([2 1])],[y([1 1]) nan y([2 2])],'Color',get(hAx1,'XColor'))
line([x([1 1]) nan x([2 2])],[y([1 2]) nan y([2 1])],'Color',get(hAx1,'YColor'))
The only problem is that the grid lines are drawn on top of your plot, which might get in the way if the grid-lines are thick :)
EDIT2:
Seems like #yoda had a similar idea to the above. Here is a slightly improved version inspired by his solution:
%# create plot as usual
plot(11:20, rand(10,1)*5)
hAx1 = gca; %# get a handle to first axis
%# create a second transparent axis, same position/extents, same ticks and labels
hAx2 = axes('Position',get(hAx1,'Position'), ...
'Color','none', 'Box','on', ...
'XTickLabel',get(hAx1,'XTickLabel'), 'YTickLabel',get(hAx1,'YTickLabel'), ...
'XTick',get(hAx1,'XTick'), 'YTick',get(hAx1,'YTick'), ...
'XLim',get(hAx1,'XLim'), 'YLim',get(hAx1,'YLim'));
%# show grid-lines of first axis, give them desired color, but hide text labels
set(hAx1, 'XColor','g', 'YColor','r', ...
'XMinorGrid','on', 'YMinorGrid','on', ...
'XTickLabel',[], 'YTickLabel',[]);
%# link the two axes to share the same limits on pan/zoom
linkaxes([hAx1 hAx2],'xy');
%# lets create a legend, and some titles
legend(hAx1, 'text')
title('title'), xlabel('x'), ylabel('y')
EDIT3 (take 2):
Here is the same example but with a log-scale x-axis. Note how instead of creating a second axis and manually setting its properties to match the first, I simply copyobj the axis, and delete its children.
%# create a plot as usual (x-axis is in the log-scale)
semilogx(logspace(0,5,100), cumsum(rand(100,1)-0.5))
xlabel('x'), ylabel('y'), title('text')
legend('plot')
%# capture handle to current figure and axis
hFig = gcf;
hAx1 = gca;
%# create a second transparent axis, as a copy of the first
hAx2 = copyobj(hAx1,hFig);
delete( get(hAx2,'Children') )
set(hAx2, 'Color','none', 'Box','on', ...
'XGrid','off', 'YGrid','off')
%# show grid-lines of first axis, style them as desired,
%# but hide its tick marks and axis labels
set(hAx1, 'XColor',[0.9 0.9 0.9], 'YColor',[0.9 0.9 0.9], ...
'XMinorGrid','on', 'YMinorGrid','on', 'MinorGridLineStyle','-', ...
'XTickLabel',[], 'YTickLabel',[]);
xlabel(hAx1, ''), ylabel(hAx1, ''), title(hAx1, '')
%# link the two axes to share the same limits on pan/zoom
linkaxes([hAx1 hAx2], 'xy');
%# Note that `gca==hAx1` from this point on...
%# If you want to change the axis labels, explicitly use hAx2 as parameter.
You should get the correct plot in your example with this code. However I think the x variable values you choose might be too close in the current figure size to show all the vertical lines (simply maximize the figure to see what I mean)...
To get a better idea of what each axis contains, here is a divided view where the plot on the left contains only the graphics rendered by hAx1, while the plot on right contains only the hAx2 components. Those two views are basically overlayed on top of each other in the final figure shown before.
Unfortunately, while the trick of over- or under-laying a second, gridded axes mostly works, Matlab does not render it properly when you save to a PDF file. This is because Matlab does not support transparency in PDFs.
One workaround is to simply use line to draw in the grid lines one by one:
for dir='XY';
ticks = get(gca, [dir 'Tick']);
lim = get(gca, [dir 'lim']);
for ii=1:length(ticks)
coord = ticks(ii);
for jj=1:9,
if jj==1 % major grid properties
color = [1 1 1]*0.9;
weight = 2;
else % minor grid properties
color = [1 1 1]*0.9;
weight = 1;
end
if jj*coord > lim(2)
continue
end
if dir=='X'
L = line((jj*coord)*[1 1], get(gca, 'ylim'), ...
'color', color, 'linewidth', weight);
else
L = line(get(gca, 'xlim'), (jj*coord)*[1 1], ...
'color', color, 'linewidth', weight);
end
uistack(L, 'bottom');
end
end
end
One downside of this approach is that it overwrites the tick marks and plot boundary box. A solution to this is to combine this approach with the trick of under-laying a second axes. Draw the fake grid on the underlying axes. This IS rendered properly in PDF:
While Amro is right that the minor grid's color is the same as that of the axis labels, you can always turn off the axis labels and overlay a second axes with transparent filling and set the labels on that in a different color. Here's a small example showing how:
plot(rand(10,1))
xTicks=get(gca,'xTick');
yTicks=get(gca,'ytick');
set(gca, 'XMinorGrid','on', 'YMinorGrid','on',...
'XColor','r', 'YColor','g','xticklabel',[],'yticklabel',[],...
'box','off')
h2=axes;
set(h2,'color','none','xtick',linspace(0,1,numel(xTicks)),'xticklabel',xTicks,...
'ytick',linspace(0,1,numel(yTicks)),'yticklabel',yTicks)
This lets you set independent colors for major and minor X and Y grid lines, without overwriting the outer box. Even better, subsequent legend() commands will pick up the plot lines, not the manually drawn grid lines.
The trick is to make copies of the axes, then reverse their order in the figure's drawing hierarchy. Each copy of the axes can then draw its own set of grid colors and styles.
This strategy is compatible with subplot() and print().
function gridcolor(majorX, majorY, minorX, minorY)
ax1 = gca; %# get a handle to first axis
%# create a second transparent axis, same position/extents, same ticks and labels
ax2 = copyobj(ax1,gcf);
ax3 = copyobj(ax1,gcf);
delete(get(ax2,'Children'));
delete(get(ax3,'Children'));
set(ax2, 'Color','none', 'Box','off','YTickLabel',[],'YTickLabel',[],...
'GridLineStyle', '-',...
'XGrid','on','YGrid','on',...
'XMinorGrid','off','YMinorGrid','off',...
'XColor',majorX,'YColor',majorY);
set(ax3,'Box','off','YTickLabel',[],'YTickLabel',[],...
'MinorGridLineStyle','-',...
'XGrid','off','YGrid','off',...
'XMinorGrid','on','YMinorGrid','on',...
'XColor',minorX,'YColor',minorY);
set(ax1, 'Color','none', 'Box','on')
handles = [ax3; ax2; ax1];
c = get(gcf,'Children');
for i=1:length(handles)
c = c(find(c ~= handles(i)));
end
set(gcf,'Children',[c; flipud(handles)]);
linkaxes([ax1 ax2 ax3]);
end
subplot(211);semilogx([1:4000]);gridcolor('r','g','c','b');
subplot(212);semilogx(([1:4000]).^-1);gridcolor('r','g','c','b');