MATLAB Answers

Exporting a figure including multiple subplots into high resolution PDF or SVG

97 views (last 30 days)
Rico Heilemann
Rico Heilemann on 14 Sep 2020
Edited: Rico Heilemann on 16 Sep 2020
Dear Mathworks Community,
I have been struggeling with a very frustrating MATLAB issue for some time now that a lot of MATLAB users seem to struggle with. And after spending hours and hours of searching the web, the Mathworks forum and several of its articles, I now wanted to try my luck opening a question about it myself.
I'm currently doing research for my Master thesis where I use MATLAB to analyze numerically calculated data in a Live script I wrote. Within this script I'm also plotting the calculated data sets for later use in my thesis. Mostly I compare different components (x,y,z) of fields and other time dependent signals for which I use figures consisting of subplots (one for each component). Of course, I would really like to produce high resolution images of these plots exporting them as PDF or vector graphics. And here lies the problem!
It seems that exporting plots (figures) in MATLAB just as they appear in the figure window on screen into high resolution output (JPG, PNG, PDF, SVG) is quite a challenge when the figures consists of several subplots. I know that I can easily export single subplots of a figure into high resolution PDF or SVG by just using the toolbar above each subplot in the figure window (described here). But when I want to export the whole figure showing all subplots into one single file, different problems occur:
  1. The output file (in my case PDF) reproduces the plots in poor quality, even when changing the resolution to high values.
  2. Both functions do not cut the white spaces to the borders around the plots.
I provied an example in the attached PDF. Here is what I already tried so far:
  • using the functions print, saveas or exportgraphics
  • using the print preview option in the GUI of the figure window to adapt several settings for each figure so it fits the look of the plot like: landscape orientation, fill page, etc.
  • creating a new toolbar in the figure window as described in this post following the described option Create Toolbar for Tiled Chart Layout which does not seem to work for subplots
  • the Mathworks add-on export_fig which seems to be very promising for cutting blank borders around the plot and producing SVG
Especially the last option made me curious when I found it searching for other options as it seemed to be a pretty awesome and promising tool for the job. So I downloaded export_fig via the Mathworks add-on manager and added it to the path of know functions (as described here) and included it in my code as follows:
LINEWIDTH = 3;
FONTSIZE = 16;
% Dipole{k,nC} is a cell array including some data to plot
figure('Name', strcat('Dipole Moment: chiral vs. achiral'), 'NumberTitle', 'off');
subplot(3,1,1) % x-component of Dipole Moment for chiral & achiral fields
hold on
plot(t, Dipole{1,1}, 'color', [0.65 0.00 0.00], 'linewidth', LINEWIDTH)
plot(t, Dipole{1,2}, '--', 'color', [0.00 0.65 0.00], 'linewidth', LINEWIDTH)
plot(t, Dipole{1,3}, ':', 'color', [0.00 0.00 0.65], 'linewidth', LINEWIDTH)
xlim([0 t(N_Time)])
title('Dipole Moment: chiral vs. achiral')
legend('$achiralXY$', '$achiralXZ$', '$chiral$', 'Interpreter', 'latex', 'Location', 'northeast', 'FontSize', 20)
ylabel('$P_{x}(t)$ $[a.u.]$', 'Interpreter', 'latex')
set(gca,'FontSize', FONTSIZE)
subplot(3,1,2) % y-component of Dipole Moment for chiral & achiral fields
hold on
plot(t, Dipole{2,3}, 'color', [0.65 0.00 0.00], 'linewidth', LINEWIDTH)
plot(t, Dipole{2,1} + Dipole_OCT{2,2}, '--', 'color', [0.00 0.65 0.65], 'linewidth', LINEWIDTH)
xlim([0 t(N_Time)])
legend('$chiral$', '$achiral: xy + xz$', 'Interpreter', 'latex', 'Location', 'northeast', 'FontSize', 20)
ylabel('$P_{y}(t)$ $[a.u.]$', 'Interpreter', 'latex')
set(gca,'FontSize', FONTSIZE)
subplot(3,1,3) % z-component of Dipole Moment for chiral & achiral fields
hold on
plot(t, Dipole{3,3}, 'color', [0.65 0.00 0.00], 'linewidth', LINEWIDTH)
plot(t, Dipole{3,1} + Dipole{3,2}, '--', 'color', [0.00 0.65 0.65], 'linewidth', LINEWIDTH)
xlim([0 t(N_Time)])
legend('$chiral$', '$achiral: xy + xz$', 'Interpreter', 'latex', 'Location', 'northeast', 'FontSize', 20)
xlabel('Time t $[\hbar/E_{h}]$', 'Interpreter', 'latex')
ylabel('$P_{z}(t)$ $[a.u.]$', 'Interpreter', 'latex')
set(gca,'FontSize', FONTSIZE)
export_fig test_plot -pdf -transparent
But after running the script as soon as it gets to the line where I use the export_fig function it just keeps running and running without finishing or producing a file with the plots. For testing I let it run over half an our but it just kept running... I followed the documentation of export_fig and its options and implemented it just like other users did, but with their codes producing output files. I also checked that ghostscript is installed correctly.
I could now list several more websites and mathworks forum post I worked through all dealing with similiar but never the same issue as it seems. I really worked through a lot of them...
So, is there something I missed or did wrong using export_fig? Are there other options I could try?
I would really appreciate any help that gets me any further with that issue since it's pretty frustrating.
Thanks in advance!
Rico

  0 Comments

