Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PGF backend + savefig.bbox results in I/O error in 3.2 #16731

Closed
Psirus opened this issue Mar 11, 2020 · 7 comments · Fixed by #16734
Closed

PGF backend + savefig.bbox results in I/O error in 3.2 #16731

Psirus opened this issue Mar 11, 2020 · 7 comments · Fixed by #16734
Assignees
Labels
backend: pgf Release critical For bugs that make the library unusable (segfaults, incorrect plots, etc) and major regressions.
Milestone

Comments

@Psirus
Copy link
Contributor

Psirus commented Mar 11, 2020

Bug report

Bug summary

When using matplotlib 3.2, the PGF backend and the rcParam "savefig.bbox" set to "tight", plt.savefig error with ValueError: I/O operation on closed file. Works fine on 3.1.3.

Code for reproduction

import matplotlib as mpl
mpl.use("pgf")
import matplotlib.pyplot as plt
plt.rcParams.update({"pgf.texsystem": "lualatex", "savefig.bbox": "tight"})
fig, ax = plt.subplots()
ax.plot([1.0, 2.0, 3.0], [4.0, 5.0, 6.0])
plt.savefig("test.pdf")

I don't know if the lualatex is necessary to reproduce, I just didn't have xelatex installed. Without the savefig.bbox it works fine.

Actual outcome

Traceback (most recent call last):
  File "test.py", line 9, in <module>
    plt.savefig("test.pdf")
  File "/usr/local/lib/python3.7/dist-packages/matplotlib/pyplot.py", line 723, in savefig
    res = fig.savefig(*args, **kwargs)
  File "/usr/local/lib/python3.7/dist-packages/matplotlib/figure.py", line 2203, in savefig
    self.canvas.print_figure(fname, **kwargs)
  File "/usr/local/lib/python3.7/dist-packages/matplotlib/backend_bases.py", line 2067, in print_figure
    self.figure.draw(renderer)
  File "/usr/local/lib/python3.7/dist-packages/matplotlib/artist.py", line 38, in draw_wrapper
    return draw(artist, renderer, *args, **kwargs)
  File "/usr/local/lib/python3.7/dist-packages/matplotlib/figure.py", line 1734, in draw
    self.patch.draw(renderer)
  File "/usr/local/lib/python3.7/dist-packages/matplotlib/artist.py", line 38, in draw_wrapper
    return draw(artist, renderer, *args, **kwargs)
  File "/usr/local/lib/python3.7/dist-packages/matplotlib/patches.py", line 602, in draw
    self._facecolor if self._facecolor[3] else None)
  File "/usr/local/lib/python3.7/dist-packages/matplotlib/backends/backend_pgf.py", line 476, in draw_path
    writeln(self.fh, r"\begin{pgfscope}")
  File "/usr/local/lib/python3.7/dist-packages/matplotlib/backends/backend_pgf.py", line 118, in writeln
    fh.write(line)
ValueError: I/O operation on closed file.

Expected outcome

Works in 3.1.3.

Matplotlib version

  • Operating system: Debian Stable
  • Matplotlib version: 3.2
  • Matplotlib backend (print(matplotlib.get_backend())): pgf
  • Python version: 3.7

Installed matplotlib from pip.

@tacaswell tacaswell added the Release critical For bugs that make the library unusable (segfaults, incorrect plots, etc) and major regressions. label Mar 11, 2020
@tacaswell tacaswell added this to the v3.2.1 milestone Mar 11, 2020
@tacaswell
Copy link
Member

@Psirus I don't have pgf set up on the machine I am currently on, can you confirm it works without the tight bounding box?

@Psirus
Copy link
Contributor Author

Psirus commented Mar 11, 2020

Yes, if I remove the savefig.bbox or set it to standard, it works.

@tacaswell
Copy link
Member

attn @anntzer I suspect this is related to the cleanup to the pgf code.

I suspect the problem is that to do the 'tight' bounding box we have to render the figure twice but are not getting a fresh file handle the second time.

@anntzer anntzer self-assigned this Mar 11, 2020
@PanagiotisS
Copy link

PanagiotisS commented Mar 11, 2020

Hi,
I have same (?) issue when using pgf backend, savefig with bbox, and matplotlib version 3.2.
Matplotlib version 3.1.3 works without problem. or matplotlib version 3.2, pgf, without bbox.

Same problem appears with python 3.6.9 when installing matplotlib through pip or with python 3.8.1 through conda env.

