问题描述
我在为散点图标记着色时遇到了一些问题。我有一个带有值“pos”和另外两个值“af_min”和“af_max”的简单数据框。我想根据 af_x 和 af_y 的某些条件为标记着色,但由于我没有任何可用作色调的列,因此我创建了自己的列“颜色”。
pos af_x af_y color
0 3671023 0.200000 0.333333 2.0
1 4492071 0.176471 0.333333 2.0
2 4492302 0.222222 0.285714 2.0
3 4525905 0.298246 0.234043 2.0
4 4520905 0.003334 0.234043 1.0
5 4520905 0.400098 0.000221 0.0
6 4520905 0.001134 0.714043 1.0
7 4520905 0.559008 0.010221 0.0
现在,我以这种方式使用 seaborn 和 seaborn 调色板创建散点图:
sns.scatterplot(data = df,x="af_x",y="af_y",hue="color",palette = "hsv",s=40,legend=False)
但结果如下:如您所见,一种色调没有被着色,因为只有两种颜色,蓝色和红色。 。
现在发生了一些非常奇怪的事情:为了解决这个问题,我建立了自己的调色板广告,将它添加到了 seaborn 中。但是散点图不是用我选择的阴影着色,而是用我前段时间在另一个脚本中使用的一些颜色着色,并且无法更改它们。这里的情节: 这是代码:
#violet #green #orange
colors = ['#747FE3','#8EE35D','#E37346']
sns.set_palette(sns.color_palette(colors))
sns.scatterplot(data = df,legend=False)
我把整个脚本放在这里,你可以复制它:
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
lst = [[3671023,0.200000,0.333333],[4492071,0.176471,[4492302,0.222222,0.285714],[4525905,0.298246,0.234043],[4520905,0.003334,0.400098,0.000221],0.001134,0.714043],0.559008,0.010221]
]
df = pd.DataFrame(lst,columns =['pos','af_x','af_y'])
afMin=0.1
afMax=0.9
df['color']=np.nan
for index in df.index:
afx=df.loc[index,"af_x"]
afy=df.loc[index,"af_y"]
if ((afx >= afMin and afx <= afMax) and (afy < afMin or afy > afMax)):
df.loc[index,"color"] = 0
elif ((afy >= afMin and afy <= afMax) and (afx < afMin or afx > afMax)):
df.loc[index,"color"] = 1
elif ((afy >= afMin and afy <= afMax) and (afx >= afMin or afx <= afMax)):
df.loc[index,"color"] = 2
sns.scatterplot(data = df,legend=False)
plt.savefig("stack_why_hsv.png")
#violet #green #orange
colors = ['#747FE3','#E37346']
sns.set_palette(sns.color_palette(colors))
sns.scatterplot(data = df,legend=False)
plt.savefig("stack_why_personal.png")
感谢任何可以提供帮助的人!
解决方法
您的第一个示例的问题在于 hsv
调色板在其开始和结束时具有相同的颜色。这是因为 "hsv" 中的“h”是一个圆形变量,从 0 到 360 度。 Matplotlib 默认使用 3 种颜色,在颜色范围内均匀分布,因此从一开始就使用红色,从中心使用青色,再从结尾使用红色。因此,在这种情况下,hsv
不是最合适的配色方案。请参阅 matplotlib's available colormaps 和 seaborn's extensions。
对于您的第二个示例,sns.set_palette()
设置了 matplotlib 的颜色循环,但 seaborn 本身并不总是使用它。当给出数字色调时,seaborn default 默认选择 rocket
颜色图。来自documentation:
色调的默认处理(以及较小程度上的大小) 语义(如果存在)取决于变量是否被推断为 表示“数字”或“分类”数据。尤其是数字 默认情况下,变量用顺序颜色图表示,并且 图例条目显示常规“刻度”,其值可能或可能 数据中不存在。
使用自定义调色板的最简单方法是直接将其提供给函数(无需调用 sns.color_palette()
,因为 seaborn 调色板在内部只是颜色列表):
colors = ['#747FE3','#8EE35D','#E37346']
sns.scatterplot(data = df,x="af_x",y="af_y",hue="color",palette=colors,s=40)
PS:set_palette
在色调是分类时使用 scatterplot
。这是一个例子。我还添加了 preferred way to set values to a selection of rows;这对于大型数据框很重要。请注意,数组上的布尔运算在这里需要相当多的括号。
afMin = 0.1
afMax = 0.9
df['color'] = ""
afx = df["af_x"]
afy = df["af_y"]
df.loc[((afx >= afMin) & (afx <= afMax) & ((afy < afMin) | (afy > afMax))),"color"] = "a"
df.loc[((afy >= afMin) & (afy <= afMax) & ((afx < afMin) | (afx > afMax))),"color"] = "b"
df.loc[((afy >= afMin) & (afy <= afMax) & (afx >= afMin) & (afx <= afMax)),"color"] = "c"
colors = ['#747FE3','#E37346']
sns.set_palette(sns.color_palette(colors))
sns.scatterplot(data=df,s=40)