使用seaborn jointplot更改每个点的颜色和标记

19

我对来自这里的代码进行了微小修改:

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并手动绘制数据和边缘分布..


也许我误解了,但根据这个答案,你不能将标记列表传递给plt.scatter,因此seaborn包装器也无法使用。 - cd98
拍摄。我得编辑一下。也许在创建图形后清除点并逐个绘制每个点是可能的。 - pbreach
最终结果并不太难。我所要做的就是使用g.ax_joint.cla()来清除绘制点的坐标轴,然后使用你提到的答案来绘制这些点。回归已经消失了,但我实际上也不需要那部分,只需要带有边缘分布的点即可。 - pbreach
请问您能否展示您的代码并回答自己的问题(然后接受它)?如果您能添加一张图片,那就更好了,这样未来的人们就可以将其作为参考 :) - cd98
6个回答

26
解决这个问题与使用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)

这使我得到了这个:

在此输入图像描述

回归线现在已经消失了,但这正是我需要的。


7
plt.scatter没有任何方式控制每个点使用的标记,因此像这样的做法可能是您最好的选择,但您可以执行g.ax_joint.collections[0].set_visible(False)而不是清除整个Axes,这将保留回归线。 - mwaskom
奇怪的是,只有在指定标记时才能正常工作。如果没有指定,它将无法绘制点! - Aku
你是怎么知道['x','o','v','^','<']是可用的标记样式的?我发现Seaborn文档很难浏览。(编辑:我想我在这里找到了它:https://matplotlib.org/3.1.1/api/markers_api.html#module-matplotlib.markers) - dumbledad

17

被采纳的答案太复杂了。可以使用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)))

4
建议跳过对 plt.sca 的调用,直接使用轴对象:g.ax_joint.scatter(tips.total_bill, ...)。尽可能避免使用 pyplot 状态机。 - Paul H

4
您也可以直接在参数列表中使用关键词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})

2
  1. seaborn/categorical.py中找到def swarmplot
  2. **kwargs之前添加参数marker='o'
  3. kwargs.update中添加marker=marker

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

我也遇到了同样的需求,但将marker作为kwarg并没有起作用。所以我简单地看了一下,在类似的方式下我们可以设置其他参数。 https://github.com/ccneko/seaborn/blob/master/seaborn/categorical.py

这里只需要做一个小改动,但这是GitHub forked页面的快速参考 ;)


1
另一个选择是使用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")

-2
另外两个答案是复杂的奢侈品(实际上,它们是由真正理解底层情况的人提供的)。
这是一个猜测的答案。但它确实有效!
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))

1
我认为这个不起作用;我刚在 seaborn 0.7.1 中尝试了一下,得到了 ValueError: Supply a 'c' kwarg or a 'color' kwarg but not both; they differ but their functionalities overlap. 尽管如果 c 参数可以是一个集合的话会很好,但我认为它不行。 - Nelson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接