Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Change Spyder and Matplotlib figure size for saved plots only

I would like to view matplotlib plots inside Spyders IPython console in one size and save figures to a multipage PDF in a different size.

Currently I set the figure size as follows:

plt.rc('axes', grid=True)
plt.rc('figure', figsize=(12, 8))
plt.rc('legend', fancybox=True, framealpha=1)

Then I plot some figures and save them to a list for saving a PDF later on. This works just fine when used alone. The plots are approriately sized for viewing in Spyder IPython console.

At the end of my script I have a loop to go through each of the figures I want to save. In here I want to set the layout and figure size exactly for better printing on an A3 paper.

with PdfPages('multi.pdf') as pdf:
    for fig in figs:
        fig.tight_layout()
        fig.set_size_inches(420/25.4, 297/25.4)
        pdf.savefig(figure=fig)

The output PDF is just like I want it to be, but the problem is with the plots shown inside Spyder. Changing the figure size while saving also affects the plots viewed inside Spyder. And using the size of an A3 makes the plots way too big.

So the question is: How do I change the size of saved PDF figures without changing the size of figures shown inside Spyder?

like image 399
saikon Avatar asked Oct 17 '22 14:10

saikon


1 Answers

As suggested by @ImportanceOfBeingErnest, changing the figure size back after saving should work and may probably solved you problem.

But, depending on your specific problem, it is possible that you are going to face scaling issues since the size of the figures saved in the pdf is much bigger than the size of those displayed in the IPython console. If you scale everything to look great on the pdf, then it is possible that everything is going to look too big in IPython as shown in the example below:

enter image description here

If you don't need the plot to be interactive in IPython, a solution may be to generate your figures to look good for the pdf and display a scaled bitmap version of them in the IPython console as shown in the code below:

import matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages
import numpy as np
from IPython.display import Image, display
try:  # Python 2
    from cStringIO import StringIO as BytesIO
except ImportError:  # Python 3
    from io import BytesIO

# Generate a matplotlib figures that looks good on A3 format :

fig, ax = plt.subplots()
ax.plot(np.random.rand(150), np.random.rand(150), 'o', color='0.35', ms=25,
        alpha=0.85)

ax.set_ylabel('ylabel', fontsize=46, labelpad=25)
ax.set_xlabel('xlabel', fontsize=46, labelpad=25)
ax.tick_params(axis='both', which='major', labelsize=30, pad=15,
               direction='out', top=False, right=False, width=3, length=10)
for loc in ax.spines:
    ax.spines[loc].set_linewidth(3)

# Save figure to pdf in A3 format:

w, h = 420/25.4, 297/25.4
with PdfPages('multi.pdf') as pdf:
    fig.set_size_inches(w, h)
    fig.tight_layout()
    pdf.savefig(figure=fig)
    plt.close(fig)

# Display in Ipython a sclaled bitmap using a buffer to save the png :

buf = BytesIO()
fig.savefig(buf, format='png', dpi=90)
display(Image(data=buf.getvalue(), format='png', width=450, height=450*h/w,
              unconfined=True))

which shows in the IPython console as: enter image description here

like image 108
Jean-Sébastien Avatar answered Oct 20 '22 10:10

Jean-Sébastien