Sign in to comment.

Answers (2)

Deva Nayak
Deva Nayak on 16 Sep 2020
Hi Rico,
As per my understanding, You need subplots and other stuff in a high-resolution pdf or svg probably vector images. But options like saveas and exportgraphics leaves white border.
I altered the code you provided. And looks like it worked for me. I can generate a high resolution image with two options
  1. Saveas
  2. Exportgraphics
The saveas option leaves a white border around the figure. And exportgraphics doesn't leave a white border.
Also, it preserves all the subplot information intact as you wanted.
LINEWIDTH = 3;
FONTSIZE = 10;
t = 0:0.02:10;
N_Time = length(t);
Dipole = {sin(t),cos(t),-sin(t);-cos(t),sin(t),cos(t);sin(t),cos(t),-sin(t)};
% Dipole{k,nC} is a cell array including some data to plot
figure('Name', strcat('Dipole Moment: chiral vs. achiral'), 'NumberTitle', 'off');
subplot(3,1,1) % x-component of Dipole Moment for chiral & achiral fields
hold on
plot(t, Dipole{1,1}, 'color', [0.65 0.00 0.00], 'linewidth', LINEWIDTH)
plot(t, Dipole{1,2}, '--', 'color', [0.00 0.65 0.00], 'linewidth', LINEWIDTH)
plot(t, Dipole{1,3}, ':', 'color', [0.00 0.00 0.65], 'linewidth', LINEWIDTH)
xlim([0 t(N_Time)])
title('Dipole Moment: chiral vs. achiral')
legend('$achiralXY$', '$achiralXZ$', '$chiral$', 'Interpreter', 'latex', 'Location', 'northeast', 'FontSize', FONTSIZE)
ylabel('$P_{x}(t)$ $[a.u.]$', 'Interpreter', 'latex')
set(gca,'FontSize', FONTSIZE)
subplot(3,1,2) % y-component of Dipole Moment for chiral & achiral fields
hold on
plot(t, Dipole{2,3}, 'color', [0.65 0.00 0.00], 'linewidth', LINEWIDTH)
plot(t, Dipole{2,1} + Dipole{2,2}, '--', 'color', [0.00 0.65 0.65], 'linewidth', LINEWIDTH)
xlim([0 t(N_Time)])
legend('$chiral$', '$achiral: xy + xz$', 'Interpreter', 'latex', 'Location', 'northeast', 'FontSize', FONTSIZE)
ylabel('$P_{y}(t)$ $[a.u.]$', 'Interpreter', 'latex')
set(gca,'FontSize', FONTSIZE)
subplot(3,1,3) % z-component of Dipole Moment for chiral & achiral fields
hold on
plot(t, Dipole{3,3}, 'color', [0.65 0.00 0.00], 'linewidth', LINEWIDTH)
plot(t, Dipole{3,1} + Dipole{3,2}, '--', 'color', [0.00 0.65 0.65], 'linewidth', LINEWIDTH)
xlim([0 t(N_Time)])
legend('$chiral$', '$achiral: xy + xz$', 'Interpreter', 'latex', 'Location', 'northeast', 'FontSize', FONTSIZE)
xlabel('Time t $[\hbar/E_{h}]$', 'Interpreter', 'latex')
ylabel('$P_{z}(t)$ $[a.u.]$', 'Interpreter', 'latex')
set(gca,'FontSize', FONTSIZE)
saveas(gcf,'subplots','pdf') %leaves white border
exportgraphics(gcf,'subplots1.pdf','ContentType','vector') %does not leaves white border
you can also take a look on the following resources
  1. Saveas
  2. Exportgraphics

  1 Comment

