Skip to content

[Bug]: axline doesn't work with some axes scales #28870

Closed
@mesvam

Description

@mesvam

Bug summary

With some types and values of axes scaling, axline fails to draw a line.

Code for reproduction

This works

fig, ax = plt.subplots(figsize=(5, 5))
ax.set_yscale('asinh', linear_width=1e-9)
ax.axline([1, 0], [1, 1])

but this errors

fig, ax = plt.subplots(figsize=(5, 5))
ax.set_yscale('asinh', linear_width=1e-10)
ax.axline([1, 0], [1, 1])

The only difference is the value of linear_width

Actual outcome

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
File C:\ProgramData\Miniconda3\Lib\site-packages\matplotlib\pyplot.py:268, in _draw_all_if_interactive()
    266 def _draw_all_if_interactive() -> None:
    267     if matplotlib.is_interactive():
--> 268         draw_all()

File C:\ProgramData\Miniconda3\Lib\site-packages\matplotlib\_pylab_helpers.py:131, in Gcf.draw_all(cls, force)
    129 for manager in cls.get_all_fig_managers():
    130     if force or manager.canvas.figure.stale:
--> 131         manager.canvas.draw_idle()

File C:\ProgramData\Miniconda3\Lib\site-packages\matplotlib\backend_bases.py:1905, in FigureCanvasBase.draw_idle(self, *args, **kwargs)
   1903 if not self._is_idle_drawing:
   1904     with self._idle_draw_cntx():
-> 1905         self.draw(*args, **kwargs)

File C:\ProgramData\Miniconda3\Lib\site-packages\matplotlib\backends\backend_agg.py:387, in FigureCanvasAgg.draw(self)
    384 # Acquire a lock on the shared font cache.
    385 with (self.toolbar._wait_cursor_for_draw_cm() if self.toolbar
    386       else nullcontext()):
--> 387     self.figure.draw(self.renderer)
    388     # A GUI class may be need to update a window using this draw, so
    389     # don't forget to call the superclass.
    390     super().draw()

File C:\ProgramData\Miniconda3\Lib\site-packages\matplotlib\artist.py:95, in _finalize_rasterization.<locals>.draw_wrapper(artist, renderer, *args, **kwargs)
     93 @wraps(draw)
     94 def draw_wrapper(artist, renderer, *args, **kwargs):
---> 95     result = draw(artist, renderer, *args, **kwargs)
     96     if renderer._rasterizing:
     97         renderer.stop_rasterizing()

File C:\ProgramData\Miniconda3\Lib\site-packages\matplotlib\artist.py:72, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
     69     if artist.get_agg_filter() is not None:
     70         renderer.start_filter()
---> 72     return draw(artist, renderer)
     73 finally:
     74     if artist.get_agg_filter() is not None:

File C:\ProgramData\Miniconda3\Lib\site-packages\matplotlib\figure.py:3162, in Figure.draw(self, renderer)
   3159             # ValueError can occur when resizing a window.
   3161     self.patch.draw(renderer)
-> 3162     mimage._draw_list_compositing_images(
   3163         renderer, self, artists, self.suppressComposite)
   3165     renderer.close_group('figure')
   3166 finally:

File C:\ProgramData\Miniconda3\Lib\site-packages\matplotlib\image.py:132, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
    130 if not_composite or not has_images:
    131     for a in artists:
--> 132         a.draw(renderer)
    133 else:
    134     # Composite any adjacent images together
    135     image_group = []

File C:\ProgramData\Miniconda3\Lib\site-packages\matplotlib\artist.py:72, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
     69     if artist.get_agg_filter() is not None:
     70         renderer.start_filter()
---> 72     return draw(artist, renderer)
     73 finally:
     74     if artist.get_agg_filter() is not None:

File C:\ProgramData\Miniconda3\Lib\site-packages\matplotlib\axes\_base.py:3137, in _AxesBase.draw(self, renderer)
   3134 if artists_rasterized:
   3135     _draw_rasterized(self.figure, artists_rasterized, renderer)
-> 3137 mimage._draw_list_compositing_images(
   3138     renderer, self, artists, self.figure.suppressComposite)
   3140 renderer.close_group('axes')
   3141 self.stale = False

File C:\ProgramData\Miniconda3\Lib\site-packages\matplotlib\image.py:132, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
    130 if not_composite or not has_images:
    131     for a in artists:
--> 132         a.draw(renderer)
    133 else:
    134     # Composite any adjacent images together
    135     image_group = []

