【问题标题】:Map data points to colormap with seaborn.swarmplot使用 seaborn.swarmplot 将数据点映射到颜色图
【发布时间】:2017-04-10 10:08:49
【问题描述】:

我想生成一个 seaborn.swarmplot,其中单个数据点的颜色映射到颜色图。

我有一个类似这样的 DataFrame:

In[48]:df
Out[48]: 
      a  c   Key
   0  1  12  1st
   1  4  35  2nd
   2  5  12  2nd
   3  6  46  1st
   4  3  78  1st
   5  4  45  2nd
   6  5  34  1st
   7  6  70  2nd

我使用以下代码生成了一个 swarmplot:

sns.swarmplot(x='Key', y = 'a',  s=20, data = df)

得到这样的情节:

Swarmplot

现在,我希望将数据点映射到颜色图,该颜色图将根据 DataFrame 的“c”列表示值。

我尝试在代码中添加 'hue = 'c' 并得到以下结果:

sns.swarmplot(x='Key', y = 'a',  hue='c',s=20, data = df)

Swarmplot with 'hue'

这种类型进入了我想要的方向,但我更喜欢将颜色映射到颜色映射,这样低 'c' 值将是例如浅绿色,而 ' c' 值越深,绿色越深。

作为一个传奇,我想要一个渐变。

非常感谢您的帮助!!!

【问题讨论】:

    标签: python pandas matplotlib seaborn


    【解决方案1】:

    没有颜色条的解决方案

    没有颜色条的解决方案相当简单。您需要创建一个颜色的palette(颜色与值一样多)并使用palette 参数将其提供给swarmplot。

    import pandas as pd
    import matplotlib.pyplot as plt
    import seaborn as sns
    print sns.__version__ # swarmplot requires version 0.7.1
    
    # Reconstruct the dataframe from the question (the hardest part)
    a = [1,4,5,6,3,4,5,6]
    c = [12,35,12,46,78,45,34,70]
    key = [1,2,2,1,1,2,1,2]
    key = ["{k}{a}".format(k=k, a={1:"st", 2:"nd"}[k]) for k in key]
    df  =pd.DataFrame({"a":a, "c":c, "Key":key})
    
    palette = sns.light_palette("seagreen", reverse=False,  n_colors=len(c) )
    sns.swarmplot(x='Key', y = 'a',  hue='c',s=20, data = df, palette=palette)
    
    plt.show()
    


    颜色条解决方案

    使用颜色条的解决方案需要更多的工作。 我们需要从 seaborn 调色板构造一个颜色图,标准化这个颜色图并创建一个颜色字典,对应于来自 df["c"] 数据框列的相应颜色。然后我们再次使用palette 关键字将这个字典提供给swarmplot。

    我们还需要移除自动生成但无用的图例,然后在绘图中创建一个新轴以放置颜色条。

    import pandas as pd
    
    import matplotlib.pyplot as plt
    import matplotlib.colorbar
    import matplotlib.colors
    import matplotlib.cm
    from mpl_toolkits.axes_grid1 import make_axes_locatable
    
    import seaborn as sns
    
    # recreate the dataframe
    a = [1,4,5,6,3,4,5,6]
    c = [12,35,12,46,78,45,34,70]
    key = [1,2,2,1,1,2,1,2]
    key = ["{k}{a}".format(k=k, a={1:"st", 2:"nd"}[k]) for k in key]
    df  =pd.DataFrame({"a":a, "c":c, "Key":key})
    
    #Create a matplotlib colormap from the sns seagreen color palette
    cmap    = sns.light_palette("seagreen", reverse=False, as_cmap=True )
    # Normalize to the range of possible values from df["c"]
    norm = matplotlib.colors.Normalize(vmin=df["c"].min(), vmax=df["c"].max())
    # create a color dictionary (value in c : color from colormap) 
    colors = {}
    for cval in df["c"]:
        colors.update({cval : cmap(norm(cval))})
    
    #create a figure
    fig = plt.figure(figsize=(5,2.8))
    #plot the swarmplot with the colors dictionary as palette
    m = sns.swarmplot(x='Key', y = 'a',  hue="c", s=20, data = df, palette = colors)
    # remove the legend, because we want to set a colorbar instead
    plt.gca().legend_.remove()
    
    ## create colorbar ##
    divider = make_axes_locatable(plt.gca())
    ax_cb = divider.new_horizontal(size="5%", pad=0.05)
    fig.add_axes(ax_cb)
    cb1 = matplotlib.colorbar.ColorbarBase(ax_cb, cmap=cmap,
                                    norm=norm,
                                    orientation='vertical')
    cb1.set_label('Some Units')
    plt.show()
    

    【讨论】:

    • 太棒了!非常感谢,搞清楚颜色条的代码可能需要我三天时间!
    • @Ozzycalifornia:如果你觉得这个答案有用,你可以投票。
    • 我做到了,但我的声誉太低了。它说,正在记录赞成票,但未显示。抱歉,再次感谢一百万!
    • 小问题:(为什么?)是否需要重新格式化“Key”列?我不明白它改变了什么。如果你有时间,一个非常短的回应会很棒!再次感谢!!
    • 在您的代码中,Key 列包含类似'1st' 的字符串。因为我手头没有您的数据框,所以我需要自己编写它,这对我来说是最简单的方法。这实际上只是为了获得与您已经拥有的相同的数据帧,因此无需担心。如果需要,您当然可以直接在列表中输入字符串。
    猜你喜欢
    • 2013-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-04
    • 1970-01-01
    • 2012-03-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多