This tutorial explains how to change certain default settings of Matlab figures, but what about the properties not listed there? For example, if I want to change the font size of the x-axis label and make the y-axis label in Latex style, whats the name for these properties? (what's the xxx in defaultxxx)
In other words, I'm looking for something similar to this matplotlib stylesheet (but for Matlab) where I can easily find the names of the properties I'm looking for so I can just change the values easily.
MATLAB has a built-in figure editor, so you can do pretty much anything there. When you plot something, in the figure, go to View > Property editor and you try different things.
If you want to do it manually, the problem is that there is not just one object in the plot figure. You can generally look at the options for figures, axes, plot and surface. However, it it possible that you will have to look further for some more specific types of figures. Useful things can be found here, that are not in the official MATLAB documentation, but you must usually search a lot.
I was looking at the link you provided for matplotlib and decided to do something similar as an example of working with MATLAB plots. The following code:
x = linspace(0, 2*pi, 100);
y = sin(x);
% Plot a sinus curve, make the data depicted with red line and red filled dots
plot(x, y, 'r-o','MarkerFaceColor','r')
set(gca, ... % Get current axes
'Color','k', ... % Set plot background color to black
'XColor',[1 1 1], ... % Set color of x axis to white
'YColor',[1 1 1], ... % Set color of y axis to white
'GridColor',[1 1 1], ... % Set color of grid to white
'GridLineStyle','--', ... % Set the grid to be dashed
'YTick',-1:0.25:1) % Set Y axis ticks from -1 to 1 with step 0.25
set(gcf,'Color','k') % Set background of the current figure to black
xlabel('Some x axis / Units') % Set X axis label
ylabel('Some y axis / Units') % Set Y axis label
grid on % Make the grid shown
And the result should look like this:
By the way, you can use some basic LaTeX notation in MATLAB without changing anything. Try writing something like
xlabel('\rho_{0} / kg m^{-3}')
Related
Here is a simple MATLAB code. How to control the default distance between ticks of the Y axis? I want to make it smaller to fit in my paper. Hint: I update the post with 2 picture that shows what I mean (they are the same but the distance between the y axis ticks is smaller in one picture that the other.
x = linspace(-10,10,200);
y = sin(4*x)./exp(x);
plot(x,y)
xlim([0 10])
ylim([-0.4 0.8])
You can control the tick by using the gca object of the plot. Here is an example for xtick. Change 'xtick' to 'ytick':
plot(x,y);
set(gca, 'xtick', [-10:2:10]);
If you want to change the x-axis tick labels with new labels, then you can change the values of the labels as follows:
% specify the ticks first where you want to change
xticks([0 2 4 6 8])
% change the corresponding labels to the required ones
xticklabels({'-1', '-2', '-3', '-4', '-5'})
You can modify the height of the graph, maintaining the number and values of the tick marks, which makes the distance between tick marks smaller.
To do so, set the figure window’s 'Position' property (this is equivalent to dragging the edges of the window to make the figure smaller), and setting the locations of the tick marks manually to prevent MATLAB from reducing their number. For example:
h = gcf; % figure handle
a = gca; % axes handle
ticks = get(a,'YTick');
pos = get(h,'Position');
pos(4) = pos(4) * 0.75; # reduce the size
set(h,'Position',pos);
set(a,'YTick',ticks)
You should also note the PaperPosition, PaperSize and other Paper... properties of the figure, as they are used when printing (also to file). You might want to manually set those properties before creating a PDF or EPS from the graph.
Here is even a simpler way then what #Cris suggested:
ax = axes;
ax.YTickMode = 'manual';
ax.Position(4) = ax.Position(4)*0.75;
by setting the YTickMode to manual you prevent Matlab from updating the ticks upon resizing of the axes. Then you change the hight of the axes by setting the position property directly.
I visualize map overlays in Matlab with some surfaces with RGB texture. It looks like this:
I would like to have better Legend icons that make clear which layer is which. Something like this:
While I just did the second one in Gimp, I would like to have it in code.
Is it possible? It would be OK to use something from Matlab File Exchange or so.
One option will be to 'draw' this part of the legend manually after you create the figure. Here is how you can do this:
plot(nan(2)) % this is to make space in the legend box
hold on
plot(rand(15,1),'r') % here you plot all your data
hold off
hleg = legend({'Lidar Map','Radar Reprojection','Robot Path'});
% get the position of the legend, and calculate the place for the colormaps:
% this values may need to be adjusted
pos = hleg.Position.*[1.01 1+hleg.Position(4)/2.3 0.27 0.6];
% Create a 'picture' of what you want to appear in the legend:
level = 64; % level of color in the colormaps
cb = [1:level; zeros(1,level); (1:level)+level];
cmap = [1 1 1;0 0 0;flipud(gray(level-1)); jet(level)]; % custom colormap
legax = axes('Position',pos); % place the new picture above the legend
imagesc(legax,repelem(cb,[3 1 3],1)) % Create the picture
colormap(cmap) % appy custom colormap
axis off % remove all axes details
Here is the result:
The problem here is that the custom color map of the legend may interfere with the color map of the data itself, so you may need to take care of that also, but I can't tell you how without knowing how your data looks like and how do you currently apply the colormaps.
Quick version
How can I control the x- and y-values for a 3-d bar plot in Matlab?
Details
Say we have an 10 x 20 data matrix and we plot it using bar3, and we want to set the x- and y-values. For instance:
foodat = rand(10,20);
xVals = [5:14];
yVals = [-3:16];
bar3(xVals, foodat);
xlabel('x'); ylabel('y');
Is there a way to feed it the yVals as well? Otherwise the y axes always defaults to [1:N].
Note I don't just want to change the labels using XTickLabel and YTickLabel. I need to change the actual values on the axes, because I am plotting multiple things in the same figure. It isn't enough to just change how the (wrong) axis ticks are labeled. So this is different from issues like this:
How can I adjust 3-D bar grouping and y-axis labeling in MATLAB?
Other things I have tried
When I try changing the xvals with:
set(gca,'XTick', xVals)
set(gca,'YTick', yVals)
The values are taken in, but actually show up on the wrong axes, so it seems x and y axes are switched using bar3. Plus, it is too late anyway as the bar graph was already plotted with the wrong x- and y-values, so we would end up giving ticks to empty values.
Note added
Matlab tech support just emailed me to let me know about the user contributed function scatterbar3, which does what I want, in a different way than the accepted answer:
http://www.mathworks.com/matlabcentral/fileexchange/1420-scatterbar3
I found a way of doing it. Ill give you a piece of code, then you'll need to "tidy up" , mainly the axis limits and the Xticks, as bar3 does set up the Xticks inside, so if you want others you'll need to set them manually yourself.
So the trick here is to get the Xdata from the bar3 handle. The thing here is that it seems that there is a handle for each row of the data, so you need to iterate for each of them. Here is the code with the current output:
foodat = rand(20,10);
xVals = [5:14];
yVals = [-3:16];
% The values of Y are OK if called like this.
subplot(121)
bar3(yVals, foodat);
subplot(122)
h=bar3(yVals, foodat);
Xdat=get(h,'XData');
axis tight
% Widdth of barplots is 0.8
for ii=1:length(Xdat)
Xdat{ii}=Xdat{ii}+(min(xVals(:))-1)*ones(size(Xdat{ii}));
set(h(ii),'XData',Xdat{ii});
end
axis([(min(xVals(:))-0.5) (max(xVals(:))+0.5) min(yVals(:))-0.5, max(yVals(:))+0.5])
Note: Y looks different but is not.
As you can see now the X values are the ones you wanted. If you'd want other size than 1 for the intervals between them you'd need to change the code, but you can guess how probably!
I know there is a function named annotation can plot arrows or double arrows. But annotation can only plot in normalized unit. For example:
annotation('arrows',[x1 x2],[y1 y2])
Here, [x1, x2] should be a ratio number less than one.
So, my question is how can I plot arrows with a true value rather than a normalized value?
I wonder if there is any other function can approach this or is there any function I can get the axis value of the figure so that I can adjust the true value into a normalized value.
For the positioning of annotations, Matlab offers the function dsxy2figxy to convert data space points to normalized space coordinates. However, for whatever reasons, the function is not included in the Matlab distribution and has to be "created" first.
Copy the following line into the command window and execute it to open the function in your editor.
edit(fullfile(docroot,'techdoc','creating_plots','examples','dsxy2figxy.m'))
To use the function dsxy2figxy save it somewhere in your matlab search path.
Please find the full instructions for the function dsxy2figxy at matlab-central: http://www.mathworks.de/help/techdoc/creating_plots/bquk5ia-1.html
Even though annotation uses normalized as default units, you can associate these objects to the current axes (gca) and use data units for setting X and Y properties.
Here is an example of plotting a single arrow.
plot(1:10);
ha = annotation('arrow'); % store the arrow information in ha
ha.Parent = gca; % associate the arrow the the current axes
ha.X = [5.5 5.5]; % the location in data units
ha.Y = [2 8];
ha.LineWidth = 3; % make the arrow bolder for the picture
ha.HeadWidth = 30;
ha.HeadLength = 30;
For anyone who comes across this topic looking to draw arrows in "data space" rather than in units relative to the figure and/or axes, I highly recommend arrow.m from the file exchange.
I've just discovered this method, since I don't want to have to bother with normalised units. Use the latex interpreter:
figure
plot([1:5],[1:5]*3,'.-')
%// Say I want to put an arrow pointing to the location, [3 9]
text(2.94,8.3,'\uparrow','fontsize',20)
text(2.8,7.8,'point [3,9]')
To make the arrow longer, use a larger fontsize.
Pros
Easier, faster and quicker than using normalised units
Don't need to install any functions (good for us lazy people..)
making use of the LaTeX interpreter, there is a whole range of arrows (up, down, left, right and other angles (see Symbol list)
Cons
Definitely needs trial and error/tweaking to get the correct location of the arrow head relative to the POI.
There is limited control over the length of the arrow
Some latex commands aren't understood by the interpreter (boo).
If I remember correctly you need to calculate the position of the axes in relation to the figure.
it should go like:
%% example plot
clf
plot(rand(5,2)*5)
%% get info specific to the axes you plan to plot into
set(gcf,'Units','normalized')
set(gca,'Units','normalized')
ax = axis;
ap = get(gca,'Position')
%% annotation from 1,2 to 3,4
xo = [1,3];
yo = [2,4];
xp = (xo-ax(1))/(ax(2)-ax(1))*ap(3)+ap(1);
yp = (yo-ax(3))/(ax(4)-ax(3))*ap(4)+ap(2);
ah=annotation('arrow',xp,yp,'Color','r');
Note Fixed offset in original calculation - ap(3),ap(4) are width and height of gca, not corner positions
After creating the annotation object you should set the property Units to an absolute one. Example:
arrowObj = annotation('arrow', [0.1 0.1], [0.5 0.5]);
set(arrowObj, 'Units', 'centimeters');
set(arrowObj, 'Position', [1 1 3 5]);
One approach would be to define an arrowhead in the axis units:
Ax=[0 -0.003 0.003 0]; % (Ax,Ay) form an upward pointing arrowhead.
Ay=[0.01 0.0060 0.0060 0.01];
Ax=Ax-mean(Ax); % center it on zero
Ay=Ay-mean(Ay);
Then at desired arrowhead index in on a curve vv, compute
x1=vv(in,1); y1=vv(in,2);
x2=vv(in+1,1); y2=vv(in+1,2);
u=x2-x1;
v=y2-y1;
th=-pi/2+atan2(v,u);
R=[cos(th) -sin(th); sin(th) cos(th)]; % Rotation matrix for local slope of vv.
A=R*[Ax;Ay]; % Rotate the arrowhead.
patch(x1+A(1,:),y1+A(2,:),'r','LineWidth',0.01) % plot rotated arrowhead at (x1,y1).
plot(x1+A(1,:),y1+A(2,:),'r','LineWidth',0.01) % Kludge to make boundary red too (I'm sure there is a more elegant way).
Worked for me, for my particular circumstances.
You can use the 'arrow' component in the (well-documented) DaVinci Draw toolbox (full disclosure: I wrote/sell the toolbox, though arrows are free).
Example syntax and example output are below.
davinci( 'arrow', 'X', [0 10], 'Y', [0 2], <plus-lots-of-options> )
I want to create images like this from a double precision matrix using MATLAB.
Sample image:
http://twitpic.com/2xs943
You can create this sort of plot yourself pretty easily using the built-in functions imagesc and text and adjusting a number of parameters for the graphics objects. Here's an example:
mat = rand(5); % A 5-by-5 matrix of random values from 0 to 1
imagesc(mat); % Create a colored plot of the matrix values
colormap(flipud(gray)); % Change the colormap to gray (so higher values are
% black and lower values are white)
textStrings = num2str(mat(:), '%0.2f'); % Create strings from the matrix values
textStrings = strtrim(cellstr(textStrings)); % Remove any space padding
[x, y] = meshgrid(1:5); % Create x and y coordinates for the strings
hStrings = text(x(:), y(:), textStrings(:), ... % Plot the strings
'HorizontalAlignment', 'center');
midValue = mean(get(gca, 'CLim')); % Get the middle value of the color range
textColors = repmat(mat(:) > midValue, 1, 3); % Choose white or black for the
% text color of the strings so
% they can be easily seen over
% the background color
set(hStrings, {'Color'}, num2cell(textColors, 2)); % Change the text colors
set(gca, 'XTick', 1:5, ... % Change the axes tick marks
'XTickLabel', {'A', 'B', 'C', 'D', 'E'}, ... % and tick labels
'YTick', 1:5, ...
'YTickLabel', {'A', 'B', 'C', 'D', 'E'}, ...
'TickLength', [0 0]);
And here's the figure this generates:
If you run into trouble with the x-axis tick labels you choose being too wide and overlapping one another, here's how you can handle it:
Newer versions of MATLAB: Not sure which version this was added, but in newer versions axes objects now have the properties '{X|Y|Z}TickLabelRotation', which allow you to rotate the labels and fit them better.
Older versions of MATLAB: For older versions you can find some submissions on the MathWorks File Exchange that can rotate the tick label text, like XTICKLABEL_ROTATE from Brian Katz.
h = imagesc(magic(8))
impixelregion(h)
http://www.mathworks.com/help/toolbox/images/ref/impixelregion.html
Requires Image Processing Toolbox
If you only care about looking at zero/non-zero entries in your matrix (e.g. if it's sparse), use spy.
Else, use imagesc.
PS: I can't access your image
I expect you could persuade Matlab to draw that, if you look at the File Exchange you may find someone has already written the code. But it would be a lot easier, if you don't have the code, to use MS Excel.
EDIT: So I gave this some more thought and here's what I came up with. I've not mastered posting graphics to SO, so trust me, this will lead you towards a solution. But it would honestly be easier with Excel.
First define a matrix with your data values; I call the matrix G in the following. Then execute the commands:
image(G);
colormap(gray)
Now, I had to do some fiddling around, rescaling the data, to get a good graphic, but this should produce a gray-scale plot with numeric axes. Now, go to your figure window and open the plot tools.
Select the X axis and hit the Ticks button. All you have to do now is edit the labels to the texts that you want. Do the same for the Y axis. Write the numbers in the squares on the plot -- use the Text Box from the Annotations menu.
After a lot of fiddling about you'll have the graphic you want. At this point, I suggest that you choose the menu command File | Generate M-File and do just that. If you want to create such graphics programmatically in future just turn the generated M file into a proper function that does what you want.
But it's still a lot easier in Excel.