Rico Heilemann
Rico Heilemann on 16 Sep 2020
Hello Deva Nayak,
first of all thank you very much for trying to help me with this very frustrating issue. As I pointed out in my post I already tried using the functions saveas and exportgraphics, but both not giving me the results I am seeking. Maybe I should explain further why that is.
What I want as a result to be exported into the output file (PDF, SVG, etc.) is the whole figure (including the subplots) as it appears in the figure window (fullscreen mode) in terms of resolution and dimension shown in the attached file plot_fullscreen.pdf that I produced with the workaround explained below.
But what I get using both functions is the figure in terms of dimension as shown in the figure preview in my live script which you can see in this screenshot:
The plot resulting from use of exportgraphics can be seen in the attached file plot_thumbnail.pdf. I want to use these and other plots created with MATLAB for my thesis, so it should have high quality and show a detailed plot, not shrinked down in size to a square format as done by these functions.
So what I always do as a workaround to get my desired output is:
  1. Open figure window in fullscreen mode
  2. Go to File -> Print Preview...
  3. In tab Layout I do changes to Left, Top, Width, Height in option Placement as well as to Format, Width, Height in Paper options to anyhow get rid of white margins between the borders of the figure window and the actual subplots.
  4. Then (and this is now different from how I did it before) under tab Advanced I change the option Renderer to painters which solves the resolution issue. I didn't recognize this option before as it was set to auto which obviously always chose OpenGL by default.
  5. After all of that I close the Print Preview window and go to File -> Save As and export into the desired format PDF.
This works just fine but has to be done manually for every single figure I produce which takes a lot of time and is not a nice workaround. In the attached file plot_fullscreen.pdf you can see a result with this workaround.
So basically I need a way or a function that does exactly produce this kind of output.

Sign in to comment.


Rico Heilemann
Rico Heilemann on 16 Sep 2020
Edited: Rico Heilemann on 16 Sep 2020
Tiled Layout instead of Subplot but...
So after hours and hours of trying different options I came across the function tiledlayout which is available with MATLAB R2019b. It works similar to the subplot function but provides several options to change the white spaces between different tiles (plots) and the margin between the tiled layout and the figure window.
BUT... for any reason unlike subplot using tiledlayout it is not possible anymore to manually move produced legends around inside the different plots and I also didn't find a way to change that. But since my plotted data takes a lot of space inside the plots, the predefined legend positions (south, west, ...., etc.) don't work for me and I need to move them manually. The option best doesn't really do what it is explained to do, but just puts the legend inside my plotted data.
I don't know if there is a way to maybe change that behaviour of tiledlayout.

  0 Comments

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!

Translated by