Problem or bug in xticklabel_rotate while drawing heatmap and rotating xtick labels in Matlab - matlab

I have been drawing heatmaps with labels in Matlab, mainly using the functions imagesc to draw the heatmap and xticklabel_rotate to rotate the xtick labels.
(please see here for xticklabel_rotate).
It usually works well. But today I met some problem which appeared to be caused by xticklabel_rotate (or maybe the Matlab text handle used by xticklabel_rotate?)
To illustrate the problem, in the following I print my code and the results generated from the code (basically, what it does is to randomly generate a normally distributed data matrix, draw a heatmap for the data using imagesc, draw its labels on top and right of the axis, and then rotate xticklabels):
function debug_xticklabelRotate(numX, numY, axisFontsize)
data = randn(numY, numX);
imagesc(data);
colormap(jet);
box on
set(gca, 'ticklength', [0,0]);
set(gca, 'xminortick', 'off', 'yminortick', 'off');
set(gca, 'XAxisLocation', 'top');
set(gca, 'YAxisLocation', 'right');
set(gca,'FontSize', axisFontsize);
axis image
set(gca, 'Xtick', 1 : numX);
htext = xticklabel_rotate([],90, [], 'fontsize', axisFontsize);
set(gca, 'YTick', 1 : numY);
end
Problem 1: I called the above function with parameters as
debug_xticklabelRotate(40, 100, .5);
the output image is shown below (to save space here, I cut the image and only show the top few rows):
Please notice that the bug is that, as the result of calling xticklabel_rotate, neither the right side of the figure box nor the yticklabels are drawn.
Problem 2: When I call the above function with parameters as
debug_xticklabelRotate(40, 200, .5); % only numY is changed from 100 to 200
the output image is shown below (again to save space here, I cut the image and only show the top few rows):
http://i55.tinypic.com/317grdd.png
Compared to the call with numY=100, in this figure both the data image and the labels are shown. However, please notice two problems here. First, the fontsize of xticklabel is not the same as that of yticklabel (axisFontsize). Second, the xtick labels are not aligned well with the columns (xticks): some labels are closer and some are further away.
Please note if I remove the function call of xticklable_rotate in my function debug_xticklabelRotate, all these mentioned problems are gone (except that now the xticklabel are not rotated).
I wish my problem is stated clear above. Any suggestion on solving the problem will be highly appreciated. Thank you very much.

As the author of xticklabel_rotate, I have tried to reproduce the errors mentioned with only small success. I have found an issue with the axis position being changed when y-labels are on the right, which I will look into. I do not get such marked misalignements as you have shown when I run the same examples, so I am not sure how to respond. Please verify that these issues exist when you PRINT the figure, and it is not a simple display issue.
The text boxes are created at the tick positions, in data units. They are middle aligned, there is not much more that can be done, but I am open to suggestions.
PS. I agree it would be nice if this function was inherent in MatLab. If it was, I wouldn't have had to work on this.

If you comment out the line:
set(gca, 'YAxisLocation', 'right')
then it should work as expected. It seems that the XTICKLABEL_ROTATE function does not support right y-labels. You should contact the original author and let him know of the possible bug...

Related

How to avoid marker clipping in Matlab while saving two axis figure to pdf?

I have some trouble while exporting a two axis figure with Matlab to pdf. The following example code works great while creating the figure in Matlab. But in the generated pdf-file all my red markers on the x-axis get cut off (see screenshot). Curiously this problem only occures, when I use a two axis plot
Here is a screenshot of my figure
fig = figure;
x = linspace(0,25);
y = sin(x/2);
marker = linspace(0,25,5);
yyaxis left
plot(x,y,'g');
hold on;
r = x.^2/2;
yyaxis right
plot(x,r,'b');
hold on;
plot(marker,0,'rx','Markersize', 8);
saveas(gcf,'myfigure.pdf');
Can anyone please help me out here?
I’ve come into this a handful of times, super frustrating. I’ve usually tried some of the below options, and eventually something works. Some things to try:
Print as a png, then convert to PDF with gimp or something of the like (where 300 represents 300 dpi):
print(handle, savefilename, ‘-dpng’, ‘-r300’)
Print as a vector image with the painters renderer, then convert to PDF with gimp:
print(handle, savefilename, ‘-depsc’, ‘-painters’)
Try changing the marker to a different shape, or size, or both (using for example: 'markersize', 3, 'marker', 's')
Good luck. Let us know what ends up fixing it!

