How to "zoom out" a plot in matplotlib, keeping all the size ratios the same, but reducing the size in inches?

12,640

Solution 1

Usually, it would be enough to set a different font-size for the complete script.

import matplotlib.pyplot as plt
plt.rcParams["font.size"] =7

Complete example:

import matplotlib.pyplot as plt
plt.rcParams["font.size"] =7


fig, ax = plt.subplots(figsize=[2.,3.], dpi=100)
ax.plot([2,4,1], label="label")
ax.set_xlabel("xlabel")
ax.set_title("title")
ax.text( 0.5,1.4,"text",)
ax.legend()

plt.tight_layout()
plt.savefig("figure.pdf", dpi="figure")
plt.savefig("figure.png", dpi="figure")
plt.show()

enter image description here enter image description here

Solution 2

You might want to ask the journal if using width=\columnwidth, e.g.,

\includegraphics[width=\columnwidth]{example-image}

is acceptable. Although this is a rescaling, it adapts to the current column width so this might be sufficiently journal-friendly.

And if not, perhaps ask them (or other authors who have published in that journal) for a sample of the LaTeX a typical paper uses to include a graphic, or advice on how graphics are to be generated.

It might also be the case that the journal simply doesn't want raster images to be scaled up since that can make images look blurry. Scaling down may not be a problem for raster images, and scaling non-raster images might not be a problem at all.


If all else fails, you could use LaTeX itself to rescale the pdf generated by matplotlib. Below, the make_plot function (taken from the matplotlib example gallery) generates /tmp/tex_demo.pdf. The rescale_pdf function rescales tex_demo.pdf and writes the result to /tmp/tex_demo-scaled.pdf. The rescale_pdf function calls pdflatex via the subprocess module.

Adjust the paperheight and paperwidth parameters in the LaTeX template

paperheight=2.25in, 
paperwidth=3in, 

to control the size of the rescaled pdf figure.


import subprocess
import os
import textwrap
import numpy as np
import matplotlib.pyplot as plt

def make_plot(filename):
    """https://matplotlib.org/users/usetex.html"""
    # Example data
    t = np.arange(0.0, 1.0 + 0.01, 0.01)
    s = np.cos(4 * np.pi * t) + 2

    # fig, ax = plt.subplots(figsize=(2, 3))

    plt.rc('text', usetex=True)
    plt.rc('font', family='serif')
    fig, ax = plt.subplots()
    ax.plot(t, s)

    ax.set_xlabel(r'\textbf{time} (s)')
    ax.set_ylabel(r'\textit{voltage} (mV)',fontsize=16)
    ax.set_title(r"\TeX\ is Number "
              r"$\displaystyle\sum_{n=1}^\infty\frac{-e^{i\pi}}{2^n}$!",
              fontsize=16, color='gray')
    # Make room for the ridiculously large title.
    plt.subplots_adjust(top=0.8)

    plt.savefig(filename)

def rescale_pdf(filename):
    stub, ext = os.path.splitext(filename)
    print('begin rescale')
    template = textwrap.dedent(r'''
        \documentclass{article}

        %% https://tex.stackexchange.com/a/46178/3919
        \usepackage[
                paperheight=2.25in, 
                paperwidth=3in, 
                bindingoffset=0in, 
                left=0in,
                right=0in,
                top=0in,
                bottom=0in, 
                footskip=0in]{geometry}
        \usepackage{graphicx}

        \begin{document}
        \pagenumbering{gobble}
        \begin{figure}
        %% https://tex.stackexchange.com/questions/63221/how-to-deal-with-pdf-figures
        \includegraphics[width=\linewidth]{%s}
        \end{figure}

        \end{document}''' % (stub,))

    tex_filename = 'result.tex'
    with open(tex_filename, 'w') as f:
        f.write(template)

    proc = subprocess.Popen(['pdflatex', '-interaction', 'batchmode', tex_filename])
    output, err = proc.communicate()

filename = '/tmp/tex_demo.pdf'
dirname = os.path.dirname(filename)
if dirname: 
    os.chdir(dirname)
make_plot(filename)
rescale_pdf(filename)
Share:
12,640
Marses
Author by

Marses

Updated on June 13, 2022

Comments

  • Marses
    Marses almost 2 years

    I'm using matplotlib for plots, and one problem I'm having is that the standard plot sizes appear to have ridiculously huge sizes (in inches). The default dpi value for MPL seems to be set at 100dpi, but plots get produced at sizes of several like 6+ inches. The problem is that if I save this as a pdf, the immediate size is much too large to put on a scientific paper (I'd rather have it be "column-sized" which would be like an inch or two of width).

    However, if you directly specify the figsize like

    fig, ax = plt.subplots(figsize=[2.,3.])
    

    the font sizes and marker sizes stay the same size in inches, leading to relatively huge figure items and ugly graphics. What I would prefer is the same ratios that come up by default, but reduced to a different inch size.

    There's two ways around this that I know of. Either save the figure in the standard size (which is coming out to about 8 by 6 inches or something), and then scale it when inserting it into LaTeX. Or manually go through all the figure elements, and change the font sizes, marker sizes, and figure sizes to make it perfect.

    In some cases you can't do the former, and the latter is extremely tedious. I'd have to figure out for each figure element what the proper size is to keep it the same ratio as in the default.

    So if there another quick option for changing figure size while also scaling everything from what it would be by default?