katosh · GitHub

Using stat_summary for a group that is a continouse value works but yields a continous color scale:

from plotnine import *
from sklearn import datasets
import pandas as pd
import numpy as np
from random import randint
iris = datasets.load_iris()
iris_melt = pd.DataFrame(iris.data, columns=iris.feature_names).melt()
iris_melt['group'] = [randint(1, 2) for i in range(iris_melt.shape[0])]
(ggplot(iris_melt) +
 aes('variable', 'value', group='group', color='group') +
 stat_summary(fun_y=np.median, geom='smooth'))

image

Making the group a category works if we use no colors:

iris_melt['group'] = iris_melt['group'].astype('category')
(ggplot(iris_melt) +
 aes('variable', 'value', group='group') +
 stat_summary(fun_y=np.median, geom='smooth'))

image

But using the the category as a color as well yields the following error:

(ggplot(iris_melt) +
 aes('variable', 'value', group='group', color='group') +
 stat_summary(fun_y=np.median, geom='smooth'))
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
~/Envs/noteEnv3/lib/python3.6/site-packages/IPython/core/formatters.py in __call__(self, obj)
    700                 type_pprinters=self.type_printers,
    701                 deferred_pprinters=self.deferred_printers)
--> 702             printer.pretty(obj)
    703             printer.flush()
    704             return stream.getvalue()
~/Envs/noteEnv3/lib/python3.6/site-packages/IPython/lib/pretty.py in pretty(self, obj)
    400                         if cls is not object \
    401                                 and callable(cls.__dict__.get('__repr__')):
--> 402                             return _repr_pprint(obj, self, cycle)
    403
    404             return _default_pprint(obj, self, cycle)
~/Envs/noteEnv3/lib/python3.6/site-packages/IPython/lib/pretty.py in _repr_pprint(obj, p, cycle)
    695     """A pprint that just redirects to the normal repr function."""
    696     # Find newlines and replace them with p.break_()
--> 697     output = repr(obj)
    698     for idx,output_line in enumerate(output.splitlines()):
    699         if idx:
~/Envs/noteEnv3/lib/python3.6/site-packages/plotnine/ggplot.py in __repr__(self)
     93         # in the jupyter notebook.
     94         if not self.figure:
---> 95             self.draw()
     96         plt.show()
     97         return '<ggplot: (%d)>' % self.__hash__()
~/Envs/noteEnv3/lib/python3.6/site-packages/plotnine/ggplot.py in draw(self, return_ggplot)
    186         # new frames knowing that they are separate from the original.
    187         with pd.option_context('mode.chained_assignment', None):
--> 188             return self._draw(return_ggplot)
    189
    190     def _draw(self, return_ggplot=False):
~/Envs/noteEnv3/lib/python3.6/site-packages/plotnine/ggplot.py in _draw(self, return_ggplot)
    217             if self.figure is not None:
    218                 plt.close(self.figure)
--> 219             raise err
    220
    221         if return_ggplot:
~/Envs/noteEnv3/lib/python3.6/site-packages/plotnine/ggplot.py in _draw(self, return_ggplot)
    209                 self._draw_facet_labels()
    210                 self._draw_labels()
--> 211                 self._draw_legend()
    212                 self._draw_title()
    213                 self._draw_watermarks()
~/Envs/noteEnv3/lib/python3.6/site-packages/plotnine/ggplot.py in _draw_legend(self)
    412         Draw legend onto the figure
    413         """
--> 414         legend_box = self.guides.build(self)
    415         if not legend_box:
    416             return
~/Envs/noteEnv3/lib/python3.6/site-packages/plotnine/guides/guides.py in build(self, plot)
    142             return
    143
--> 144         gboxes = self.draw(gdefs, plot.theme)
    145         bigbox = self.assemble(gboxes, gdefs, plot.theme)
    146         return bigbox
~/Envs/noteEnv3/lib/python3.6/site-packages/plotnine/guides/guides.py in draw(self, gdefs, theme)
    282             g.theme = theme
    283             g._set_defaults()
--> 284         return [g.draw() for g in gdefs]
    285
    286     def assemble(self, gboxes, gdefs, theme):
~/Envs/noteEnv3/lib/python3.6/site-packages/plotnine/guides/guides.py in <listcomp>(.0)
    282             g.theme = theme
    283             g._set_defaults()
--> 284         return [g.draw() for g in gdefs]
    285
    286     def assemble(self, gboxes, gdefs, theme):c
~/Envs/noteEnv3/lib/python3.6/site-packages/plotnine/guides/guide_legend.py in draw(self)
    314                 with suppress(IndexError):
    315                     data = gl.data.iloc[i]
--> 316                     da = gl.geom.draw_legend(data, da, gl.layer)
    317             drawings.append(da)
    318         themeable['legend_key'].append(drawings)
~/Envs/noteEnv3/lib/python3.6/site-packages/plotnine/geoms/geom_smooth.py in draw_legend(data, da, lyr)
     62         out : DrawingArea
     63         """
---> 64         if lyr.stat.params['se']:
     65             r = lyr.geom.params['legend_fill_ratio']
     66             bg = Rectangle((0, (1-r)*da.height/2),
KeyError: 'se'

The same happens if we use strings for the groups iris_melt['group'] = iris_melt['group'].astype('str'). Everything works however if we use geom='point' instead:

(ggplot(iris_melt) +
 aes('variable', 'value', group='group', color='group') +
 stat_summary(fun_y=np.median, geom='point'))

image
This works even when we ommit the group argument and use color only. The same does not hold true for the first example.

Read the original on github.com ↗