Axis commands changes TightInset property to zero

I use some things from this question get-rid-of-the-white-space-around-matlab-figures-pdf-output to get rid of the white space when saving figure plots and images. This works fine, but my problem is when I use commands like "axis square" or "axis image". Ivt sets TightInset property of corresponding axes to 0 in "y" direction. I mean when I use this:
inset=get(a,'TightInset');
second and fourth numbers in "inset" are always zero, even if I set title and x-label. So in the end I don't see plot titles and x-labels.
Can I fix it somehow? So far I do it manually by adding some suitable number, but it is not convenient.
EDIT: Some more code for example. It displays two histograms.
h=figure;
subplot(121)
bar(bins,histogram1,'hist');
axis square
title('Historgram 1');
xlabel('Intensity');
ylabel('Pixel count');
set(gca,'xlim',[0 1])
subplot(122)
bar(bins,histogram_out,'hist');
axis square
title('Histogram 2');
set(gca,'xlim',[0 1])
xlabel('Intensity');
ylabel('Pixel count');
and if I call
a=get(h,'Children');
for i=1:length(a)
inset=get(a(i),'TightInset');
%...some stuff here
end
those y-related numbers in inset are zeros. If I comment axis square and do this, then inset are correct and it does what I need.
As far as I know when you use 'TightInset' you'll get only the graph or image, axis will be removed. I downloaded a function from mathworks file exchange 'saveTightfigure.m' to solve a similar problem. But I did not needed axes. If you need axes may be you can edit limits set inside the function. I mean you can give a little more space at left and bottom for keeping the axes.

matlab: plot area continues after data ends

I have a simple plot in Matlab but as you can see from the screenshot. There is a lot of white space on the right side of the graph after the end of the data series.
Any idea how to get rid of this white space and make the plot go right to the edge of the figure? Here is my code:
Plotx = plot(x);
hold on
PlotState = plot(Y);
set(Plotx,'Color','black','LineWidth',2.5);
set(PlotState,'Color','red','LineWidth',2.5);
set(gca, 'XTick',(1:3:62))
labels = time;
set(gca,'XTickLabel',labels(1:3:62))
grid on
This usually works for me:
axis tight;
xlim('auto');
You must select your figure, go back to the console and use those commands so they affect the last active figure.
EDIT: The above line should automatically make your graph axis very tight on your data. For more fine control, you may want to define the axis limits manually:
axis([xmin,xmax,ymin,ymax])
I found a solution. I manually adjust the limit of the x-axis, using:
set(gca,'XLim',[0 63])

Remove border around Matlab plot

