Save exact image output from imagesc in matlab - matlab

Hi , I want to save this image produced from imagesc(magic(3)), the exact rainbow representation, is it possible?
Thanks.
This question might look like a duplicate , but it is not . I looked at the solution to the similar question at this site , but it did not satisfy me .
I have looked into the Matlab help center and the close answer that I got was this one , at the bottom of http://goo.gl/p907wR

To save the figure as a file (don't matter how it was created), one should do:
saveas(figureHandle,'filename','format')
where figureHandle could be the gcf handle, which means: get current figure.
As pointed in the discussion, if someone doesn't want the ticks to be shown, the person can add:
set(gca,'XTick',[])
set(gca,'YTick',[])
where gca is the handle to the current axis, just as gcf. If you have more than one axis, don't forget to "handle the handles". They are returned to you when you create them, i.e.:
hFig = figure(pairValuedProperties); % Create and get the figure handle
hAxes1 = suplot(2,1,1,pairValuedProperties); % Create and get the upper axes handle
hAxes2 = suplot(2,1,2,pairValuedProperties); % Create and get the bottom axes handle
where the pair value are the figure or axes properties declared in the following syntax:
'PropertyName1',PropertyValue1,'PropertyName2',PropertyValue2,…
Here are the matlab documentation about the Figure and Axes Properties, and about the saveas method.
Example:
The image saved with the following code:
figure
imagesc(magic(3))
set(gca,'XTick',[]) % Remove the ticks in the x axis!
set(gca,'YTick',[]) % Remove the ticks in the y axis
set(gca,'Position',[0 0 1 1]) % Make the axes occupy the hole figure
saveas(gcf,'Figure','png')

You can use:
print -djpeg99 'foo.jpg'
This will save it as 'foo.jpg' as you need.

You can use the following code
imagesc(A);
%%saving the image
hgexport(gcf, 'figure1.jpg', hgexport('factorystyle'), 'Format', 'jpeg');
set(gcf,'PaperUnits','inches','PaperPosition',[0 0 4 4]);
print -djpeg filename.jpg -r10
Here A will be the matrix from which you will have an image. And the image will be saved as filename.jpg in the directory.

Related

Matlab doesn't save the new dimension of the plot

I'm trying to save a figure with a no-default dimension, but I always obtain the default size plot.
figure
for i=1:6
for j=1:4
subplot(6,4,j+(i-1)*4)
[...]
end
end
w=600; h=800;
set(gcf,'Position',[30 60 w h]);
set(gcf, 'PaperUnits', 'centimeters');
set(gcf,'PaperPositionMode','manual')
print('test','-depsc');
It is mainly a 6-by-4 subplot. I looked for a solution on internet, I found many comments about Position, PaperUnits, PaperPositionMode, but none has worked so far. The only solution that works is when I export as .fig.
What I actually realized, is that after the set(gcf,'Position',[30 60 w h]) the window dimension of the plot is correct, but the subplot are squeezed like when the dimension is the default. If I just insert a pause and manually resize the window (even by almost nothing), the subplots expand nicely within the larger window. But still, with the print command the result is not the desired one.
I tried also with saveas and I got the same result.
Ah, if I manually save the figure, it works perfectly, but, of course, I need to automatize the process!
Thanks for your help!
Although i can't reproduce this behaviour as MATLAB 2014b automatically handles axes resizing, i'll still post an answer, that may need some adjustments.
Basically, what you need to do is :
% Get a handle to your figure object
Myfig=gcf;
% Get all of your figure Children - Warning : if you have a global
% legend in your figure, it will belong to your figure Children and you
% ll have to ignore it
AllChildren=get(Myfig,'Children');
MyAxes=findobj(AllChildren,'type','axes');
% Now you have your axes objects, whose Position attributes should be in
% normalized units. What you need to do now is to store these positions
% before changing the size of your figure, to reapply them after
% resizing (the beauty of normalized positions).
Positions=zeros(size(MyAxes,1),4);
for ii=1:size(MyAxes,1)
Positions(ii,:)=get(MyAxes(ii),'Position');
end
% Resize your figure
w=600;
h=800;
set(gcf,'Position',[30 60 w h]);
% Reuse the positions you stored to resize your subplots
for ii=1:size(MyAxes,1)
set(MyAxes(ii),'Position',Positions(ii,:));
end
This should do the trick.

How to change font size of right axis of Pareto plot in Matlab

I am trying to bold the right side y axis for a Pareto plot in Matlab, but I can not get it to work. Does anyone have any suggestions? When I try to change the second dimension of ax, I get an error:
"Index exceeds matrix dimensions.
Error in pcaCluster (line 66)
set(ax(2),'Linewidth',2.0);"
figure()
ax=gca();
h1=pareto(ax,explained,X);
xlabel('Principal Component','fontweight','b','fontsize',20)
ylabel('Variance Explained (%)','fontweight','b','fontsize',20)
set(ax(1),'Linewidth',2.0);
set(ax(1),'fontsize',18,'fontweight','b');
%set(ax(2),'Linewidth',2.0);
%set(ax(2),'fontsize',18,'fontweight','b');
set(h1,'LineWidth',2)
Actually you need to add an output argument during the call to pareto and you will then get 2 handles (the line and the bar series) as well as 2 axes. You want to get the YTickLabel property of the 2nd axes obtained. So I suspect that in your call to pareto above you do not need to supply the ax argument.
Example:
[handlesPareto, axesPareto] = pareto(explained,X);
Now if you use this command:
RightYLabels = get(axesPareto(2),'YTickLabel')
you get the following (or something similar):
RightYLabels =
'0%'
'14%'
'29%'
'43%'
'58%'
'72%'
'87%'
'100%'
What you can do is actually to erase them altogether and replace them with text annotations, which you can customize as you like. See here for a nice demonstration.
Applied to your problem (with dummy values from the function docs), here is what you can do:
clear
clc
close all
y = [90,75,30,60,5,40,40,5];
figure
[hPareto, axesPareto] = pareto(y);
%// Get the poisition of YTicks and the YTickLabels of the right y-axis.
yticks = get(axesPareto(2),'YTick')
RightYLabels = cellstr(get(axesPareto(2),'YTickLabel'))
%// You need the xlim, i.e. the x limits of the axes. YTicklabels are displayed at the end of the axis.
xl = xlim;
%// Remove current YTickLabels to replace them.
set(axesPareto(2),'YTickLabel',[])
%// Add new labels, in bold font.
for k = 1:numel(RightYLabels)
BoldLabels(k) = text(xl(2)+.1,yticks(k),RightYLabels(k),'FontWeight','bold','FontSize',18);
end
xlabel('Principal Component','fontweight','b','fontsize',20)
ylabel('Variance Explained (%)','fontweight','b','fontsize',20)
which gives this:
You can of course customize everything you want like this.
That is because ax is a handle to the (first/left) axes object. It is a single value and with ax(1) you got lucky, its ax again, but ax(2) is simply not valid.
I suggest to read the docs about how to get the second axis. Another good idea always is to open the plot in the plot browser, click whatever object you want so it is selected and then get its handle by typing gco (get current object) in the command window. You can then use it with set(gco, ...).

Creating annotation boxes for subplots in a for-loop in Matlab

I have the following code in Matlab that runs through a for loop, reads data from a file and plots 9 different figures, that correspond to some particular "channels" in my data, so I decided to annotate them in the for loop.
clear
clc
for i=1:9
subplot(3,3,i);
hold on
x = [4 13]; % from your example
y = ([1 1]); % from your example
y2 = ([-0.4 -0.4]);
H=area(x,y,'LineStyle','none',...
'FaceColor',[1 0.949019610881805 0.866666674613953]);
H1=area(x,y2,'LineStyle','none',...
'FaceColor',[1 0.949019610881805 0.866666674613953]);
% Create textbox
annotation('textbox',...
[0.719849840255583 0.603626943005185 0.176316293929713 0.308290155440411],...
'String',{'FABLIGHT04','Channel',i},...
'FontWeight','bold',...
'FontSize',10,...
'FontName','Geneva',...
'FitBoxToText','off',...
'EdgeColor','none');
axis([0 24 -0.4 1])
set(gca,'XTick',[0:1:24])
set(gca,'YTick',[-0.4:0.2:1])
xlabel('Time (s)');
end
Initially it was giving me 9 different figures and the annotation thing worked fine. But I wanted to be able to tile them onto a subplot for easier comparison.
Since I switched over to using subplot, it does not annotate my figure properly. On opening the editing dock and generating the code, I find that matlab is plotting everything first and then just putting the annotation boxes in the same figure, one on top of the other. Looking at the code it generated, it apparently takes this part of the code:
annotation('textbox',...
[0.719849840255583 0.603626943005185 0.176316293929713 0.308290155440411],...
'String',{'FABLIGHT04','Channel',i},...
'FontWeight','bold',...
'FontSize',10,...
'FontName','Geneva',...
'FitBoxToText','off',...
'EdgeColor','none');
and does it as:
annotation(figure1,'textbox'...)
etc etc
So for all 9 text boxes, it puts them onto the same figure. I tried to do S=subplot(3,3,i) then annotation(S,'textbox') etc etc, I have also tried S(i)=subplot(3,3,i) and then annotation(S,'textbox') etc etc but nothing seems to work.
I have also tried to change the location of the box. I can't seem to figure out how to make it smaller either.
Does anyone know how to have annotation boxes in the right subplot in a for loop?
Thanks
I'm afraid annotation objects are properties of figures and NOT axes, as such its harder to customize the position of each annotation objects because no matter how many subplots you have, they are all part of the same figure and you need to specify their position relatively to the figure coordinate system.
Therefore, you can manually set the position of each text box in your code depending on the subplot it belongs to...
Simple example:
clear
clc
close all
figure('Units','normalized'); %// new figure window
for k = 1:2
str = sprintf('Subplot %d',k);
subplot(1,2,k)
plot(rand(1,10));
%// Customize position here
hAnnot(k) = annotation('textbox', [k*.4-.2 .6 .1 .1],...
'String', str,'FontSize',14);
end
Which looks like this:
Its not very elegant but I'm personally not aware of any other option if you do need to use annotations objects. A less cumbersome alternative would be to use a simple text objects, which are properties of axes and therefore much more friendly to position :)
Hope that helps!

Displaying whole image by clicking on a subplot

I croped some parts of images and displayed them in one figure with subplots. Number of subplots are not certain. I read images from a file then crop them. My aim is that when I click or double click on an subplot, I want to see whole image in new figure.
I want to give an example just to make clear my question. if I click on first subplot, I want to see whole cameraman image in new figure.
Is it possible? If it is possible, What is the way?
The example uses the ButtonDownFcn that can be added to most matlab plot commands.
Just copy both functions into one file and run the "interactivePlot" function.
The list_of_images contains all matrices that shall be plotted.
The number of matrices is flexible. However, you have to adjust the subplot command...
function interactivePlot
list_of_images = {rand(5), rand(10), rand(50), rand(100)}
for ii = 1:length(list_of_images)
subplot(2,2,ii)
imagesc(list_of_images{ii}, 'ButtonDownFcn', #newFigure1)
end
end
function newFigure1(h1, h2)
figure()
data = get(h1, 'CData');
imagesc(data)
end
I had same problem, change your function like below then it will be solved:
function newFigure1(h1, h2)
figure()
data = get(h1, 'CData');
colormap(gray);
imagesc(data)
end

How to specify the axis size when plotting figures in Matlab?

Suppose that I have 2 figures in MATLAB both of which plot data of size (512x512), however one figure is being plotted by an external program which is sets the axis parameters. The other is being plotted by me (using imagesc). Currently the figures, or rather, the axes are different sizes and my question is, how do I make them equal?.
The reason for my question, is that I would like to export them to pdf format for inclusion in a latex document, and I would like to have them be the same size without further processing.
Thanks in Advance, N
Edit: link to figures
figure 1: (big)
link to smaller figure (i.e. the one whose properties I would like to copy and apply to figure 1)
For this purpose use linkaxes():
% Load some data included with MATLAB
load clown
% Plot a histogram in the first subplot
figure
ax(1) = subplot(211);
hist(X(:),100)
% Create second subplot
ax(2) = subplot(212);
Now link the axes of the two subplots:
linkaxes(ax)
By plotting on the second subplot, the first one will adapt
imagesc(X)
First, you have the following:
Then:
Extending the example to images only:
load clown
figure
imagesc(X)
h(1) = gca;
I = imread('eight.tif');
figure
imagesc(I)
h(2) = gca;
Note that the configurations of the the first handle prevail:
linkaxes(h)
1.Get the handle of your figure and the axes, like this:
%perhaps the easiest way, if you have just this one figure:
myFigHandle=gcf;
myAxHandle=gca;
%if not possible, you have to search for the handles:
myFigHandle=findobj('PropertyName',PropertyValue,...)
%you have to know some property to identify it of course...
%same for the axes!
2.Set the properties, like this:
%set units to pixels (or whatever you prefer to make it easier to compare to the other plot)
set(myFigHandle, 'Units','pixels')
set(myAxHandle, 'Units','pixels')
%set the size:
set(myFigHandle,'Position',[x_0 y_0 width height]) %coordinates on screen!
%set the size of the axes:
set(myAxHandle,'Position',[x_0 y_0 width height]) %coordinates within the figure!
Ok, based on the answer of #Lucius Domitius Ahenoba here is what I came up with:
hgload('fig1.fig'); % figure whose axis properties I would like to copy
hgload('fig2.fig');
figHandles = get(0,'Children');
figHandles = sort(figHandles,1);
ax(1) = findobj(figHandles(1),'type','axes','-not','Tag','legend','-not','Tag','Colorbar');
ax(2) = findobj(figHandles(2),'type','axes','-not','Tag','legend','-not','Tag','Colorbar');
screen_pos1 = get(figHandles(1),'Position');
axis_pos1 = get(ax(1),'Position');
set(figHandles(2),'Position',screen_pos1);
set(ax(2),'Position',axis_pos1);
This is the 'before' result:
and this is the 'after' result:
Almost correct, except that the aspect ratios are still off. Does anybody know how to equalize everything related to the axes? (I realize that I'm not supposed to ask questions when posting answers, however adding the above as a comment was proving a little unwieldy!)