has2k1 / plotnine

A Grammar of Graphics for Python
https://plotnine.org
MIT License
3.99k stars 213 forks source link

Passing None an aes color mapping value raises error #791

Closed machow closed 1 week ago

machow commented 4 months ago

plotnine's color aesthetic accepts NA-like values. In this case, NAs are colored grey, and sometimes there are special scale arguments to change the color of NA values, etc..

However, if a None is passed directly to aes, it raises an error:

# Works ----
# could also replace pd.Series(...) with np.nan, pd.NA, etc..
(
    ggplot(mpg2, aes("displ", "hwy", color=pd.Series([None])))
    + geom_point()
)

# Raises error ----
(
    ggplot(mpg2, aes("displ", "hwy", color=None))
    + geom_point()
)

Error:

```python File [~/.virtualenvs/plotnine-guide/lib/python3.9/site-packages/plotnine/layer.py:463](https://file+.vscode-resource.vscode-cdn.net/Users/machow/repos/plotnine-guide/~/.virtualenvs/plotnine-guide/lib/python3.9/site-packages/plotnine/layer.py:463), in Layers.compute_aesthetics(self, plot) [461](https://file+.vscode-resource.vscode-cdn.net/Users/machow/repos/plotnine-guide/~/.virtualenvs/plotnine-guide/lib/python3.9/site-packages/plotnine/layer.py:461) def compute_aesthetics(self, plot: ggplot): [462](https://file+.vscode-resource.vscode-cdn.net/Users/machow/repos/plotnine-guide/~/.virtualenvs/plotnine-guide/lib/python3.9/site-packages/plotnine/layer.py:462) for l in self: --> [463](https://file+.vscode-resource.vscode-cdn.net/Users/machow/repos/plotnine-guide/~/.virtualenvs/plotnine-guide/lib/python3.9/site-packages/plotnine/layer.py:463) l.compute_aesthetics(plot) File [~/.virtualenvs/plotnine-guide/lib/python3.9/site-packages/plotnine/layer.py:260](https://file+.vscode-resource.vscode-cdn.net/Users/machow/repos/plotnine-guide/~/.virtualenvs/plotnine-guide/lib/python3.9/site-packages/plotnine/layer.py:260), in layer.compute_aesthetics(self, plot) [253](https://file+.vscode-resource.vscode-cdn.net/Users/machow/repos/plotnine-guide/~/.virtualenvs/plotnine-guide/lib/python3.9/site-packages/plotnine/layer.py:253) def compute_aesthetics(self, plot: ggplot): [254](https://file+.vscode-resource.vscode-cdn.net/Users/machow/repos/plotnine-guide/~/.virtualenvs/plotnine-guide/lib/python3.9/site-packages/plotnine/layer.py:254) """ [255](https://file+.vscode-resource.vscode-cdn.net/Users/machow/repos/plotnine-guide/~/.virtualenvs/plotnine-guide/lib/python3.9/site-packages/plotnine/layer.py:255) Return a dataframe where the columns match the aesthetic mappings [256](https://file+.vscode-resource.vscode-cdn.net/Users/machow/repos/plotnine-guide/~/.virtualenvs/plotnine-guide/lib/python3.9/site-packages/plotnine/layer.py:256) [257](https://file+.vscode-resource.vscode-cdn.net/Users/machow/repos/plotnine-guide/~/.virtualenvs/plotnine-guide/lib/python3.9/site-packages/plotnine/layer.py:257) Transformations like 'factor(cyl)' and other [258](https://file+.vscode-resource.vscode-cdn.net/Users/machow/repos/plotnine-guide/~/.virtualenvs/plotnine-guide/lib/python3.9/site-packages/plotnine/layer.py:258) expression evaluation are made in here [259](https://file+.vscode-resource.vscode-cdn.net/Users/machow/repos/plotnine-guide/~/.virtualenvs/plotnine-guide/lib/python3.9/site-packages/plotnine/layer.py:259) """ --> [260](https://file+.vscode-resource.vscode-cdn.net/Users/machow/repos/plotnine-guide/~/.virtualenvs/plotnine-guide/lib/python3.9/site-packages/plotnine/layer.py:260) evaled = evaluate(self.mapping._starting, self.data, plot.environment) [261](https://file+.vscode-resource.vscode-cdn.net/Users/machow/repos/plotnine-guide/~/.virtualenvs/plotnine-guide/lib/python3.9/site-packages/plotnine/layer.py:261) evaled_aes = aes(**{str(col): col for col in evaled}) [262](https://file+.vscode-resource.vscode-cdn.net/Users/machow/repos/plotnine-guide/~/.virtualenvs/plotnine-guide/lib/python3.9/site-packages/plotnine/layer.py:262) plot.scales.add_defaults(evaled, evaled_aes) File [~/.virtualenvs/plotnine-guide/lib/python3.9/site-packages/plotnine/mapping/evaluation.py:251](https://file+.vscode-resource.vscode-cdn.net/Users/machow/repos/plotnine-guide/~/.virtualenvs/plotnine-guide/lib/python3.9/site-packages/plotnine/mapping/evaluation.py:251), in evaluate(aesthetics, data, env) [249](https://file+.vscode-resource.vscode-cdn.net/Users/machow/repos/plotnine-guide/~/.virtualenvs/plotnine-guide/lib/python3.9/site-packages/plotnine/mapping/evaluation.py:249) else: [250](https://file+.vscode-resource.vscode-cdn.net/Users/machow/repos/plotnine-guide/~/.virtualenvs/plotnine-guide/lib/python3.9/site-packages/plotnine/mapping/evaluation.py:250) msg = f"Do not know how to deal with aesthetic '{ae}'" --> [251](https://file+.vscode-resource.vscode-cdn.net/Users/machow/repos/plotnine-guide/~/.virtualenvs/plotnine-guide/lib/python3.9/site-packages/plotnine/mapping/evaluation.py:251) raise PlotnineError(msg) [253](https://file+.vscode-resource.vscode-cdn.net/Users/machow/repos/plotnine-guide/~/.virtualenvs/plotnine-guide/lib/python3.9/site-packages/plotnine/mapping/evaluation.py:253) # Using `type` preserves the subclass of pd.DataFrame [254](https://file+.vscode-resource.vscode-cdn.net/Users/machow/repos/plotnine-guide/~/.virtualenvs/plotnine-guide/lib/python3.9/site-packages/plotnine/mapping/evaluation.py:254) index = data.index if len(data.index) and evaled else None PlotnineError: "Do not know how to deal with aesthetic 'color'" ```

Note on None in other aesthetics

It looks like passing a None directly to an aesthetic mapping doesn't work for other aesthetics (e.g. aes(shape=None)). But this seems like it would be highly unusual for people to do.