Home > OS >  How to map values on to a range in seaborn swarmplot?
How to map values on to a range in seaborn swarmplot?

Time:05-13

I have an array of 100 float values in the range [0, 1]. (min and max values are not necessarily 0 and 1)

I want to map them to a hue in the "icefire" color palette, in a swarmplot. In other words I want the data points, the dots, to have a hue based on the 100-val-array.

Now, I do not want the lowest value to map to the "lowest" color in the palette; I want the lowest value to map to the "corresponding" color in the palette.

Let's imagine the color palette just goes from [0, 1] as well, so in the case of "icefire", 0 is light blue and 1 is light red (icefire goes from light blue, to black in the middle, to light red).

With that in mind, if the minimum value in the 100-val-array is 0.27, then I want that value to map to the color 0.27, i.e., in the case of icefire, somewhere in the blues.

I hope I am making myself clear.

I have no idea how the "palette" parameter in swarmplot works, but it is not doing what I want.

The reason I need this is because the color of the data point is important, as it reflects the actual value in the 100-val-array.

I believe by just using swarmplot(..., palette="icefire"), that is not what happens.

CodePudding user response:

Unlike a scatter plot, Seaborn's swarmplot (currently?) doesn't use a vmin= and vmax= parameter. The swarmplot considers the hue mapping as categorical. You can simulate working with a colormap by creating a palette as a dictionary that maps every possible hue value to its corresponding color.

Here is how your example could look like:

import matplotlib.pyplot as plt
from matplotlib.cm import ScalarMappable
import seaborn as sns
import pandas as pd
import numpy as np

df = pd.DataFrame({'x': ['swarm 1'] * 100,
                   'y': np.random.normal(size=100),
                   'hue': np.random.uniform(0.27, 0.9, 100)})
cmap = sns.color_palette('icefire', as_cmap=True)
norm = plt.Normalize(vmin=0, vmax=1)  # 0 and 1 are the defaults, but you can adapt these to fit other uses
palette = {h: cmap(norm(h)) for h in df['hue']}

ax = sns.swarmplot(data=df, x='x', y='y', hue='hue', palette=palette)
ax.legend_.remove()  # remove the categorical legend
plt.colorbar(ScalarMappable(cmap=cmap, norm=norm), ax=ax)  # optionally add a colorbar
plt.show()

swarmplot with colormapped hue

  • Related