Make figure without white border

300 ビュー (過去 30 日間)
Anders Brakestad
Anders Brakestad 2017 年 2 月 8 日
コメント済み: Maureen 2024 年 10 月 1 日
I have a piece of code that plots a surface, and I feel it is ready for being included into the report. The only thing is that the figure has a quite large white border which substantially increases the size of it. I would like to have the unnecessary white space reduced to a minimum.
I did try
set(gca,'LooseInset',get(gca,'TightInset'))
But this cuts off my z-axis label. Is there an easy way to achieve this? With LaTeX, we can simply use the standalone documentclass with PGFplots/tikz, but I don't think there's a simple keyword or option to do this with matlab. I'm using R2016b.

採用された回答

Chad Greene
Chad Greene 2017 年 2 月 8 日
export_fig removes the border by default.
  1 件のコメント
Sim
Sim 2022 年 1 月 5 日
編集済み: Sim 2022 年 1 月 5 日
Hi, I have used both the following functions to save a figure as a PDF file:
print (figure_name, '-dpdf','-opengl','-r600', [path, plot_name{:}] )
export_fig([path, plot_name{:}], '-pdf', '-opengl','-r600');
Result:
Even though the matlab built-in function print does not crop the white margins in a PDF figure (right?), it mantains a very good resolution/quality of the saved PDF figure. The file exchange export_fig crops instead the white space in a figure automatically, but it reduces a bit the quality of the saved PDF figure, resulting in slightly blurry contours (after zooming in).
This is just my experience, but if you know a reason for the loss of quality in a PDF figure by using export_fig, please let me know!
All the best

サインインしてコメントする。

その他の回答 (6 件)

atilla Maia
atilla Maia 2018 年 12 月 19 日
編集済み: KSSV 2024 年 2 月 1 日
I have tried many suggestions. This one works for me:
f = figure;
F= getframe(f);
img = F.cdata;
imwrite(img, filename) ;

Gyaneshwar dubacharla
Gyaneshwar dubacharla 2020 年 8 月 9 日
移動済み: Image Analyst 2023 年 8 月 20 日
Use this command from MATLAB - exportgraphics(gca,fname.emf,'BackgroundColor','none')
  1 件のコメント
Maureen
Maureen 2024 年 10 月 1 日
Oddly, exportgraphics works for many situations, but not always.

サインインしてコメントする。


Hajra Afzal
Hajra Afzal 2021 年 4 月 26 日
移動済み: Image Analyst 2023 年 8 月 20 日
@Gyaneshwar dubacharla exportgraphics(gca,fname.emf,'BackgroundColor','none') worked for me. Thankyou for sharing. I faced quite a hassle before implementing this command.

Jose Marques
Jose Marques 2017 年 9 月 8 日
You can "imwrite" too.

