pythonmatplotlibplotseaborn

Variable markersize in seaborn pointplot


I would like to vary the marker size in my seaborn pointplot according to a numpy array representing the sample size.

markersize_array = np.array([[10, 5, 6]])

Feeding markersize_array to the markersize keyword produces an error:

TypeError: only length-1 arrays can be converted to Python scalars

Here is some example code:

penguins = sns.load_dataset("penguins")

fig, ax = plt.subplots(1, 1, figsize=(2, 2))

markersize_array = np.array([[10, 5, 6]])

sns.pointplot(
    data=penguins,
    x="body_mass_g",
    y="island",
    ax=ax,
    estimator=np.mean,
    errorbar=('ci', 95),
    capsize=0,
    color="k",
    log_scale=False,
    linestyle="none",
    marker="s",
    markersize=np.array([[5]]),
    # markersize=markersize_array,  # <- I need this
)

Is there a way to make this happen?

Constant Marker Size

Edit

Using seaborn objects also does not work:

import seaborn.objects as so

tips = sns.load_dataset("tips")

p1 = so.Plot(tips, "total_bill", "tip")
p1.add(so.Dot())
(
    so.Plot(tips, x="total_bill", y="day")
    .add(so.Dot(pointsize=np.array(10)), so.Agg())
    # .add(so.Dot(pointsize=np.array([[10, 10, 10, 10]])), so.Agg())
    .add(so.Range(), so.Est(errorbar=("se", 2)))
)

Solution

  • Maybe you can set the marker to "none" and use plt.scatter afterwards to draw the points at the right sizes.

    pointplot

    import matplotlib.pyplot as plt
    import numpy as np
    import seaborn as sns
    
    penguins = sns.load_dataset("penguins")
    x = "body_mass_g"
    y = "island"
    
    fig, ax = plt.subplots(figsize=(6, 4))
    
    # Error bars
    sns.pointplot(
        data=penguins,
        x=x,
        y=y,
        estimator="mean",
        errorbar=("ci", 95),
        capsize=0,
        color="k",
        ls="none",
        marker="s",  # "none" here
        ax=ax,
    )
    
    # Central points with variable sizes
    means = penguins.groupby(y)[x].mean()
    markersize_array = np.array([10, 5, 6])
    ax.scatter(
        x=means.values,
        y=means.index,
        s=markersize_array * 40,
        color="green",
        marker="s",
        alpha=0.5,
    )
    
    
    fig.tight_layout()
    fig.show()