File C:\ProgramData\Miniconda3\Lib\site-packages\matplotlib\artist.py:39, in _prevent_rasterization.<locals>.draw_wrapper(artist, renderer, *args, **kwargs)
     36     renderer.stop_rasterizing()
     37     renderer._rasterizing = False
---> 39 return draw(artist, renderer, *args, **kwargs)

File C:\ProgramData\Miniconda3\Lib\site-packages\matplotlib\lines.py:1541, in AxLine.draw(self, renderer)
   1539 def draw(self, renderer):
   1540     self._transformed_path = None  # Force regen.
-> 1541     super().draw(renderer)

File C:\ProgramData\Miniconda3\Lib\site-packages\matplotlib\artist.py:72, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
     69     if artist.get_agg_filter() is not None:
     70         renderer.start_filter()
---> 72     return draw(artist, renderer)
     73 finally:
     74     if artist.get_agg_filter() is not None:

File C:\ProgramData\Miniconda3\Lib\site-packages\matplotlib\lines.py:769, in Line2D.draw(self, renderer)
    767 renderer.open_group('line2d', self.get_gid())
    768 if self._lineStyles[self._linestyle] != '_draw_nothing':
--> 769     tpath, affine = (self._get_transformed_path()
    770                      .get_transformed_path_and_affine())
    771     if len(tpath.vertices):
    772         gc = renderer.new_gc()

File C:\ProgramData\Miniconda3\Lib\site-packages\matplotlib\lines.py:734, in Line2D._get_transformed_path(self)
    732 """Return this line's `~matplotlib.transforms.TransformedPath`."""
    733 if self._transformed_path is None:
--> 734     self._transform_path()
    735 return self._transformed_path

File C:\ProgramData\Miniconda3\Lib\site-packages\matplotlib\lines.py:729, in Line2D._transform_path(self, subslice)
    727 else:
    728     _path = self._path
--> 729 self._transformed_path = TransformedPath(_path, self.get_transform())

File C:\ProgramData\Miniconda3\Lib\site-packages\matplotlib\lines.py:1510, in AxLine.get_transform(self)
   1508 if np.allclose(x1, x2):
   1509     if np.allclose(y1, y2):
-> 1510         raise ValueError(
   1511             f"Cannot draw a line through two identical points "
   1512             f"(x={(x1, x2)}, y={(y1, y2)})")
   1513     slope = np.inf
   1514 else:

ValueError: Cannot draw a line through two identical points (x=(1.0, 1.0), y=(0.0, 2.3718998110500403e-09))

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
File C:\ProgramData\Miniconda3\Lib\site-packages\IPython\core\formatters.py:343, in BaseFormatter.__call__(self, obj)
    341     pass
    342 else:
--> 343     return printer(obj)
    344 # Finally look for special method names
    345 method = get_real_method(obj, self.print_method)

File C:\ProgramData\Miniconda3\Lib\site-packages\IPython\core\pylabtools.py:170, in print_figure(fig, fmt, bbox_inches, base64, **kwargs)
    167     from matplotlib.backend_bases import FigureCanvasBase
    168     FigureCanvasBase(fig)
--> 170 fig.canvas.print_figure(bytes_io, **kw)
    171 data = bytes_io.getvalue()
    172 if fmt == 'svg':

File C:\ProgramData\Miniconda3\Lib\site-packages\matplotlib\backend_bases.py:2175, in FigureCanvasBase.print_figure(self, filename, dpi, facecolor, edgecolor, orientation, format, bbox_inches, pad_inches, bbox_extra_artists, backend, **kwargs)
   2172     # we do this instead of `self.figure.draw_without_rendering`
   2173     # so that we can inject the orientation
   2174     with getattr(renderer, "_draw_disabled", nullcontext)():
-> 2175         self.figure.draw(renderer)
   2176 if bbox_inches:
   2177     if bbox_inches == "tight":

File C:\ProgramData\Miniconda3\Lib\site-packages\matplotlib\artist.py:95, in _finalize_rasterization.<locals>.draw_wrapper(artist, renderer, *args, **kwargs)
     93 @wraps(draw)
     94 def draw_wrapper(artist, renderer, *args, **kwargs):
---> 95     result = draw(artist, renderer, *args, **kwargs)
     96     if renderer._rasterizing:
     97         renderer.stop_rasterizing()

File C:\ProgramData\Miniconda3\Lib\site-packages\matplotlib\artist.py:72, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
     69     if artist.get_agg_filter() is not None:
     70         renderer.start_filter()
