MATLAB: how to save a geoshow figure with faceAlph

2019-07-25 11:38发布

问题:

I am trying to save a figure in Matlab R2014a in which I want to plot data over an Image. This is the code:

[Singapore, R] = geotiffread(file);
s = size(Singapore);
matrix = rand(s(1),s(2));
geoshow(Singapore(:,:,1:3), R)
hold on
geoshow(matrix, R, 'DisplayType', 'texturemap','facealpha',.2);
xlim([103.605,104.04])
ylim([1.2,1.475])

This one is the plot that works perfectly:

While when I am printing the figure

print(gcf, '-dpng',     fullfile(FileF, 'test.png')) 

the image is completely white

回答1:

Many thanks for the image link! I have tried your code (adapted for the `Singapore.tif' file you provided and an appropriate output file) and it works as expected on my system (Matlab 2013b, Linux 64-bit). This is the output file:

So I'm sorry to say that there's nothing wrong with your code, and it's probably something to do with the 'png' driver on windows or your particular installation. Have you tried printing to a different driver? (e.g. jpg or pdf?). Does it actually work if you do this from the figure's graphical menu, i.e. File->Save As; or via File->Export Setup->Export with appropriate properties?


The only other thing I can think of which may be confusing your system is the attempt to print a uint8 rgb image (your Singapore image) and an overlayed double grayscale image. You can see if converting your Singapore image to double solves this by changing:

geoshow(Singapore(:,:,1:3), R)

to

geoshow(mat2gray(Singapore(:,:,1:3)), R)


Might also be worth trying to plot the data manually and see if printing that works, e.g.:

[Singapore, R] = geotiffread('Singapore.tif');
SingaporeXYImage = cat(3, flipud(Singapore(:,:,1)), ...
                          flipud(Singapore(:,:,2)), ...
                          flipud(Singapore(:,:,3)));
s = size(Singapore);
matrix3D = repmat( rand(s(1),s(2)), [1,1,3]);
imagesc(R.LongitudeLimits, R.LatitudeLimits, mat2gray(SingaporeXYImage));
hold on;
imagesc(R.LongitudeLimits, R.LatitudeLimits, matrix3D, 'alphadata', .2);
hold off;
axis xy equal tight;
xlim([103.605,104.04])
ylim([1.2,1.475])
print(gcf, '-dpng', 'test.png');


As a bonus, here's how you might perform the same thing in Octave, in case you're interested (I find printed plots from Octave look much nicer, especially in terms of fonts!):

pkg load mapping;
pkg load image;
[SingaporeStruct, R] = rasterread('Singapore.tif');
SingaporeImage = cat(3, SingaporeStruct(1:3).data); % note this is a matrix of 
                                                    % "doubles" in range [0,255]
SingaporeImage = mat2gray(SingaporeImage); % Convert to appropriate [0,1] range 
                                           % for "doubles" rgb images!
s = size (SingaporeImage);
matrix3D = repmat (rand (s(1), s(2)), [1, 1, 3]);
imagesc (R.bbox(:,1), R.bbox(:,2), ...
         SingaporeImage .* 0.8 + matrix3D .* 0.2); % manually create
                                                   % transparency effect
axis xy equal tight
xlim([103.605,104.04])
ylim([1.2,1.475])
print (gcf, '-dpng', 'test.png');


Also, no disrespect to my colleague and the effort he / she put into his / her answer, but I will note that the other answer you received is essentially completely wrong and you should retract your marked accepted regardless of his / her claim and warnings about how rude it is to retract a marked answer. mapshow is specifically used for images using a MapCellsReference format: the boston.tif image is one such image. Your image however uses a GeographicCellsReference format. mapshow is used for the former, geoshow is used for the latter; geoshow would have failed for boston.tif, in the same way mapshow fails for Singapore.tif. It should have been obvious your image is a "Geo" variant because your line geoshow(Singapore(:,:,1:3), R) worked without throwing an error. Therefore the suggestion to use mapshow is not the correct answer to your question, and is misleading. Not to mention it is completely irrelevant to your actual question about why the print command does not produce the expected result from its figure handle, which should in theory have nothing to do with how the figure was produced in the first place. I would have no qualms about retracting your "accepted" mark from it. Not least because this site functions as a reference for many other viewers; it does not make sense to direct users to the wrong answer just because you got bullied into accepting it.



回答2:

As suggested by mathworks, using mapshow should solve your problem. The following works for me:

[boston, R] = geotiffread('boston.tif');
figure
mapshow(boston, R);
axis image off
S = size(boston);
matrix=rand(S(1),S(2));
hold on
mapshow(matrix, R,'DisplayType','texturemap','facealpha',0.2);
print(gcf, '-dpng','test.png') ;