seaborn
seaborn copied to clipboard
Passing scalar variable assignments in Plot.add should be possible
This works:
so.Plot(x=[1, 2, 3, 4], ymin=0, ymax=[1, 2, 3, 4]).add(so.Interval())
This fails:
so.Plot(x=[1, 2, 3, 4], ymax=[1, 2, 3, 4]).add(so.Interval(), ymin=0)
---------------------------------------------------------------------------
ValueError 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:232, in Plot._repr_png_(self)
230 def _repr_png_(self) -> tuple[bytes, dict[str, float]]:
--> 232 return self.plot()._repr_png_()
File ~/code/seaborn/seaborn/_core/plot.py:678, in Plot.plot(self, pyplot)
675 plotter = Plotter(pyplot=pyplot)
677 # Process the variable assignments and initialize the figure
--> 678 common, layers = plotter._extract_data(self)
679 plotter._setup_figure(self, common, layers)
681 # Process the scale spec for coordinate variables and transform their data
File ~/code/seaborn/seaborn/_core/plot.py:810, in Plotter._extract_data(self, p)
808 for layer in p._layers:
809 spec = layer.copy()
--> 810 spec["data"] = common_data.join(layer.get("source"), layer.get("vars"))
811 layers.append(spec)
813 return common_data, layers
File ~/code/seaborn/seaborn/_core/data.py:93, in PlotData.join(self, data, variables)
90 disinherit = [k for k, v in variables.items() if v is None]
92 # Create a new dataset with just the info passed here
---> 93 new = PlotData(data, variables)
95 # -- Update the inherited DataSource with this new information
97 drop_cols = [k for k in self.frame if k in new.frame or k in disinherit]
File ~/code/seaborn/seaborn/_core/data.py:57, in PlotData.__init__(self, data, variables)
51 def __init__(
52 self,
53 data: DataSource,
54 variables: dict[str, VariableSpec],
55 ):
---> 57 frame, names, ids = self._assign_variables(data, variables)
59 self.frame = frame
60 self.names = names
File ~/code/seaborn/seaborn/_core/data.py:260, in PlotData._assign_variables(self, data, variables)
255 ids[key] = id(val)
257 # Construct a tidy plot DataFrame. This will convert a number of
258 # types automatically, aligning on index in case of pandas objects
259 # TODO Note: this fails when variable specs *only* have scalars!
--> 260 frame = pd.DataFrame(plot_data)
262 return frame, names, ids
File ~/miniconda3/envs/seaborn-py39-latest/lib/python3.9/site-packages/pandas/core/frame.py:636, in DataFrame.__init__(self, data, index, columns, dtype, copy)
630 mgr = self._init_mgr(
631 data, axes={"index": index, "columns": columns}, dtype=dtype, copy=copy
632 )
634 elif isinstance(data, dict):
635 # GH#38939 de facto copy defaults to False only in non-dict cases
--> 636 mgr = dict_to_mgr(data, index, columns, dtype=dtype, copy=copy, typ=manager)
637 elif isinstance(data, ma.MaskedArray):
638 import numpy.ma.mrecords as mrecords
File ~/miniconda3/envs/seaborn-py39-latest/lib/python3.9/site-packages/pandas/core/internals/construction.py:502, in dict_to_mgr(data, index, columns, dtype, typ, copy)
494 arrays = [
495 x
496 if not hasattr(x, "dtype") or not isinstance(x.dtype, ExtensionDtype)
497 else x.copy()
498 for x in arrays
499 ]
500 # TODO: can we get rid of the dt64tz special case above?
--> 502 return arrays_to_mgr(arrays, columns, index, dtype=dtype, typ=typ, consolidate=copy)
File ~/miniconda3/envs/seaborn-py39-latest/lib/python3.9/site-packages/pandas/core/internals/construction.py:120, in arrays_to_mgr(arrays, columns, index, dtype, verify_integrity, typ, consolidate)
117 if verify_integrity:
118 # figure out the index, if necessary
119 if index is None:
--> 120 index = _extract_index(arrays)
121 else:
122 index = ensure_index(index)
File ~/miniconda3/envs/seaborn-py39-latest/lib/python3.9/site-packages/pandas/core/internals/construction.py:664, in _extract_index(data)
661 raise ValueError("Per-column arrays must each be 1-dimensional")
663 if not indexes and not raw_lengths:
--> 664 raise ValueError("If using all scalar values, you must pass an index")
666 elif have_series:
667 index = union_indexes(indexes)
ValueError: If using all scalar values, you must pass an index
(Incidentally, this specific plot should be possible with a Stem
mark that uses y
rather than ymin
/ymax
, but it demonstrates the point)