---> 72     return draw(artist, renderer)
     73 finally:
     74     if artist.get_agg_filter() is not None:

File C:\ProgramData\Miniconda3\Lib\site-packages\matplotlib\figure.py:3162, in Figure.draw(self, renderer)
   3159             # ValueError can occur when resizing a window.
   3161     self.patch.draw(renderer)
-> 3162     mimage._draw_list_compositing_images(
   3163         renderer, self, artists, self.suppressComposite)
   3165     renderer.close_group('figure')
   3166 finally:

File C:\ProgramData\Miniconda3\Lib\site-packages\matplotlib\image.py:132, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
    130 if not_composite or not has_images:
    131     for a in artists:
--> 132         a.draw(renderer)
    133 else:
    134     # Composite any adjacent images together
    135     image_group = []

File C:\ProgramData\Miniconda3\Lib\site-packages\matplotlib\artist.py:72, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
     69     if artist.get_agg_filter() is not None:
     70         renderer.start_filter()
---> 72     return draw(artist, renderer)
     73 finally:
     74     if artist.get_agg_filter() is not None:

File C:\ProgramData\Miniconda3\Lib\site-packages\matplotlib\axes\_base.py:3137, in _AxesBase.draw(self, renderer)
   3134 if artists_rasterized:
   3135     _draw_rasterized(self.figure, artists_rasterized, renderer)
-> 3137 mimage._draw_list_compositing_images(
   3138     renderer, self, artists, self.figure.suppressComposite)
   3140 renderer.close_group('axes')
   3141 self.stale = False

File C:\ProgramData\Miniconda3\Lib\site-packages\matplotlib\image.py:132, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
    130 if not_composite or not has_images:
    131     for a in artists:
--> 132         a.draw(renderer)
    133 else:
    134     # Composite any adjacent images together
    135     image_group = []

File C:\ProgramData\Miniconda3\Lib\site-packages\matplotlib\artist.py:39, in _prevent_rasterization.<locals>.draw_wrapper(artist, renderer, *args, **kwargs)
     36     renderer.stop_rasterizing()
     37     renderer._rasterizing = False
---> 39 return draw(artist, renderer, *args, **kwargs)

File C:\ProgramData\Miniconda3\Lib\site-packages\matplotlib\lines.py:1541, in AxLine.draw(self, renderer)
   1539 def draw(self, renderer):
   1540     self._transformed_path = None  # Force regen.
-> 1541     super().draw(renderer)

File C:\ProgramData\Miniconda3\Lib\site-packages\matplotlib\artist.py:72, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
     69     if artist.get_agg_filter() is not None:
     70         renderer.start_filter()
---> 72     return draw(artist, renderer)
     73 finally:
     74     if artist.get_agg_filter() is not None:

File C:\ProgramData\Miniconda3\Lib\site-packages\matplotlib\lines.py:769, in Line2D.draw(self, renderer)
    767 renderer.open_group('line2d', self.get_gid())
    768 if self._lineStyles[self._linestyle] != '_draw_nothing':
--> 769     tpath, affine = (self._get_transformed_path()
    770                      .get_transformed_path_and_affine())
    771     if len(tpath.vertices):
    772         gc = renderer.new_gc()

File C:\ProgramData\Miniconda3\Lib\site-packages\matplotlib\lines.py:734, in Line2D._get_transformed_path(self)
    732 """Return this line's `~matplotlib.transforms.TransformedPath`."""
    733 if self._transformed_path is None:
--> 734     self._transform_path()
    735 return self._transformed_path

File C:\ProgramData\Miniconda3\Lib\site-packages\matplotlib\lines.py:729, in Line2D._transform_path(self, subslice)
    727 else:
    728     _path = self._path
--> 729 self._transformed_path = TransformedPath(_path, self.get_transform())

File C:\ProgramData\Miniconda3\Lib\site-packages\matplotlib\lines.py:1510, in AxLine.get_transform(self)
   1508 if np.allclose(x1, x2):
   1509     if np.allclose(y1, y2):
-> 1510         raise ValueError(
   1511             f"Cannot draw a line through two identical points "
   1512             f"(x={(x1, x2)}, y={(y1, y2)})")
   1513     slope = np.inf
   1514 else:

ValueError: Cannot draw a line through two identical points (x=(1.0, 1.0), y=(0.0, 2.3718998110500403e-09))

Expected outcome

Should generate plot without error

Additional information

No response

Operating system

No response

Matplotlib Version

3.9.2

Matplotlib Backend

No response

Python version

No response

Jupyter version

No response

Installation

None

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions