【问题标题】:Changing color and marker of each point using seaborn jointplot使用 seaborn 联合图更改每个点的颜色和标记
【发布时间】:2020-12-04 03:31:40
【问题描述】:

我对@9​​87654321@ 稍微修改了这段代码:

import seaborn as sns
sns.set(style="darkgrid")

tips = sns.load_dataset("tips")
color = sns.color_palette()[5]
g = sns.jointplot("total_bill", "tip", data=tips, kind="reg", stat_func=None,
                  xlim=(0, 60), ylim=(0, 12), color='k', size=7)

g.set_axis_labels('total bill', 'tip', fontsize=16)

我得到了一个漂亮的图 - 但是,对于我的情况,我需要能够更改每个单独点的颜色和格式。

我尝试使用关键字markerstylefmt,但收到错误TypeError: jointplot() got an unexpected keyword argument

这样做的正确方法是什么?我想避免调用 sns.JointGrid 并手动绘制数据和边际分布。

【问题讨论】:

  • 也许我理解错了,但根据this answer,您不能将标记列表传递给plt.scatter,因此seaborn 包装器也不起作用。
  • 射击。我将不得不编辑它。也许可以在创建图形后清除点并单独绘制每个点
  • 最终并不太难。我所要做的就是g.ax_joint.cla() 清除绘制点的轴,然后使用您提到的答案绘制点。回归消失了,但我真的不需要那部分,只是边缘分布的点
  • 您能否回答您自己的问题以显示您的代码(然后接受它)?如果你能添加一张图片,这样以后的人可以作为参考,那就更好了:)

标签: python matplotlib seaborn


【解决方案1】:

解决这个问题与 matplotlib 几乎没有什么不同(用不同的标记和颜色绘制散点图),除了我想保持边缘分布:

import seaborn as sns
from itertools import product
sns.set(style="darkgrid")

tips = sns.load_dataset("tips")
color = sns.color_palette()[5]
g = sns.jointplot("total_bill", "tip", data=tips, kind="reg", stat_func=None,
                  xlim=(0, 60), ylim=(0, 12), color='k', size=7)

#Clear the axes containing the scatter plot
g.ax_joint.cla()

#Generate some colors and markers
colors = np.random.random((len(tips),3))
markers = ['x','o','v','^','<']*100

#Plot each individual point separately
for i,row in enumerate(tips.values):
    g.ax_joint.plot(row[0], row[1], color=colors[i], marker=markers[i])

g.set_axis_labels('total bill', 'tip', fontsize=16)

这给了我这个:

回归线现在消失了,但这就是我所需要的。

【讨论】:

  • plt.scatter 没有任何方法可以控制用于单个点的标记,所以这样的事情可能是您最好的选择,但您可以使用g.ax_joint.collections[0].set_visible(False) 而不是清除整个轴,这将保留回归线。
  • 奇怪的是,这只在指定标记时有效。没有它,它就不会绘制点!
  • 您怎么知道['x','o','v','^','&lt;'] 是可用的标记样式?我发现 Seaborn 文档难以浏览。 (编辑:我想我找到了?here
【解决方案2】:

接受的答案太复杂了。 plt.sca() 可用于以更简单的方式执行此操作:

import matplotlib.pyplot as plt
import seaborn as sns

tips = sns.load_dataset("tips")
g = sns.jointplot("total_bill", "tip", data=tips, kind="reg", stat_func=None,
                  xlim=(0, 60), ylim=(0, 12))


g.ax_joint.cla() # or g.ax_joint.collections[0].set_visible(False), as per mwaskom's comment

# set the current axis to be the joint plot's axis
plt.sca(g.ax_joint)

# plt.scatter takes a 'c' keyword for color
# you can also pass an array of floats and use the 'cmap' keyword to
# convert them into a colormap
plt.scatter(tips.total_bill, tips.tip, c=np.random.random((len(tips), 3)))

【讨论】:

  • 我建议跳过对plt.sca 的调用并直接使用轴对象:g.ax_joint.scatter(tips.total_bill, ...)。尽可能避免使用pyplot 状态机。
【解决方案3】:

您也可以直接在参数列表中精确它,这要归功于关键字:joint_kws(使用 seaborn 0.8.1 测试)。如果需要,您还可以使用marginal_kws 更改边缘的属性

所以你的代码变成了:

import seaborn as sns
colors = np.random.random((len(tips),3))
markers = (['x','o','v','^','<']*100)[:len(tips)]

sns.jointplot("total_bill", "tip", data=tips, kind="reg",
    joint_kws={"color":colors, "marker":markers})

【讨论】:

    【解决方案4】:
    1. seaborn/categorical.py 中,找到def swarmplot
    2. **kwargs之前添加参数marker='o'
    3. kwargs.update 中,添加marker=marker

    然后添加例如marker='x' 在使用 sns.swarmplot() 绘图时作为参数,就像使用 Matplotlib plt.scatter() 一样。

    刚遇到同样的需求,将marker 作为kwarg 不起作用。所以我看了一眼。我们可以用类似的方式设置其他参数。 https://github.com/ccneko/seaborn/blob/master/seaborn/categorical.py

    这里只需要做一点小改动,但这里是 GitHub 分叉页面供快速参考;)

    【讨论】:

      【解决方案5】:

      另一个选择是使用 JointGrid,因为jointplot 是一个简化其使用的包装器。

      import matplotlib.pyplot as plt
      import seaborn as sns
      
      tips = sns.load_dataset("tips")
      
      g = sns.JointGrid("total_bill", "tip", data=tips)
      g = g.plot_joint(plt.scatter, c=np.random.random((len(tips), 3)))
      g = g.plot_marginals(sns.distplot, kde=True, color="k")
      

      【讨论】:

        【解决方案6】:

        另外两个答案是复杂的奢侈(实际上,它们是由真正了解幕后情况的人提供的)。

        这是一个只是猜测的人的答案。但它确实有效!

        tips = sns.load_dataset("tips")
        g = sns.jointplot("total_bill", "tip", data=tips,
                      c=tips.day.cat.codes, cmap='Set1', stat_func=None,
                      xlim=(0, 60), ylim=(0, 12))
        

        【讨论】:

        • 我认为这行不通;我刚刚在 seaborn 0.7.1 中尝试了它并得到了 ValueError: Supply a 'c' kwarg or a 'color' kwarg but not both; they differ but their functionalities overlap. 如果 c 参数可以是一个集合,那该有多好,我不认为它可以。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-09-14
        • 1970-01-01
        • 2020-08-07
        • 2021-06-23
        • 2022-01-13
        • 2015-10-12
        相关资源
        最近更新 更多