lemonad
lemonad

Reputation: 4208

Incorrect marker sizes with Seaborn relplot and scatterplot relative to legend

I'm trying to understand how to get the legend examples to align with the dots plotted using Seaborn's relplot in a Jupyter notebook. I have a size (float64) column in my pandas DataFrame df:

sns.relplot(x="A", y="B", size="size", data=df)

The values in the size column are [0.0, -7.0, -14.0, -7.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 8.0, 2.0, 0.0, -4.0, 7.0, -4.0, 0.0, 0.0, 4.0, 0.0, 0.0, -3.0, 0.0, 1.0, 7.0] and as you can see, the minimum value is -14 and the maximum value is 8. It looks like the legend is aligned well with that. However, look at the actual dots plotted, there's a dot considerably smaller than the one corresponding to -16 in the legend. There's also no dot plotted as large as the 8 in the legend.

What am I doing wrong -- or is this a bug?

Example of sizes not occurring in the dataset

I'm using pandas 0.24.2 and seaborn 0.9.0.


Edit: Looking closer at the Seaborn relplot example:

relplot example

the smallest weight is 1613 but there's an orange dot to the far left in the plot that's smaller than the dot for 1500 in the legend. I think this points to this being a bug.

Upvotes: 0

Views: 2471

Answers (1)

ImportanceOfBeingErnest
ImportanceOfBeingErnest

Reputation: 339600

Not sure what seaborn does here, but if you're willing to use matplotlib alone, it could look like

import numpy as np; np.random.rand
import matplotlib.pyplot as plt
import pandas as pd

s = [0.0, -7.0, -14.0, -7.0, 0.0, 1.0, 0.0, 0.0, 0.0, -1.0, 0.0, 8.0, 2.0, 
     0.0, -4.0, 7.0, -4.0, 0.0, 0.0, 4.0, 0.0, 0.0, -3.0, 0.0, 1.0, 7.0]
x = np.linspace(0, 2*np.pi, len(s))
y = np.sin(x)
df = pd.DataFrame({"A" : x, "B" : y, "size" : s})

# calculate some sizes in points^2 from the initial values
smin = df["size"].min()
df["scatter_sizes"] = 0.25 * (df["size"] - smin + 3)**2
# state the inverse of the above transformation
finv = lambda y: 2*np.sqrt(y)+smin-3

sc = plt.scatter(x="A", y="B", s="scatter_sizes", data=df)
plt.legend(*sc.legend_elements("sizes", func=finv), title="Size")

plt.show()

enter image description here

More details are in the Scatter plots with a legend example.

Upvotes: 3

Related Questions