Matlab is displaying a black border around a plot and I would like to remove it. I think i should be using something like:
set(Figure#,'PropertyName',PropertyValue);
But I'm not sure what PropertyName or PropertyValue should be used...
Edit:
I tried all of the suggestions including:
set(gca,'box','off');
set(gca,'xcolor','w','ycolor','w','xtick',[],'ytick',[]);
axis off;
The figure still has a black boarder and looks like this:
Edit 2:
This is a simplified package that reproduces the black box. Run the script called "runPlot". Here it is:
http://dl.dropbox.com/u/8058705/plotTest.zip
I can't figure out why the box is still visible. This might be due to the line in "plotTEC.m"
axis([-.65 .6 .25 1.32]) % hardwiring axis length since the coastline runs off of the plot
#Pursuit: If I use "plot browser" I get a recursive error....I am not familiar with the matlab plotting package but this seems strange. Does anyone else get this error? Again, thank you guys for your advise!
Does anyone have any other suggestions?
Thanks in advance!
You want to experiment with the properties of the axis. Some properties of interest.
xcolor %The color of the x-axis line and the x axis labels
ycolor %
box %'on', or 'off' indicating if one or both sides of a plot should have lines
xtick %Where to place the labels
ytick
For a completely bare plot, use:
figure
set(gca,'xcolor','w','ycolor','w','xtick',[],'ytick',[])
To set the figure background to white as well
set(gcf,'color','w')
Depending on your exact problem, you can try the 'box' property, to see how it affects your plots
set(gca,'box','on')
set(gca,'box','off')
If you want to turn off the actual plots lines but keep the plot labels then I am not aware of a simple solution. I think that I would need to remove the axes as described above, and then manually add labels using the text function.
Edit: As I just learned from this question, Plot Overlay MATLAB you can also try
axis off
axis on
Which I think is equivalent to
set(gca,'visible','off')
set(gca,'visible','on')
Edit 2:
If nothing else works, activate the "plot browser" in your figure. Use "view" --> "plot browser". From the plot browser panel, uncheck each object until you figure out which object is drawing the lines that you need to remove.
Then double click on the offending object to bring up the "property editor" panel, and mostly likely click "More properties" to view all possible properties of that object. From that view you can (hopefully) figure out what object is drawing the offending lines.
After you have figured out the object and property to edit, you can probably figure out where in the code that object is created, and set the property programmatically.
Try:
set(gca, 'Box', 'off');
Solution to remove 'gray' background in imagesc
I = imread('imgname.jpg');
[rows columns] = size(I);
posX = 100; posY = 100; %you can set any value for posX and posY - try to keep it on screen
f = figure (1);
imagesc(I);
set(gcf,'Position',[posX posY columns rows]);
set(gca,'units','pixels');
set(gca,'units','normalized','position',[0 0 1 1]);
axis off;
axis tight;
This should save the image with same size as that of the original, using imagesc.
Cheers!
set( gca , 'Visible' , 'off' );

how to make an image large enough to avoid tick label overlapping?

Assume that the data X has size 1000 *1000. X is displayed using the command:
imagesc(X);
and all the rows are labeld using:
set(gca, 'YTickLabel', somelabels);
Although the data X are properly polotted and the Ytick labels are also shown, the labels are highly overlapped because of the large number of rows. Is there any way to solve the problem? Any help will be highly appreciated.
Edit 1
I realize my question was not stated well to represent my problem. I am going to wrap up my understanding based on the answers and re-ask a question:
To show as many rows/labels in a Figure Window, the following helps:
set(gca,'FontSize',6),
or, alternate the distance (suggested by yuk),
or, set(gca,'YTick',1:10:1000,'YTickLabel',somelabels(1:10:1000));
The code
set(gca,'Units','pixels','Position',[20 20 10000 10000]);
will display a zoomed-in image by default. But if the zoomed-in image is too large to fit in the Figure Window, only part of the image will be displayed. However, neither zoom out nor the pan tool can reach to the rest part of that image.
The default behavior of the code
imagesc(X);
set(gca, 'ytick', 1:1000, 'yticklabe', ylabel);
displays the whole image fitting to the Figure Window with overlapping labels. Nevertheless, it does allow one to zoom into part of the image and to see the un-overlapped labels.
If I save the image into a pdf file:
imagesc(X);
set(gca, 'ytick', 1:1000, 'yticklabe', ylabel);
saveas(gcf, 'fig.pdf');
Then the saved pdf is only the image fit to the Figure Window with overlapping labels. However, unlike zoom in within Matlab figure window, zoom in within a pdf reader won't change the relative position/distance of labels. As a result, the zoomed-in image in pdf is still label-overlaped.
So my question is:
How to save the image into a pdf file or png such that it has a similar behavior as of point 3 above when opened in Adobe reader, rather than that of point 4?
You can also play with axes label font to make it smaller.
set(gca,'FontSize',6)
See also other axes properties to change font - FontName, FontWidth, FontUnits, etc.
Another solution: If your labels are short, you can alternate there distance from the axes, so the labels will not overlap. Check this example:
lbl = cellstr(reshape(sprintf('%3d',1:100),3,100)');
lbl(1:2:100) = strcat(lbl(1:2:100),{' '});
imagesc(rand(100))
set(gca,'ytick',1:100)
set(gca,'yticklabel',lbl)
Part of the resulted image:
UPDATE
To answer your updated question.
PDF document can contain only static images. Once you saved the figure to PDF (or any other graphic file), you cannot zoom in/out as with MATLAB figure tools.
You can zoom first on the MATLAB figure, then save PDF file. In this case the figure will be saved as is. But this way assumes user interactivity with the figure.
If you know your region of interest in advance, you can set axes limits with XLim/YLim properties, then save the figure.
Example:
imagesc(X);
set(gca, 'ytick', 1:1000, 'yticklabe', ylabel);
set(gca, 'XLim',[1 20], 'YLim', [20 40])
saveas(gcf, 'fig.pdf');
By the way, you can also save figure to file with PRINT function. More flexible. SAVEAS is just wrapper around it.
print('-dpdf','fig.pdf')
Another option is to rotate the tick labels which is discussed in this technical solution. You can find a number of easy-to-use implementations on the MATLAB File Exchange.