6

I have prepared a Jupyter Notebook with a number of matplotlib plots. Now I would like to save plots to PGF format, so I can reuse them in LaTeX. I have followed this blog post to implement that idea.

Unfortunately, if I configure matplotlib to generate PGF files they are not shown in the notebook. If I disable matplotlib to generate PGF files plots are shown but PGF files are not generated. How can I have both?

Here's minimal example to reproduce the problem:

# Test if integration between python and latex works fine
import subprocess; subprocess.check_call(["latex", "-help"])

# Configure matplotlib to generate PGF files
import matplotlib
import matplotlib.pyplot as plt 
matplotlib.use("pgf")
matplotlib.rcParams.update({
    "pgf.texsystem": "pdflatex",
    'font.family': 'serif',
    'text.usetex': True,
    'pgf.rcfonts': False,
})

# Prepare simple plot
import pandas as pd
df = pd.DataFrame({
     'length': [1.5, 0.5, 1.2, 0.9, 3],
     'width': [0.7, 0.2, 0.15, 0.2, 1.1]
     }, index= ['pig', 'rabbit', 'duck', 'chicken', 'horse'])
hist = df.hist(bins=3)

# Save the plot to PGF file
plt.savefig('histogram.pgf')

Here's the output for enabled configuration of matplotlib. histogram.pgf file is generated and saved, but plot is not shown.

With configuration enabled

Here's example of when disabling matplotlib configuration for PGF. Plot is shown, but generated histogram.pgf file is empty --- does not contain the plot.

enter image description here

dzieciou
  • 4,049
  • 8
  • 41
  • 85
  • Can you check if histogram.pgf is generated on your jupyter path? If it is, you probably need to import the generated pgf file to your latex document just as you would a png file. – Jason Chia Jan 24 '20 at 08:33
  • @JasonChia `histogram.pgf` is generated, but plot is not shown in Jupyter Notebook. I have added a screenshot. – dzieciou Jan 24 '20 at 08:39
  • Simply add plt.show() should fix your problem i think. – Jason Chia Jan 24 '20 at 08:42
  • @JasonChia Unfortunately, it results in `UserWarning: Matplotlib is currently using pgf, which is a non-GUI backend, so cannot show the figure.` – dzieciou Jan 24 '20 at 08:44
  • Can you try adding:" %matplotlib inline " I can't seem to reproduce your error since I do not have latex on my setup right now. https://github.com/jupyter/notebook/issues/3523 – Jason Chia Jan 24 '20 at 09:03
  • @JasonChia In this case it doesn't help. I added another screenshot showing that plot is generated when PGF configuration is disabled. – dzieciou Jan 24 '20 at 09:11
  • 1
    Reading the blog post in detail, I think the pgf format is not graphically possible for pyplot to plot it as its a latex specific format. Are you able to load the graph into latex? I believe the blog describes tuning the width and height of the graph after getting line width from latex. This probably hints that you cannot visualize the graph when using pgf format. Do check out this link too. https://matplotlib.org/3.1.1/tutorials/text/pgf.html – Jason Chia Jan 24 '20 at 09:27
  • 2
    If `plt.something` is called in its own cell, it will by default not remember the previous pyplot state. So independent of any `pgf` issue, either put `plt.savefig` in the same cell where the figure is created, or use `fig.savefig` where `fig` is the figure to save. Knowing this, maybe you can edit the question to get rid of this tangential problem. – ImportanceOfBeingErnest Jan 27 '20 at 16:07
  • 1
    @ImportanceOfBeingErnest Wow! Thanks. (1) Keeping `plt.savefig` in the same cell where the figure is created + (2) removing `matplotlib.use("pgf")` and `matplotlib.rcParams.update(...` lines helped. Figure is saved correctly to PGF file and is rendered correctly in LaTeX, despite not saying explcitytly to matplotlib to use PGF backend. – dzieciou Jan 30 '20 at 16:21

2 Answers2

0

I cannot reproduce your problem

enter image description here

enter image description here

I had to run the first cell three or four times, otherwise I wouldn't see the figure.

%matplotlib inline

By the way, I am using Ubuntu 16.04, with Python 3.7.6 and Matplotlib 3.1.1.

Community
  • 1
  • 1
David
  • 435
  • 3
  • 12
  • Interesting. case In my case two things helped that I described in my comment: https://stackoverflow.com/questions/59892762/showing-and-saving-pgf-plots-from-jupyter-notebook?noredirect=1#comment106093852_59892762 – dzieciou Jan 30 '20 at 16:23
0

Don't use matplotlib.use("pgf"); there is an alternative that achieves the same thing without the downside of not being able to show your plot:

from matplotlib.backends.backend_pgf import FigureCanvasPgf
matplotlib.backend_bases.register_backend('pdf', FigureCanvasPgf)

This method allows you to keep using regular interactive back-ends while being able to save compiled PDF files using plt.savefig('figure.pdf')1, and the plot is shown inline after the file is saved.

You can still set the pgf parameters. There is no need to remove them since they don't interfere with the interactive back-end:

matplotlib.rcParams.update({
    "pgf.texsystem": "pdflatex",
    'pgf.rcfonts': False,
})
gijswijs
  • 1,958
  • 19
  • 24
  • 1
    @dzieciou as the author of this answer I was wondering the same thing. This *is* the approach that helped me solve this issue, and it is the approach recommended in the official docs. Maybe my wording of the 1st sentence seems like I am being derogatory, but that's not the case. You really shouldn't use it, as there are better alternatives. Let me rephrase it a bit, maybe that helps future readers. – gijswijs Sep 19 '21 at 08:19