20

I'm working on several pieces of coursework involving lots of plots generated with matplotlib in python scripts.

Currently I'm doing this with an iterative process where I set a plot size in the latex code, generate the correctly sized plot in my python script and run latex to generate the document. This is then repeated when it inevitably doesn't quite look how I want it.

This is quite time consuming so I've been looking for some way of speeding things up. What would be ideal would be to run my python script once to produce the graph and then import it in latex using some command to scale it appropriately while keeping the font settings consistent with the rest of the document. I'd then play with the settings within latex without needing to modify and re-run the python script each time.

The first and second answers to this question seem to be what I'm looking for, but unfortunately they are for Matlab.

I've tried using the same procedure with the matplotlib equivalent commands but have had the following problems:

1. Generating pgf with matplotlib, scaling with tikzscale:

I generate a pgf plot from matplotlib called test.pgf and use the following latex code:

\documentclass{article}
\usepackage{pgf}
\usepackage{tikz}
\usepackage{tikzscale}
\usepackage{pgfplots}

\begin{document}
    \begin{figure}
        \centering
        \includegraphics[width=0.5\textwidth]{test.pgf}
        \caption{Some figure}
        \label{fig:figure}
    \end{figure}
\end{document}

Fails with the following error:

! Package tikzscale Error: Requested to scale unscalable graphic.

2. Generating .svg with matplotlib, converting to .pdf, scaling with \includegraphics:

As before except just include test.pdf.

Fails as text in plots is not scaled correctly...

I'd of course be happy to look into some other method too if you can suggest anything!

3

2 Answers 2

23

The matplotlib PGF backend saves as raw PGF. What you probably want instead is pgfplots, which you can get using tikzplotlib, assuming your plots aren't too complex and all the features are supported.

Sample Python script for creating figure:

from pylab import *
from tikzplotlib import save as tikz_save
x = linspace(0, 10, 101)
plot(x, sin(x))
xlabel('$x$-axis')
ylabel('$y$-axis')
tikz_save('fig.tikz',
           figureheight = '\\figureheight',
           figurewidth = '\\figurewidth')

Sample accompanying LaTeX document that brings in the plots with two different dimensions (you could use \input; I'm using \InputIfFileExists so that missing figures won't kill compilation):

\documentclass{article}

\usepackage{pgfplots}

\newlength\figureheight
\newlength\figurewidth

\begin{document}

\setlength\figureheight{2in}
\setlength\figurewidth{3in}
\InputIfFileExists{fig.tikz}{}{\textbf{!! Missing graphics !!}}

\setlength\figureheight{3in}
\setlength\figurewidth{4in}
\InputIfFileExists{fig.tikz}{}{\textbf{!! Missing graphics !!}}

\end{document}

Output:

enter image description here

Depending on what you are doing, you could also consider using my PythonTeX package to put everything in the LaTeX source:

\documentclass{article}

\usepackage{pgfplots}
\usepackage[stdout=false]{pythontex}
% matplotlib2tikz prints messages to stdout, so don't include
% stdout automatically; could also redirect stdout to avoid this
\setpythontexworkingdir{.}
% set PythonTeX to use the document root directory as the working
% directory, so that all plots will be saved there; could use 
% another location, but then would need to specify a path when
% using \input and \InputIfFileExists

\newlength\figureheight
\newlength\figurewidth

\begin{document}

\begin{pycode}
from pylab import *
from tikzplotlib import save as tikz_save
x = linspace(0, 10, 101)
plot(x, sin(x))
xlabel('$x$-axis')
ylabel('$y$-axis')
tikz_save('fig.tikz',
       figureheight = '\\figureheight',
       figurewidth = '\\figurewidth')
\end{pycode}

\setlength\figureheight{2in}
\setlength\figurewidth{3in}
\InputIfFileExists{fig.tikz}{}{\textbf{!! Missing graphics !!}}

\setlength\figureheight{3in}
\setlength\figurewidth{4in}
\InputIfFileExists{fig.tikz}{}{\textbf{!! Missing graphics !!}}

\end{document}
4
  • Thanks for the help, this works nicely. As you say though it only seems to work for relatively simple plots. Commented Mar 15, 2014 at 17:52
  • 2
    matplotlib2tikz has improved recently and can handle quite the variety now. Perhaps worth checking it out again. Commented Mar 10, 2016 at 7:50
  • @NicoSchlömer That's excellent news. I got through graduate school using the early versions of matlab2tikz, and have been using matplotlib2tikz since before matplotlib had built-in PGF support.
    – G. Poore
    Commented Mar 10, 2016 at 14:12
  • 1
    I've just tested it with tikzplotlib-0.9.2 and I had to replace figureheight with axis_height and figurewidth with axis_width. By the way, bulk import with pylab is strongly discuraged, import matplotlib.pyplot as plt and import numpy as np is recommended. Commented Jul 3, 2020 at 12:30
1

Might be useful here to state how to get hold of the module matplotlib2tikz for the sake of a complete answer. I went through these steps before I could use it and apply the accepted answer above.

  1. Install pip and add it to the path variable. This site worked for me on Windows.
  2. Run the pip command: pip install matplotlib2tikz

But other than that, the above answer by G. Poore works.

2
  • The website says 'matplotlib2tikz has been renamed to tikzplotlib. matplotlib2tikz will no longer be supported.', so I guess this answer is now redundant.
    – Fritz
    Commented Jan 20, 2020 at 14:22
  • users of anaconda shoudn't use pip if it can be avoided, use instead conda install -c conda-forge tikzplotlib Commented Jul 3, 2020 at 10:10

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .