RamsesII
RamsesII

Reputation: 549

How to plot matching filled and empty markers in Python's plotnine / matplotlib?

I'm using Python's plotnine package to plot some grouped data, similarly as one would do in R's ggplot2 package. So far, I'm grouping by color and shape. Now, I want to additionally plot filled vs. unfilled shapes/markers. Since plotnine's shapes are based on matplotlib's markers, I cannot find any matching pairs of markers, e.g., unfilled vs. filled squares, circles or triangles...

Here's my code incl. some example data and the current plot:

import pandas as pd
import numpy as np
from plotnine import *

# create data
df = pd.DataFrame({
        'Data': [x for x in ['Data 1', 'Data 2'] for i in range(6)],
        'Group': ['G1', 'G1', 'G2', 'G2', 'G3', 'G3'] * 2,
        'Method': ['M1', 'M2'] * 6,
        'value_1': np.random.rand(12),
        'value_2': np.random.rand(12)
})

# plot
(
ggplot(df, aes(x = 'value_1', y = 'value_2', color = 'Method', shape = 'Group')) +
geom_point(size = 5, alpha = 0.75) +
scale_x_continuous(name = 'Value 1') +
scale_y_continuous(name = 'Value 2') +
scale_color_manual(values = ['blue', 'green'] * 3) +
facet_grid('~Data') +
theme_bw() +
theme(axis_title_x = element_text(size = 12),
      axis_text_x = element_text(size = 10, angle = 45),
      axis_title_y = element_text(size = 12),
      axis_text_y = element_text(size = 10),
      strip_text_x = element_text(size = 10),
      legend_title = element_text(size = 12),
      legend_text = element_text(size = 10))
)

enter image description here

What I want is that all markers from Method 1 are filled (as they are now) while all markers from Method 2 are unfilled (or striped or s.th. else). Everything else should stay as it is. Somehow I don't manage to get there...

Any help is highly appreciated!

Upvotes: 1

Views: 1053

Answers (1)

Z-Y.L
Z-Y.L

Reputation: 1779

There is a workround if you want to get unfilled markers for Methed 2. Just add a fill mapping and specify the fill color of Method 2 to be transparent (set alpha to zero by using RGBA string).

(
ggplot(df, aes(x = 'value_1', y = 'value_2', shape = 'Group',color='Method', fill='Method')) +  # Add fill mapping
geom_point(size = 5, alpha = 0.75) +
scale_x_continuous(name = 'Value 1') +
scale_y_continuous(name = 'Value 2') + 
scale_fill_manual(values = ['blue', '#ffffff00'] * 3) +  # Add this
scale_color_manual(values = ['blue', 'green'] * 3) +
facet_grid('~Data') +
theme_bw() +
theme(axis_title_x = element_text(size = 12),
      axis_text_x = element_text(size = 10, angle = 45),
      axis_title_y = element_text(size = 12),
      axis_text_y = element_text(size = 10),
      strip_text_x = element_text(size = 10),
      legend_title = element_text(size = 12),
      legend_text = element_text(size = 10))
)

This is the obtained figure:

enter image description here

Upvotes: 2

Related Questions