Python 3.8.1 (default, Jan  8 2020, 22:29:32)
[GCC 7.3.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import matplotlib as mpl
>>> import matplotlib.pyplot as plt
>>> x = [1, 2, 3]
>>> y = [5, 6, 7]
>>> plt.plot(x, y)
[<matplotlib.lines.Line2D object at 0x7fb0a4e1ed90>]
>>> plt.savefig("plots/test.pdf", bbox_inches="tight")
>>> mpl.use("pgf")
>>> plt.savefig("plots/test.pdf", bbox_inches="tight")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/user/.conda/envs/mpltest/lib/python3.8/site-packages/matplotlib/pyplot.py", line 723, in savefig
    res = fig.savefig(*args, **kwargs)
  File "/home/user/.conda/envs/mpltest/lib/python3.8/site-packages/matplotlib/figure.py", line 2203, in savefig
    self.canvas.print_figure(fname, **kwargs)
  File "/home/user/.conda/envs/mpltest/lib/python3.8/site-packages/matplotlib/backend_bases.py", line 2067, in print_figure
    self.figure.draw(renderer)
  File "/home/user/.conda/envs/mpltest/lib/python3.8/site-packages/matplotlib/artist.py", line 38, in draw_wrapper
    return draw(artist, renderer, *args, **kwargs)
  File "/home/user/.conda/envs/mpltest/lib/python3.8/site-packages/matplotlib/figure.py", line 1734, in draw
    self.patch.draw(renderer)
  File "/home/user/.conda/envs/mpltest/lib/python3.8/site-packages/matplotlib/artist.py", line 38, in draw_wrapper
    return draw(artist, renderer, *args, **kwargs)
  File "/home/user/.conda/envs/mpltest/lib/python3.8/site-packages/matplotlib/patches.py", line 598, in draw
    draw_path(tpath, affine,
  File "/home/user/.conda/envs/mpltest/lib/python3.8/site-packages/matplotlib/backends/backend_pgf.py", line 476, in draw_path
    writeln(self.fh, r"\begin{pgfscope}")
  File "/home/user/.conda/envs/mpltest/lib/python3.8/site-packages/matplotlib/backends/backend_pgf.py", line 118, in writeln
    fh.write(line)
ValueError: I/O operation on closed file.
>>>

I created a new conda env where only matplotlib was installed in order to test it.

 ○ conda list
# packages in environment at /home/user/.conda/envs/mpltest:
#
# Name                    Version                   Build  Channel
_libgcc_mutex             0.1                        main
blas                      1.0                         mkl
ca-certificates           2019.11.28           hecc5488_0    conda-forge
certifi                   2019.11.28               py38_0    conda-forge
cycler                    0.10.0                   py38_0
dbus                      1.13.12              h746ee38_0
expat                     2.2.6                he6710b0_0
fontconfig                2.13.1            h86ecdb6_1001    conda-forge
freetype                  2.9.1                h8a8886c_1
glib                      2.63.1               h5a9c865_0
gst-plugins-base          1.14.5               h0935bb2_2    conda-forge
gstreamer                 1.14.5               h36ae1b5_2    conda-forge
icu                       64.2                 he1b5a44_1    conda-forge
intel-openmp              2020.0                      166
jpeg                      9c                h14c3975_1001    conda-forge
kiwisolver                1.0.1            py38he6710b0_0
ld_impl_linux-64          2.33.1               h53a641e_7
libedit                   3.1.20181209         hc058e9b_0
libffi                    3.2.1                hd88cf55_4
libgcc-ng                 9.1.0                hdf63c60_0
libgfortran-ng            7.3.0                hdf63c60_0
libpng                    1.6.37               hbc83047_0
libstdcxx-ng              9.1.0                hdf63c60_0
libuuid                   2.32.1            h14c3975_1000    conda-forge
libxcb                    1.13                 h1bed415_1
libxml2                   2.9.9                hea5a465_1
matplotlib                3.2.0                         1    conda-forge
matplotlib-base           3.2.0            py38h250f245_1    conda-forge
mkl                       2020.0                      166
mkl-service               2.3.0            py38he904b0f_0
mkl_fft                   1.0.15           py38ha843d7b_0
mkl_random                1.1.0            py38h962f231_0
ncurses                   6.2                  he6710b0_0
numpy                     1.18.1           py38h4f9e942_0
numpy-base                1.18.1           py38hde5b4d6_1
openssl                   1.1.1d               h516909a_0    conda-forge
pcre                      8.43                 he6710b0_0
pip                       20.0.2                   py38_1
pyparsing                 2.4.6                      py_0
pyqt                      5.9.2            py38h05f1152_4
python                    3.8.1                h0371630_1
python-dateutil           2.8.1                      py_0
qt                        5.9.7                h0c104cb_3    conda-forge
readline                  7.0                  h7b6447c_5
setuptools                45.2.0                   py38_0
sip                       4.19.13          py38he6710b0_0
six                       1.14.0                   py38_0
sqlite                    3.31.1               h7b6447c_0
tk                        8.6.10               hed695b0_0    conda-forge
tornado                   6.0.3            py38h7b6447c_3
wheel                     0.34.2                   py38_0
xz                        5.2.4                h14c3975_4
zlib                      1.2.11               h7b6447c_3
(mpltest)

○ uname -a
Linux hostname1 3.10.0-1062.12.1.el7.x86_64 #1 SMP Tue Feb 4 23:02:59 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

○ lsb_release -d                                                                                       
Description:    CentOS Linux release 7.7.1908 (Core)  

I hope this can be of use to you

@anntzer
Copy link
Contributor

anntzer commented Mar 11, 2020

I understand where the problem comes from, but it's going to be slightly tricky to fix so it will likely take a few days.

Basically this comes from the fact that the pgf backend needs to interact for real with the filesystem even when saving to an in-memory BytesIO() object (both because of TeX, and because draw_image works by saving to an image and then includegraphics'ing it). This breaks the assumption I made in #14134, which is that the "dummy" renderer used for tight-layouting could just use an in-memory buffer without filesystem considerations.

@tacaswell
Copy link
Member

Is the fastest path to revert #14134 for 3.2.x or is there a bunch of follow on PRs that would also need to be backed out?

@anntzer
Copy link
Contributor

anntzer commented Mar 11, 2020

Reverting #14134 and its followup #14216 is likely easiest for 3.2.
edit: now done as #16732.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend: pgf Release critical For bugs that make the library unusable (segfaults, incorrect plots, etc) and major regressions.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants