Skip to content

BUG: TypeError in plt.savefig using cairo backend #12806

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

Closed
jor- opened this issue Nov 14, 2018 · 5 comments
Closed

BUG: TypeError in plt.savefig using cairo backend #12806

jor- opened this issue Nov 14, 2018 · 5 comments

Comments

@jor-
Copy link
Contributor

jor- commented Nov 14, 2018

Saving a figure with plt.savefig in svg file format using the cairo backend results in a TypeError. The Traceback is:

  File "/sfs/fs5/home-sh/sunip229/opt/miniconda3/envs/py37_forge_jore/lib/python3.7/site-packages/util/plot.py", line 814, in save_and_close_fig
    plt.savefig('plot.svg', transparent=True, dpi=800)
  File "/sfs/fs5/home-sh/sunip229/opt/miniconda3/envs/py37_forge_jore/lib/python3.7/site-packages/matplotlib/pyplot.py", line 689, in savefig
    res = fig.savefig(*args, **kwargs)
  File "/sfs/fs5/home-sh/sunip229/opt/miniconda3/envs/py37_forge_jore/lib/python3.7/site-packages/matplotlib/figure.py", line 2094, in savefig
    self.canvas.print_figure(fname, **kwargs)
  File "/sfs/fs5/home-sh/sunip229/opt/miniconda3/envs/py37_forge_jore/lib/python3.7/site-packages/matplotlib/backend_bases.py", line 2075, in print_figure
    **kwargs)
  File "/sfs/fs5/home-sh/sunip229/opt/miniconda3/envs/py37_forge_jore/lib/python3.7/site-packages/matplotlib/backends/backend_cairo.py", line 569, in print_svg
    return self._save(fobj, 'svg', *args, **kwargs)
  File "/sfs/fs5/home-sh/sunip229/opt/miniconda3/envs/py37_forge_jore/lib/python3.7/site-packages/matplotlib/backends/backend_cairo.py", line 622, in _save
    self.figure.draw(renderer)
  File "/sfs/fs5/home-sh/sunip229/opt/miniconda3/envs/py37_forge_jore/lib/python3.7/site-packages/matplotlib/artist.py", line 50, in draw_wrapper
    return draw(artist, renderer, *args, **kwargs)
  File "/sfs/fs5/home-sh/sunip229/opt/miniconda3/envs/py37_forge_jore/lib/python3.7/site-packages/matplotlib/figure.py", line 1649, in draw
    renderer, self, artists, self.suppressComposite)
  File "/sfs/fs5/home-sh/sunip229/opt/miniconda3/envs/py37_forge_jore/lib/python3.7/site-packages/matplotlib/image.py", line 138, in _draw_list_compositing_images
    a.draw(renderer)
  File "/sfs/fs5/home-sh/sunip229/opt/miniconda3/envs/py37_forge_jore/lib/python3.7/site-packages/matplotlib/artist.py", line 50, in draw_wrapper
    return draw(artist, renderer, *args, **kwargs)
  File "/sfs/fs5/home-sh/sunip229/opt/miniconda3/envs/py37_forge_jore/lib/python3.7/site-packages/matplotlib/axes/_base.py", line 2628, in draw
    mimage._draw_list_compositing_images(renderer, self, artists)
  File "/sfs/fs5/home-sh/sunip229/opt/miniconda3/envs/py37_forge_jore/lib/python3.7/site-packages/matplotlib/image.py", line 138, in _draw_list_compositing_images
    a.draw(renderer)
  File "/sfs/fs5/home-sh/sunip229/opt/miniconda3/envs/py37_forge_jore/lib/python3.7/site-packages/matplotlib/artist.py", line 50, in draw_wrapper
    return draw(artist, renderer, *args, **kwargs)
  File "/sfs/fs5/home-sh/sunip229/opt/miniconda3/envs/py37_forge_jore/lib/python3.7/site-packages/matplotlib/axis.py", line 1185, in draw
    ticks_to_draw = self._update_ticks(renderer)
  File "/sfs/fs5/home-sh/sunip229/opt/miniconda3/envs/py37_forge_jore/lib/python3.7/site-packages/matplotlib/axis.py", line 1023, in _update_ticks
    tick_tups = list(self.iter_ticks())  # iter_ticks calls the locator
  File "/sfs/fs5/home-sh/sunip229/opt/miniconda3/envs/py37_forge_jore/lib/python3.7/site-packages/matplotlib/axis.py", line 967, in iter_ticks
    majorLocs = self.major.locator()
  File "/sfs/fs5/home-sh/sunip229/opt/miniconda3/envs/py37_forge_jore/lib/python3.7/site-packages/matplotlib/ticker.py", line 2128, in __call__
    return self.tick_values(vmin, vmax)
  File "/sfs/fs5/home-sh/sunip229/opt/miniconda3/envs/py37_forge_jore/lib/python3.7/site-packages/matplotlib/ticker.py", line 2189, in tick_values
    have_subs = len(subs) > 1 or (len(subs == 1) and subs[0] != 1.0)
TypeError: len() of unsized object
Uncaught exception. Entering post mortem debugging
Running 'cont' or 'step' will restart the program
> /sfs/fs5/home-sh/sunip229/opt/miniconda3/envs/py37_forge_jore/lib/python3.7/site-packages/matplotlib/ticker.py(2189)tick_values()
-> have_subs = len(subs) > 1 or (len(subs == 1) and subs[0] != 1.0)
(Pdb) subs
array(100.)
(Pdb) subs.ndim
0

Maybe subs should be converted to a one dimensional array first.

The versions of the related programs are:

matplotlib                3.0.2            py37h8a2030e_1    conda-forge
matplotlib-base           3.0.2            py37h20b835b_1    conda-forge
cairo                     1.14.12              h276e583_5    conda-forge
pycairo                   1.18.0           py37h4d1f301_0    conda-forge
python                    3.7.1                h5001a0f_0    conda-forge

The bug occurred at several plots. However, the creation of the plots is rather complex. Thus I have no minimal example that reproduces the bug for now. If this is necessary, however, I can try to construct one.

@jklymak
Copy link
Member

jklymak commented Nov 14, 2018

Can you reproduce a minimal working example that shows the problem? Just the trace back will make this hard to reproduce and fix.

@jor-
Copy link
Contributor Author

jor- commented Nov 15, 2018

@timhoffm: #12809 does not fix this bug, because subs is an array with 0 dimensions and thus len(subs) can not be evaluated.

@anntzer
Copy link
Contributor

anntzer commented Nov 15, 2018

Perhaps something like

diff --git i/lib/matplotlib/ticker.py w/lib/matplotlib/ticker.py
index b7c27d275..ecf530e2d 100644
--- i/lib/matplotlib/ticker.py
+++ w/lib/matplotlib/ticker.py
@@ -2127,7 +2127,7 @@ class LogLocator(Locator):
                                  "found '%s'." % subs)
             self._subs = subs
         else:
-            self._subs = np.asarray(subs, dtype=float)
+            self._subs = np.array(subs, dtype=float, copy=False, ndmin=1)
 
     def __call__(self):
         'Return the locations of the ticks'

would help?

@jor-
Copy link
Contributor Author

jor- commented Nov 15, 2018

Yes, this would help. Should I write a patch or do you want to do it?

@anntzer
Copy link
Contributor

anntzer commented Nov 15, 2018

go for it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants