Make figure without white border

294 次查看(过去 30 天)
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
移动: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