Skip to content

Area mark raises with log x scale #2886

@mwaskom

Description

@mwaskom
so.Plot([1, 10, 100, 1000], [1, 2, 4, 3]).add(so.Area()).scale(x="log")

Raises:

/Users/mwaskom/miniconda3/envs/seaborn-py39-latest/lib/python3.9/site-packages/matplotlib/transforms.py:2664: RuntimeWarning: invalid value encountered in double_scalars
  self._mtx = np.array([[x_scale, 0.0    , (-inl*x_scale)],
---------------------------------------------------------------------------
LinAlgError                               Traceback (most recent call last)
File ~/miniconda3/envs/seaborn-py39-latest/lib/python3.9/site-packages/IPython/core/formatters.py:343, in BaseFormatter.__call__(self, obj)
    341     method = get_real_method(obj, self.print_method)
    342     if method is not None:
--> 343         return method()
    344     return None
    345 else:

File ~/code/seaborn/seaborn/_core/plot.py:224, in Plot._repr_png_(self)
    222 def _repr_png_(self) -> tuple[bytes, dict[str, float]]:
--> 224     return self.plot()._repr_png_()

File ~/code/seaborn/seaborn/_core/plot.py:635, in Plot.plot(self, pyplot)
    632 plotter._layers = layers
    634 for layer in layers:
--> 635     plotter._plot_layer(self, layer)
    637 plotter._make_legend()
    639 # TODO this should be configurable

File ~/code/seaborn/seaborn/_core/plot.py:1142, in Plotter._plot_layer(self, p, layer)
   1137     grouping_vars = mark._grouping_props + default_grouping_vars
   1138     split_generator = self._setup_split_generator(
   1139         grouping_vars, df, subplots
   1140     )
-> 1142     mark._plot(split_generator, scales, orient)
   1144 # TODO is this the right place for this?
   1145 for view in self._subplots:

File ~/code/seaborn/seaborn/_marks/area.py:47, in AreaBase._plot(self, split_gen, scales, orient)
     44     kws[ax]["linestyle"].append(resolved["edgestyle"])
     46 for ax, ax_kws in kws.items():
---> 47     ax.add_collection(mpl.collections.PolyCollection(**ax_kws))

File ~/miniconda3/envs/seaborn-py39-latest/lib/python3.9/site-packages/matplotlib/axes/_base.py:2248, in _AxesBase.add_collection(self, collection, autolim)
   2244 if autolim:
   2245     # Make sure viewLim is not stale (mostly to match
   2246     # pre-lazy-autoscale behavior, which is not really better).
   2247     self._unstale_viewLim()
-> 2248     datalim = collection.get_datalim(self.transData)
   2249     points = datalim.get_points()
   2250     if not np.isinf(datalim.minpos).all():
   2251         # By definition, if minpos (minimum positive value) is set
   2252         # (i.e., non-inf), then min(points) <= minpos <= max(points),
   2253         # and minpos would be superfluous. However, we add minpos to
   2254         # the call so that self.dataLim will update its own minpos.
   2255         # This ensures that log scales see the correct minimum.

File ~/miniconda3/envs/seaborn-py39-latest/lib/python3.9/site-packages/matplotlib/collections.py:295, in Collection.get_datalim(self, transData)
    288         offsets = offsets.filled(np.nan)
    289     # get_path_collection_extents handles nan but not masked arrays
    290     # collections that are just in data units (like quiver)
    291     # can properly have the axes limits set by their shape +
    292     # offset.  LineCollections that have no offsets can
    293     # also use this algorithm (like streamplot).
    294     return mpath.get_path_collection_extents(
--> 295         transform.get_affine() - transData, paths,
    296         self.get_transforms(),
    297         transOffset.transform_non_affine(offsets),
    298         transOffset.get_affine().frozen())
    300 # NOTE: None is the default case where no offsets were passed in
    301 if self._offsets is not None:
    302     # this is for collections that have their paths (shapes)
    303     # in physical, axes-relative, or figure-relative units
    304     # (i.e. like scatter). We can't uniquely set limits based on
    305     # those shapes, so we just set the limits based on their
    306     # location.

File ~/miniconda3/envs/seaborn-py39-latest/lib/python3.9/site-packages/matplotlib/transforms.py:1470, in Transform.__sub__(self, other)
   1468 # if we have got this far, then there was no shortcut possible
   1469 if other.has_inverse:
-> 1470     return self + other.inverted()
   1471 else:
   1472     raise ValueError('It is not possible to compute transA - transB '
   1473                      'since transB cannot be inverted and there is no '
   1474                      'shortcut possible.')

File ~/miniconda3/envs/seaborn-py39-latest/lib/python3.9/site-packages/matplotlib/transforms.py:2452, in CompositeGenericTransform.inverted(self)
   2449 def inverted(self):
   2450     # docstring inherited
   2451     return CompositeGenericTransform(
-> 2452         self._b.inverted(), self._a.inverted())

File ~/miniconda3/envs/seaborn-py39-latest/lib/python3.9/site-packages/matplotlib/transforms.py:2452, in CompositeGenericTransform.inverted(self)
   2449 def inverted(self):
   2450     # docstring inherited
   2451     return CompositeGenericTransform(
-> 2452         self._b.inverted(), self._a.inverted())

File ~/miniconda3/envs/seaborn-py39-latest/lib/python3.9/site-packages/matplotlib/transforms.py:1890, in Affine2DBase.inverted(self)
   1888     if self._shorthand_name:
   1889         shorthand_name = '(%s)-1' % self._shorthand_name
-> 1890     self._inverted = Affine2D(inv(mtx), shorthand_name=shorthand_name)
   1891     self._invalid = 0
   1892 return self._inverted

File <__array_function__ internals>:180, in inv(*args, **kwargs)

File ~/miniconda3/envs/seaborn-py39-latest/lib/python3.9/site-packages/numpy/linalg/linalg.py:552, in inv(a)
    550 signature = 'D->D' if isComplexType(t) else 'd->d'
    551 extobj = get_linalg_error_extobj(_raise_linalgerror_singular)
--> 552 ainv = _umath_linalg.inv(a, signature=signature, extobj=extobj)
    553 return wrap(ainv.astype(result_t, copy=False))

File ~/miniconda3/envs/seaborn-py39-latest/lib/python3.9/site-packages/numpy/linalg/linalg.py:89, in _raise_linalgerror_singular(err, flag)
     88 def _raise_linalgerror_singular(err, flag):
---> 89     raise LinAlgError("Singular matrix")

LinAlgError: Singular matrix

Appears to be specific to the x scale, and not to the orient dimension.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions