Home > Back-end >  Rounding the marker sizes to a given list of ranges
Rounding the marker sizes to a given list of ranges

Time:12-05

I have marker sizes varied based on a column in my geodataframe but I want the sizes in 5 groups. I don't want every value to have its own size, instead I'd like a range of values to have one marker size.

Here is the code:

fig, ax = mpl.pyplot.subplots(1, figsize = (10,10))

sns.scatterplot(
    data=fishpts_clip, x="Lon", y="Lat", color='Green', size='SpeciesCatch',
    sizes=(100, 300), legend="full"
)

plt.legend(loc='center left', bbox_to_anchor=(1.05, 0.5), ncol=1, title='Sizes')

This is what I got:

enter image description here

Instead, I'd like something like this:

enter image description here

CodePudding user response:

You could create an extra column with each of the values rounded up to one of the desired bounds. That new column can be used for the sizes and the hue. To update the legend, the values are located in the list of bounds; the value itself and the previous one form the new legend label.

The following code illustrates the concept from simplified test data.

import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import numpy as np
from scipy import interpolate

df = pd.DataFrame({'val': np.arange(1, 61),
                   'x': np.arange(60) % 10,
                   'y': np.arange(60) // 10 * 10})

fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(16, 5))

sns.scatterplot(data=df, x="x", y="y", hue='val', palette='flare',
                size='val', sizes=(100, 300), legend='full', ax=ax1)
sns.move_legend(ax1, loc='center left', bbox_to_anchor=(1.01, 0.5), ncol=6, title='Sizes')
ax1.set_title('using the given values')

# create an extra column with the values rounded up towards one of the bounds
bounds = [0, 5, 10, 20, 40, 60]
round_to_bound = interpolate.interp1d(bounds, bounds, kind='next', fill_value='extrapolate', bounds_error=False)
df['rounded'] = round_to_bound(df['val']).astype(int)

sns.scatterplot(data=df, x="x", y="y", hue='rounded', palette='flare',
                size='rounded', sizes=(100, 300), ax=ax2)
sns.move_legend(ax2, loc='center left', bbox_to_anchor=(1.01, 0.5), ncol=1, title='Sizes')
for t in ax2.legend_.texts:
     v = int(t.get_text())
     t.set_text(f"{bounds[bounds.index(v) - 1]} - {v}")
ax2.set_title('rounding up the values towards given bounds')
sns.despine()
plt.tight_layout()
plt.show()

sns.scatterplot with list of sizes

  • Related