Thomas
Thomas 2023 年 8 月 20 日
Maybe this way?
fig_1 = figure(1);
clf();
n = 512;
m = 2 * n + 1;
j = ones(1, m);
i = (-n : n) / n;
i = i .* i;
ii = i' * j;
img = real(sqrt(1 - (ii' + ii)));
imshow(img);
hold on;
lw = .01 * m;
x = 4 * lw + (m - 8 * lw) * [.25 .25 .50 .75 .25 .75 .25 .75 .75];
y = 4 * lw + (m - 8 * lw) * [1.0 .50 .00 .50 .50 1.0 1.0 .50 1.0];
plot(x, y, LineWidth = lw, Color=[1 0 0]);
title("ball with santa's house");
hold off;
new_bordersize = 2; % must not be greater than the original border
img = remove_border(frame2im(getframe(fig_1)), new_bordersize);
imwrite(img, "ball_with_santas_house.tiff");
%%REMOVE_BORDER
function img = remove_border(img, new_bordersize)
%REMOVE_BORDER
% default value for new_bordersize is zero.
if ~exist("new_bordersize", "var")
new_bordersize = 0;
end
% get the border color
col = img(1, 1);
% get the image size
[h, w, ~] = size(img);
% search from left for the first column that not contains only the border-color
x0 = 0;
while x0 < w
x0 = x0 + 1;
if ~all(img(:, x0) == col)
break;
end
end
% search from rigth for the first column that not contains only the border-color
x1 = w + 1;
while 1 < x1
x1 = x1 - 1;
if ~all(img(:, x1) == col)
break;
end
end
% search from bottom for the first row that not contains only the border-color
y0 = 0;
while y0 < h
y0 = y0 + 1;
if ~all(img(y0, :) == col)
break;
end
end
% search from top for the first row that not contains only the border-color
y1 = h + 1;
while 1 < y1
y1 = y1 - 1;
if ~all(img(y1, :) == col)
break;
end
end
% calculate the sub image size to cut out
x0 = max(0, x0 - new_bordersize);
x1 = min(w, x1 + new_bordersize);
y0 = max(0, y0 - new_bordersize - 7);
y1 = min(h, y1 + new_bordersize);
% return the new image
img = img(y0 : y1, x0 : x1, :);
end
  1 件のコメント
DGM
DGM 2023 年 8 月 20 日
Trimming after the fact is not ideal, but it is often the only option left.
That said, the whole trimming process can be simplified. In this example, I use an image with a non-white background for sake of demonstration. While I'm reading the image from a file for simplicity, the same applies to an image as captured using getframe()/frame2im().
The original padding is removed and new padding added. In this case, the result demonstrates that the new padding is not constrained by the original amount of padding.
% inputs
inpict = imread('stuffthings.png');
padwidth = [50 0]; % [y x]
% create a mask of non-BG pixels
mask = ~all(inpict == inpict(1,1,:),3);
% find ROI geometry
mkr = any(mask,2);
mkc = any(mask,1);
r1 = find(mkr,1,'first');
r2 = find(mkr,1,'last');
c1 = find(mkc,1,'first');
c2 = find(mkc,1,'last');
% crop original image to extents
roipict = inpict(r1:r2,c1:c2,:,:);
% re-pad as specified
% doing this with IPT or base tools is clumsy, but it's fine
% doing the padding this way instead of shifting subscripts
% allows the output padding to be unconstrained by the original image size
szo = size(roipict,1:2)+2*padwidth;
outpict = zeros(szo,class(roipict));
for c = 1:size(inpict,3)
outpict(:,:,c) = padarray(roipict(:,:,c),padwidth,inpict(1,1,c),'both');
end
imshow(inpict,'border','tight')
figure
imshow(outpict,'border','tight')
Of course, there are more convenient ways. If I were doing it with MIMT, this simplifies to:
% inputs
inpict = imread('stuffthings.png');
padwidth = [100 10]; % [y x]
% create a mask of non-BG pixels
bg = inpict(1,1,:);
mask = ~all(inpict == bg,3);
% crop original image to extents
[~,rr,cc] = crop2box(mask);
outpict = inpict(rr,cc,:,:);
% re-pad as specified
outpict = addborder(outpict,padwidth,ctflop(bg));
imshow(outpict,'border','tight')
... or more simply:
% inputs
inpict = imread('stuffthings.png');
padwidth = [100 10]; % [y x]
% crop uniform border vectors
outpict = cropborder(inpict,NaN(1,4));
% re-pad as specified
bg = inpict(1,1,:);
outpict = addborder(outpict,padwidth,ctflop(bg));
imshow(outpict,'border','tight')

サインインしてコメントする。


Chris
Chris 2024 年 8 月 16 日
編集済み: Chris 2024 年 8 月 16 日
This is by no means the most elegant solution, but in my case I was saving figures as *.png files and then cropping them down once I'd inserted them onto a PowerPoint slide. After about 60 of these I found this thread. Since I'm the only one doing this work and I'm always working on the same monitor, I developed the following workflow:
  1. create an image that is the size of my monitor,
  2. save the figure as a PNG file,
  3. load it back in using imread,
  4. crop the image matrix down to the height and width I want using the associated row/column ranges,
  5. save it out again overwriting the original PNG using imwrite.
The code looks like this:
test = rand(100,1);
f = figure('units','normalized');
plot(test,'LineWidth',3)
legend('Random Noise')
set(gca,'LineWidth',2,'YLim',[-0.1, 1.1],'FontSize',64)
set(f,'Position',[0,0.0333,1.0000,0.9132])
saveas(f,'test','png')
im = imread('test.png');
imwrite(im(100:2025,461:5000,:),'test.png')
The difference in the saved images goes from this:
->||<-
To this:
->||<-
I've been working on a large monitor and haven't noticed any negative impact on the image quality.

タグ

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by