has2k1 / plotnine

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

theme_minimal crops out facet labels (not happening with other themes) #760

Closed jwhendy closed 4 months ago

jwhendy commented 4 months ago

Hello, I've never run into this before so I'm suspecting it's some kind of regression. Here's a repro:

import pandas as pd
from plotnine import * 

foo = pd.DataFrame({'label': ['a', 'a', 'b', 'b'],
                    'x': [0, 1, 2, 3],
                    'y': [4, 5, 6, 7]})

By default we get:

p = ggplot(foo, aes(x='x', y='y', group=1)) + geom_line()
p = p + facet_wrap('~label')
p
image

And trying a few others:

p + theme_bw()
image
p + theme_dark()
image

However with theme_minimal() the facet labels are removed. You can try this without the additional plot background arguments to theme(), but the result is the same. I'm including it so it's white and easily seen vs. the default transparent bg:

p + theme_minimal() + theme(plot_background=element_rect(fill='white'))
image
has2k1 commented 4 months ago

The problem is

theme(strip_background=element_blank())

removes the box around the facet labels. The layout manager uses the box to account for the space taken by the labels.

jwhendy commented 4 months ago

Is it a dumb/hacky fix to adjust L28 to specify a transparent strip_background vs. fixing via the layout manager (which to my unfamiliar ear, sounds much more involved)?

Googling around, it seems transparency can be specified in RGB codes like #AARRGGBB, as long as the backend will accept the additional alpha parameter. Having found that, I tried this and it works:

p = ggplot(foo, aes(x='x', y='y', group=1)) + geom_line()
p = p + facet_wrap('~label')
p = p + theme_minimal()
p = p + theme(strip_background=element_rect(fill="#00000000", color="#00000000"))
p
image

Showing here with an additional theme arg so things are not transparent:

p = p + theme(plot_background=element_rect(fill="white"))
p
image

Not sure if there are other byproducts of setting strip_background to an element_rect vs. element_blank...

has2k1 commented 4 months ago

Is it a dumb/hacky fix to adjust L28 to specify a transparent strip_background vs. fixing via the layout manager (which to my unfamiliar ear, sounds much more involved)?

This is a real bug based on a wrong assumption, and requires fixing it in the layout manager has to be fixed. I have a working solution and I'll make a release on Friday.

In the meantime, you should be able to use theme(strip_background=element_rect(fill="none", color="none"))