Search code examples
pythonmatplotlibdata-visualizationseabornswarmplot

Swarmplot "gradient"


I want to plot a swarmplot like this

enter image description here

I can highlight the specific point. But I want all the points get kind of the colormap. And the specific point has the respectively color. I'm trying hue and palette but it does not work.

palette = sns.light_palette("purple", reverse=False,  n_colors=df[typeId].max())
ax = sns.swarmplot(x = df[typeId], ax = ax, hue = df[typeId], alpha = 0.8, size = 8)
axData = ax.get_children()
for a in axData:
    if type(a) is matplotlib.collections.PathCollection:
        offsets = a.get_offsets()
        break
ax.scatter(offsets[index,0], offsets[index,1], marker='o', color='red', zorder=10, s=200, edgecolor = "white")
ax.text(offsets[index,0], offsets[index,1]-0.1,"Value: " + str(player[typeId]) + "\nPercentile rank: " + str("{0:.2f}".format(player[typeRank]*100)), ha = "center", color = "white", zorder = 9, fontproperties=prop_bold,fontsize=10)

enter image description here


Solution

  • It seems that when no y= is given, swarmplot() doesn't take the hue= parameter into account. (And when y is a constant, the code seems to hang.)

    A workaround is to set the color manually:

    import matplotlib.pyplot as plt
    import matplotlib
    import seaborn as sns
    import numpy as np
    
    type_ids = np.random.binomial(200, 0.7, 500)
    ax = plt.gca()
    
    plt.style.use("dark_background")
    ax = sns.swarmplot(x=type_ids, ax=ax, size=8)
    for a in ax.get_children():
        if type(a) is matplotlib.collections.PathCollection:
            offsets = a.get_offsets()
            cmap = sns.light_palette("purple", reverse=False, as_cmap=True)
            norm = plt.Normalize(vmin=offsets[:,0].min(), vmax=offsets[:,0].max())
            facecolors = [cmap(norm(x)) for x, y in offsets]
            a.set_color(facecolors)
            break
    index = 20
    ax.scatter(offsets[index, 0], offsets[index, 1], marker='o', color='red', zorder=10, s=200, edgecolor="white")
    ax.text(offsets[index, 0], offsets[index, 1] - 0.1, "\nPercentile rank:  ...",
            ha="center", color="white", zorder=9, fontsize=10)
    plt.show()
    

    resulting plot