Skip to content

Saving plot with text annotation and time axis to pgf file errors with multiple backends #11116

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
x49 opened this issue Apr 24, 2018 · 2 comments

Comments

@x49
Copy link

x49 commented Apr 24, 2018

Bug report

Writing a simple plot to a pgf file produces a ValueError exception, when saving through png works fine. This occurs explicitly only in the combination of

  1. Having a time axis in the plot
  2. Adding a text annotation into the plot

With no time axis or no annotation, the error does not appear. Tested with Qt5Agg, GTK3Agg, GTK3Cairo.

Code for reproduction

import matplotlib as mpl

mpl.use('Qt5Agg')  ## Error present
# mpl.use('GTK3Agg') ## Error present
# mpl.use('GTK3Cairo') ## Error present
print(mpl.get_backend())

import matplotlib.pyplot as plt
fig, ax = plt.subplots(1,1)


# t = [10, 20]                                        ## This works with text + pgf
t = [mpl.dates.num2date(5), mpl.dates.num2date(5.2)]  ## This is buggy with text + pgf

y = [10, 20]
ax.plot(t,y)

## This works in all cases
fig.savefig('out-1.png')
fig.savefig('out-1.pgf')

## Everything works fine without the text
ax.text(t[0],15,'Test')

fig.savefig('out-2.png') ## This works in all cases
fig.savefig('out-2.pgf') ## This does not work with time x-axis + text

Actual outcome

Qt5Agg
qt5ct: using qt5ct plugin
Traceback (most recent call last):
  File "test.py", line 23, in <module>
    fig.savefig('out-2.pgf') ## This does not work with time x-axis
  File "/usr/lib/python3.6/site-packages/matplotlib/figure.py", line 2035, in savefig
    self.canvas.print_figure(fname, **kwargs)
  File "/usr/lib/python3.6/site-packages/matplotlib/backends/backend_qt5agg.py", line 94, in print_figure
    super(FigureCanvasQTAgg, self).print_figure(*args, **kwargs)
  File "/usr/lib/python3.6/site-packages/matplotlib/backend_bases.py", line 2263, in print_figure
    **kwargs)
  File "/usr/lib/python3.6/site-packages/matplotlib/backends/backend_pgf.py", line 863, in print_pgf
    self._print_pgf_to_fh(fh, *args, **kwargs)
  File "/usr/lib/python3.6/site-packages/matplotlib/backends/backend_pgf.py", line 844, in _print_pgf_to_fh
    self.figure.draw(renderer)
  File "/usr/lib/python3.6/site-packages/matplotlib/artist.py", line 55, in draw_wrapper
    return draw(artist, renderer, *args, **kwargs)
  File "/usr/lib/python3.6/site-packages/matplotlib/figure.py", line 1475, in draw
    renderer, self, artists, self.suppressComposite)
  File "/usr/lib/python3.6/site-packages/matplotlib/image.py", line 141, in _draw_list_compositing_images
    a.draw(renderer)
  File "/usr/lib/python3.6/site-packages/matplotlib/artist.py", line 55, in draw_wrapper
    return draw(artist, renderer, *args, **kwargs)
  File "/usr/lib/python3.6/site-packages/matplotlib/axes/_base.py", line 2607, in draw
    mimage._draw_list_compositing_images(renderer, self, artists)
  File "/usr/lib/python3.6/site-packages/matplotlib/image.py", line 141, in _draw_list_compositing_images
    a.draw(renderer)
  File "/usr/lib/python3.6/site-packages/matplotlib/artist.py", line 55, in draw_wrapper
    return draw(artist, renderer, *args, **kwargs)
  File "/usr/lib/python3.6/site-packages/matplotlib/text.py", line 755, in draw
    ismath=ismath, mtext=mtext)
  File "/usr/lib/python3.6/site-packages/matplotlib/backends/backend_pgf.py", line 716, in draw_text
    x, y = mtext.get_transform().transform_point(mtext.get_position())
  File "/usr/lib/python3.6/site-packages/matplotlib/transforms.py", line 1533, in transform_point
    return self.transform(np.asarray([point]))[0]
  File "/usr/lib/python3.6/site-packages/matplotlib/transforms.py", line 1446, in transform
    res = self.transform_affine(self.transform_non_affine(values))
  File "/usr/lib/python3.6/site-packages/matplotlib/transforms.py", line 2482, in transform_affine
    return self.get_affine().transform(points)
  File "/usr/lib/python3.6/site-packages/matplotlib/transforms.py", line 1796, in transform
    return self.transform_affine(values)
  File "/usr/lib/python3.6/site-packages/matplotlib/transforms.py", line 1880, in transform_affine
    return affine_transform(points, mtx)
ValueError: object too deep for desired array

Expected outcome
png output is fine in both cases:
out-1.png:
out-1

out-2.png:
out-2

I would expect the pgf file to also be written in the second case.

Matplotlib version

  • Operating system: Arch Linux / 4.15.15-1-ARCH
  • Matplotlib version: 2.2.2
  • Matplotlib backend: Qt5Agg / GTK3Agg / GTK3Cairo
  • Python version: 3.6.5

All packages installed through distribution packages.

@tacaswell
Copy link
Member

attn @pwuertz

It looks like "object too deep for desired array" is coming out of numpy and mis-matched dimensions.

@pwuertz
Copy link
Contributor

pwuertz commented Apr 24, 2018

In the example posted here, adding/removing the seemingly unrelated text element to the figure makes the tick labels' Text.get_position() method flip its behavior. Instead of returning float positions it suddenly returns date objects, on which the subsequent get_position().transform_point() call chokes on.

Apparently, there is get_unitless_position() for getting the desired coordinates in such situations. I'll prepare a PR for that.

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

No branches or pull requests

4 participants