import pandas as pd
import plotnine as pn
# Create sample data
data = pd.DataFrame({
'year': [2020, 2021, 2022, 2023, 2020, 2021, 2022, 2023, 2020, 2021, 2022, 2023],
'values': [10, 15, 20, 25, 5, 8, 12, 18, 2, 4, 6, 8],
'category': ['Apple', 'Apple', 'Apple', 'Apple', 'Banana', 'Banana', 'Banana', 'Banana', 'Cherry', 'Cherry', 'Cherry', 'Cherry']
})
p = (
pn.ggplot(data, pn.aes(x='year', y='values', color='category')) +
pn.geom_point() +
pn.geom_line() +
pn.scale_color_manual(
values={
'Apple': 'red',
'Banana': 'yellow',
'Cherry': 'darkred'
},
breaks=['Cherry', 'Apple', 'Banana'] # Custom order
) +
pn.labs(title="Custom colors AND custom order") +
pn.theme_minimal()
)
p
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
File ~/miniforge3/envs/SRAgent_nb/lib/python3.12/site-packages/IPython/core/formatters.py:984, in IPythonDisplayFormatter.__call__(self, obj)
982 method = get_real_method(obj, self.print_method)
983 if method is not None:
--> 984 method()
985 return True
File ~/miniforge3/envs/SRAgent_nb/lib/python3.12/site-packages/plotnine/ggplot.py:141, in ggplot._ipython_display_(self)
134 def _ipython_display_(self):
135 """
136 Display plot in the output of the cell
137
138 This method will always be called when a ggplot object is the
139 last in the cell.
140 """
--> 141 self._display()
File ~/miniforge3/envs/SRAgent_nb/lib/python3.12/site-packages/plotnine/ggplot.py:181, in ggplot._display(self)
179 figure_size_px = self.theme._figure_size_px
180 buf = BytesIO()
--> 181 self.save(buf, format=save_format, verbose=False)
182 display_func = get_display_function(format, figure_size_px)
183 display_func(buf.getvalue())
File ~/miniforge3/envs/SRAgent_nb/lib/python3.12/site-packages/plotnine/ggplot.py:673, in ggplot.save(self, filename, format, path, width, height, units, dpi, limitsize, verbose, **kwargs)
624 def save(
625 self,
626 filename: Optional[str | Path | BytesIO] = None,
(...) 635 **kwargs: Any,
636 ):
637 """
638 Save a ggplot object as an image file
639
(...) 671 Additional arguments to pass to matplotlib `savefig()`.
672 """
--> 673 sv = self.save_helper(
674 filename=filename,
675 format=format,
676 path=path,
677 width=width,
678 height=height,
679 units=units,
680 dpi=dpi,
681 limitsize=limitsize,
682 verbose=verbose,
683 **kwargs,
684 )
686 with plot_context(self).rc_context:
687 sv.figure.savefig(**sv.kwargs)
File ~/miniforge3/envs/SRAgent_nb/lib/python3.12/site-packages/plotnine/ggplot.py:621, in ggplot.save_helper(self, filename, format, path, width, height, units, dpi, limitsize, verbose, **kwargs)
618 if dpi is not None:
619 self.theme = self.theme + theme(dpi=dpi)
--> 621 figure = self.draw(show=False)
622 return mpl_save_view(figure, fig_kwargs)
File ~/miniforge3/envs/SRAgent_nb/lib/python3.12/site-packages/plotnine/ggplot.py:286, in ggplot.draw(self, show)
283 self.theme.setup(self)
285 # Drawing
--> 286 self._draw_layers()
287 self._draw_panel_borders()
288 self._draw_breaks_and_labels()
File ~/miniforge3/envs/SRAgent_nb/lib/python3.12/site-packages/plotnine/ggplot.py:450, in ggplot._draw_layers(self)
446 """
447 Draw the main plot(s) onto the axes.
448 """
449 # Draw the geoms
--> 450 self.layers.draw(self.layout, self.coordinates)
File ~/miniforge3/envs/SRAgent_nb/lib/python3.12/site-packages/plotnine/layer.py:464, in Layers.draw(self, layout, coord)
462 for i, l in enumerate(self, start=1):
463 l.zorder = i
--> 464 l.draw(layout, coord)
File ~/miniforge3/envs/SRAgent_nb/lib/python3.12/site-packages/plotnine/layer.py:367, in layer.draw(self, layout, coord)
364 self.data = self.geom.handle_na(self.data)
365 # At this point each layer must have the data
366 # that is created by the plot build process
--> 367 self.geom.draw_layer(self.data, layout, coord, **params)
File ~/miniforge3/envs/SRAgent_nb/lib/python3.12/site-packages/plotnine/geoms/geom.py:292, in geom.draw_layer(self, data, layout, coord, **params)
290 panel_params = layout.panel_params[ploc]
291 ax = layout.axs[ploc]
--> 292 self.draw_panel(pdata, panel_params, coord, ax, **params)
File ~/miniforge3/envs/SRAgent_nb/lib/python3.12/site-packages/plotnine/geoms/geom_point.py:63, in geom_point.draw_panel(self, data, panel_params, coord, ax, **params)
52 def draw_panel(
53 self,
54 data: pd.DataFrame,
(...) 58 **params: Any,
59 ):
60 """
61 Plot all groups
62 """
---> 63 self.draw_group(data, panel_params, coord, ax, **params)
File ~/miniforge3/envs/SRAgent_nb/lib/python3.12/site-packages/plotnine/geoms/geom_point.py:77, in geom_point.draw_group(data, panel_params, coord, ax, **params)
75 for _, udata in data.groupby(units, dropna=False):
76 udata.reset_index(inplace=True, drop=True)
---> 77 geom_point.draw_unit(udata, panel_params, coord, ax, **params)
File ~/miniforge3/envs/SRAgent_nb/lib/python3.12/site-packages/plotnine/geoms/geom_point.py:94, in geom_point.draw_unit(data, panel_params, coord, ax, **params)
92 size = ((data["size"] + data["stroke"]) ** 2) * np.pi
93 linewidth = data["stroke"] * SIZE_FACTOR
---> 94 color = to_rgba(data["color"], data["alpha"])
95 shape = data["shape"].iloc[0]
97 # It is common to forget that scatter points are
98 # filled and slip-up by manually assigning to the
99 # color instead of the fill. We forgive.
File ~/miniforge3/envs/SRAgent_nb/lib/python3.12/site-packages/plotnine/_utils/__init__.py:613, in to_rgba(colors, alpha)
610 return "none"
612 if isinstance(alpha, (Sequence, pd.Series)):
--> 613 return [to_rgba_hex(c, a) for c, a in zip(colors, alpha)]
614 else:
615 return [to_rgba_hex(c, alpha) for c in colors]
File ~/miniforge3/envs/SRAgent_nb/lib/python3.12/site-packages/plotnine/_utils/__init__.py:598, in to_rgba.<locals>.to_rgba_hex(c, a)
595 return c
597 _has_alpha = has_alpha(c)
--> 598 c = to_hex(c, keep_alpha=_has_alpha)
600 if not _has_alpha:
601 arr = colorConverter.to_rgba(c, a)
File ~/miniforge3/envs/SRAgent_nb/lib/python3.12/site-packages/matplotlib/colors.py:548, in to_hex(c, keep_alpha)
532 def to_hex(c, keep_alpha=False):
533 """
534 Convert *c* to a hex color.
535
(...) 546 ``#rrggbb`` or ``#rrggbbaa`` hex color string
547 """
--> 548 c = to_rgba(c)
549 if not keep_alpha:
550 c = c[:3]
File ~/miniforge3/envs/SRAgent_nb/lib/python3.12/site-packages/matplotlib/colors.py:317, in to_rgba(c, alpha)
315 rgba = None
316 if rgba is None: # Suppress exception chaining of cache lookup failure.
--> 317 rgba = _to_rgba_no_colorcycle(c, alpha)
318 try:
319 _colors_full_map.cache[c, alpha] = rgba
File ~/miniforge3/envs/SRAgent_nb/lib/python3.12/site-packages/matplotlib/colors.py:394, in _to_rgba_no_colorcycle(c, alpha)
390 raise ValueError(
391 f"Invalid string grayscale value {orig_c!r}. "
392 f"Value must be within 0-1 range")
393 return c, c, c, alpha if alpha is not None else 1.
--> 394 raise ValueError(f"Invalid RGBA argument: {orig_c!r}")
395 # turn 2-D array into 1-D array
396 if isinstance(c, np.ndarray):
ValueError: Invalid RGBA argument: 'Banana'
Example:
Error: