has2k1 / plotnine

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

Using a ggplot figure as standard Matplotlib device #730

Closed lucazav closed 10 months ago

lucazav commented 10 months ago

I'm trying to inject the plot returned by the draw() method into the default Matplotlib device displayed using plt.show(). I need to do this because Power BI only uses the default device to display plots in Python. The code I'm using is as follows:

import matplotlib.pyplot as plt
import pandas as pd

from plotnine import (
    options, theme_tufte, ggplot, aes, geom_bar,
    geom_text, after_stat, labs
)

dataset_url = 'http://bit.ly/titanic-dataset-csv'
df = pd.read_csv(dataset_url)

p = (
        ggplot(df) 
        + aes(x='Pclass', fill="factor(Pclass)") 
        + geom_bar()
        + geom_text(
            aes(label = after_stat('count')),
            stat = 'count',
            nudge_x = -0.14,
            nudge_y = 0.125,
            va = 'bottom',
            size = 8
        )
        + geom_text(
            aes(label = after_stat('prop*100'), group=1),
            stat = 'count',
            nudge_x = 0.14,
            nudge_y = 0.125,
            va = 'bottom',
            format_string = '({:.1f}%)',
            size = 8
        )
        + labs(title='Passenger Count by Class',
               x='Class', y='Count', fill='Class')
        + theme_tufte()
)

mng = plt.get_current_fig_manager()
mng.figure = p.draw()

plt.show()

Unfortunately I get an empty plot:

image

Am I doing something wrong?

lucazav commented 10 months ago

I found that a simple print(p) works fine. So the complete working code is as follows:

import matplotlib.pyplot as plt
import pandas as pd

from plotnine import (
    options, theme_tufte, ggplot, aes, geom_bar,
    geom_text, after_stat, labs
)

dataset_url = 'http://bit.ly/titanic-dataset-csv'
df = pd.read_csv(dataset_url)

p = (
        ggplot(df) 
        + aes(x='Pclass', fill="factor(Pclass)") 
        + geom_bar()
        + geom_text(
            aes(label = after_stat('count')),
            stat = 'count',
            nudge_x = -0.14,
            nudge_y = 0.125,
            va = 'bottom',
            size = 8
        )
        + geom_text(
            aes(label = after_stat('prop*100'), group=1),
            stat = 'count',
            nudge_x = 0.14,
            nudge_y = 0.125,
            va = 'bottom',
            format_string = '({:.1f}%)',
            size = 8
        )
        + labs(title='Passenger Count by Class',
               x='Class', y='Count', fill='Class')
        + theme_tufte()
)

print(p)