Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Specifying a Marker as a Tuple seems broken in 3.2 #16811

Copy link
Copy link
Closed
@Erotemic

Description

@Erotemic
Issue body actions

Bug report

Bug summary

In matplotlib 3.2 setting a line marker=(3, 2, 0.0) (which should be an asterisk style marker with 3 sides and 0 degrees of rotation) causes an error.

AttributeError: 'IdentityTransform' object has no attribute 'scale'

In version 3.1.2, this error does not occur. It looks like

Code for reproduction

def main():
    import matplotlib.pyplot as plt
    fig = plt.figure()
    fig.add_axes()
    ax = fig.gca()
    ax.plot([0, 1, 2], [0, 1, 2], marker=(3, 2, 0.0))
    fig.savefig('foo.png')


if __name__ == '__main__':
    main()

This results in the error:

Traceback (most recent call last):
  File "/home/joncrall/code/kwplot/dev/mwe_markerstye.py", line 15, in <module>
    main()
  File "/home/joncrall/code/kwplot/dev/mwe_markerstye.py", line 7, in main
    fig.savefig('foo.png')
  File "/home/joncrall/.local/conda/envs/py38/lib/python3.8/site-packages/matplotlib/figure.py", line 2203, in savefig
    self.canvas.print_figure(fname, **kwargs)
  File "/home/joncrall/.local/conda/envs/py38/lib/python3.8/site-packages/matplotlib/backends/backend_qt5agg.py", line 94, in print_figure
    super().print_figure(*args, **kwargs)
  File "/home/joncrall/.local/conda/envs/py38/lib/python3.8/site-packages/matplotlib/backend_bases.py", line 2086, in print_figure
    result = print_method(
  File "/home/joncrall/.local/conda/envs/py38/lib/python3.8/site-packages/matplotlib/backends/backend_agg.py", line 514, in print_png
    FigureCanvasAgg.draw(self)
  File "/home/joncrall/.local/conda/envs/py38/lib/python3.8/site-packages/matplotlib/backends/backend_agg.py", line 393, in draw
    self.figure.draw(self.renderer)
  File "/home/joncrall/.local/conda/envs/py38/lib/python3.8/site-packages/matplotlib/artist.py", line 38, in draw_wrapper
    return draw(artist, renderer, *args, **kwargs)
  File "/home/joncrall/.local/conda/envs/py38/lib/python3.8/site-packages/matplotlib/figure.py", line 1735, in draw
    mimage._draw_list_compositing_images(
  File "/home/joncrall/.local/conda/envs/py38/lib/python3.8/site-packages/matplotlib/image.py", line 137, in _draw_list_compositing_images
    a.draw(renderer)
  File "/home/joncrall/.local/conda/envs/py38/lib/python3.8/site-packages/matplotlib/artist.py", line 38, in draw_wrapper
    return draw(artist, renderer, *args, **kwargs)
  File "/home/joncrall/.local/conda/envs/py38/lib/python3.8/site-packages/matplotlib/axes/_base.py", line 2630, in draw
    mimage._draw_list_compositing_images(renderer, self, artists)
  File "/home/joncrall/.local/conda/envs/py38/lib/python3.8/site-packages/matplotlib/image.py", line 137, in _draw_list_compositing_images
    a.draw(renderer)
  File "/home/joncrall/.local/conda/envs/py38/lib/python3.8/site-packages/matplotlib/artist.py", line 38, in draw_wrapper
    return draw(artist, renderer, *args, **kwargs)
  File "/home/joncrall/.local/conda/envs/py38/lib/python3.8/site-packages/matplotlib/lines.py", line 866, in draw
    marker_trans = marker_trans.scale(w)
AttributeError: 'IdentityTransform' object has no attribute 'scale'

While the 3.1.2 version results in a nice plot:

image

Matplotlib version

  • Operating system: Linux
  • Matplotlib version: 3.2 (via pip)
  • Matplotlib backend: tried agg and pyqt5
  • Python version: 3.7 and 3.8

I've identified a possible solution. The main difference seems to be in the _set_tuple_marker function. In 3.1.2 it was:

    def _set_tuple_marker(self):
        marker = self._marker
        if isinstance(marker[0], Number):
            if len(marker) == 2:
                numsides, rotation = marker[0], 0.0
            elif len(marker) == 3:
                numsides, rotation = marker[0], marker[2]
            symstyle = marker[1]
            if symstyle == 0:
                self._path = Path.unit_regular_polygon(numsides)
                self._joinstyle = 'miter'
            elif symstyle == 1:
                self._path = Path.unit_regular_star(numsides)
                self._joinstyle = 'bevel'
            elif symstyle == 2:
                self._path = Path.unit_regular_asterisk(numsides)
                self._filled = False
                self._joinstyle = 'bevel'
            elif symstyle == 3:
                cbook.warn_deprecated(
                    "3.0", message="Setting a circle marker using `(..., 3)` "
                    "is deprecated since Matplotlib 3.0, and support for it "
                    "will be removed in 3.2.  Directly pass 'o' instead.")
                self._path = Path.unit_circle()
            self._transform = Affine2D().scale(0.5).rotate_deg(rotation)
        else:
            cbook.warn_deprecated(
                "3.0", message="Passing vertices as `(verts, 0)` is "
                "deprecated since Matplotlib 3.0, and support for it will be "
                "removed in 3.2.  Directly pass `verts` instead.")
            verts = np.asarray(marker[0])
            path = Path(verts)
            self._set_custom_marker(path)

and in 3.2 it was cleaned up to:

    def _set_tuple_marker(self):
        marker = self._marker
        print('marker = {!r}'.format(marker))
        if len(marker) == 2:
            numsides, rotation = marker[0], 0.0
        elif len(marker) == 3:
            numsides, rotation = marker[0], marker[2]
        symstyle = marker[1]
        if symstyle == 0:
            self._path = Path.unit_regular_polygon(numsides)
            self._joinstyle = 'miter'
        elif symstyle == 1:
            self._path = Path.unit_regular_star(numsides)
            self._joinstyle = 'bevel'
        elif symstyle == 2:
            self._path = Path.unit_regular_asterisk(numsides)
            self._filled = False
            self._joinstyle = 'bevel'
        else:
            raise ValueError(f"Unexpected tuple marker: {marker}")

However, notice that in the second version self._transform is never set. Also note that in the 3.2 version the rotation param is never used. I expect that the self._transform = Affine2D().scale(0.5).rotate_deg(rotation) line was supposed to be ported, but never was. Adding it back in seems to fix the issue.

I noticed it when looking in the lines.py draw method. I saw most markers had an AffineTransform, but the ones I made using the tuple method of initialization has IdentityTransforms.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      Morty Proxy This is a proxified and sanitized view of the page, visit original site.