如何在 Seaborn 散点图图例中组合色调和样式组?
How can I combine hue and style groups in a Seaborn scatter plot legend?
我已经遵循了这个问题中的代码:。
我想更改图例,使样式和色调不是单独的列表,而是实际上组合在一起。
#practice dataset before applying to above
df = pd.DataFrame({"Sites" : ["Site 1","Site 1", "Site 2", "Site 2", "Site 3", "Site 3"],
"Depth" : ["a" , "b", "c", "d", "e", "f"],
"D/L_FAA" : [0.1 , 0.2, 0.3, 0.4, 0.5, 0.6],
"D/L_THAA" : [0.1 , 0.2, 0.3, 0.4, 0.5, 0.6]})
#creating dictionary for legend
dictionary = df.set_index("Depth")["Sites"].to_dict()
df['Subscale'] = df['Depth'].apply(lambda i: dictionary[i])
df['Subscale'] = pd.Categorical(df['Subscale']) # creates a fixed order
#create plot
ax = sns.scatterplot(data = df, x = "D/L_FAA", y = "D/L_THAA", style = "Depth",
hue = "Subscale", palette="colorblind", markers=True)
# create a dictionary mapping the subscales to their color
handles, labels = ax.get_legend_handles_labels()
index_depth_title = labels.index('Depth')
color_dict = {label: handles.get_color()
for handle, label in zip(handles[1:index_depth_title], labels[1:index_depth_title])}
# loop through the items, assign color via the subscale of the item idem
for handle, label in zip(handles[index_depth_title + 1:], labels[index_depth_title + 1:]):
handle.set_color(color_dict[dictionary[handle]])
# create a legend only using the items
ax.legend(handles[index_depth_title + 1:], labels[index_depth_title + 1:], title='Item',
bbox_to_anchor=(1.03, 1.02), fontsize=10)
plt.tight_layout()
plt.show()
我目前收到此错误:
AttributeError: 'list' object has no attribute 'get_color'
我不确定为什么我的代码无法正常工作,而问题中的代码可以正常工作。
如有任何帮助,我们将不胜感激。
谢谢,
艾莉
下面的代码做了如下改动:
- 将变量
dictionary
重命名为 depth_to_site_dict
- in
color_dict = {label: handles.get_color() ...}
:将handles
更改为handle
,将get_color
更改为get_facecolor()
(链接图使用了线图,在此代码中我们有散点图)
- 在
handle.set_color(color_dict[dictionary[handle]])
中:使用color_dict[depth_to_site_dict[label]]
from matplotlib import pyplot as plt
import seaborn as sns
import pandas as pd
import numpy as np
df = pd.DataFrame({"Sites": ["Site 1", "Site 1", "Site 2", "Site 2", "Site 3", "Site 3"],
"Depth": ["a", "b", "c", "d", "e", "f"],
"D/L_FAA": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6],
"D/L_THAA": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6]})
# creating dictionary for legend
depth_to_site_dict = df.set_index("Depth")["Sites"].to_dict()
df['Subscale'] = df['Depth'].map(depth_to_site_dict)
df['Subscale'] = pd.Categorical(df['Subscale']) # creates a fixed order
# create plot
ax = sns.scatterplot(data=df, x="D/L_FAA", y="D/L_THAA", style="Depth",
hue="Subscale", palette="colorblind", markers=True)
# create a dictionary mapping the subscales to their color
handles, labels = ax.get_legend_handles_labels()
index_depth_title = labels.index('Depth')
color_dict = {label: handle.get_facecolor()
for handle, label in zip(handles[1:index_depth_title], labels[1:index_depth_title])}
# loop through the items, assign color via the subscale of the item idem
for handle, label in zip(handles[index_depth_title + 1:], labels[index_depth_title + 1:]):
handle.set_color(color_dict[depth_to_site_dict[label]])
# create a legend only using the items
ax.legend(handles[index_depth_title + 1:], labels[index_depth_title + 1:], title='Item',
bbox_to_anchor=(1.03, 1.02), fontsize=10)
plt.tight_layout()
plt.show()
我已经遵循了这个问题中的代码:
我想更改图例,使样式和色调不是单独的列表,而是实际上组合在一起。
#practice dataset before applying to above
df = pd.DataFrame({"Sites" : ["Site 1","Site 1", "Site 2", "Site 2", "Site 3", "Site 3"],
"Depth" : ["a" , "b", "c", "d", "e", "f"],
"D/L_FAA" : [0.1 , 0.2, 0.3, 0.4, 0.5, 0.6],
"D/L_THAA" : [0.1 , 0.2, 0.3, 0.4, 0.5, 0.6]})
#creating dictionary for legend
dictionary = df.set_index("Depth")["Sites"].to_dict()
df['Subscale'] = df['Depth'].apply(lambda i: dictionary[i])
df['Subscale'] = pd.Categorical(df['Subscale']) # creates a fixed order
#create plot
ax = sns.scatterplot(data = df, x = "D/L_FAA", y = "D/L_THAA", style = "Depth",
hue = "Subscale", palette="colorblind", markers=True)
# create a dictionary mapping the subscales to their color
handles, labels = ax.get_legend_handles_labels()
index_depth_title = labels.index('Depth')
color_dict = {label: handles.get_color()
for handle, label in zip(handles[1:index_depth_title], labels[1:index_depth_title])}
# loop through the items, assign color via the subscale of the item idem
for handle, label in zip(handles[index_depth_title + 1:], labels[index_depth_title + 1:]):
handle.set_color(color_dict[dictionary[handle]])
# create a legend only using the items
ax.legend(handles[index_depth_title + 1:], labels[index_depth_title + 1:], title='Item',
bbox_to_anchor=(1.03, 1.02), fontsize=10)
plt.tight_layout()
plt.show()
我目前收到此错误:
AttributeError: 'list' object has no attribute 'get_color'
我不确定为什么我的代码无法正常工作,而问题中的代码可以正常工作。
如有任何帮助,我们将不胜感激。
谢谢,
艾莉
下面的代码做了如下改动:
- 将变量
dictionary
重命名为depth_to_site_dict
- in
color_dict = {label: handles.get_color() ...}
:将handles
更改为handle
,将get_color
更改为get_facecolor()
(链接图使用了线图,在此代码中我们有散点图) - 在
handle.set_color(color_dict[dictionary[handle]])
中:使用color_dict[depth_to_site_dict[label]]
from matplotlib import pyplot as plt
import seaborn as sns
import pandas as pd
import numpy as np
df = pd.DataFrame({"Sites": ["Site 1", "Site 1", "Site 2", "Site 2", "Site 3", "Site 3"],
"Depth": ["a", "b", "c", "d", "e", "f"],
"D/L_FAA": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6],
"D/L_THAA": [0.1, 0.2, 0.3, 0.4, 0.5, 0.6]})
# creating dictionary for legend
depth_to_site_dict = df.set_index("Depth")["Sites"].to_dict()
df['Subscale'] = df['Depth'].map(depth_to_site_dict)
df['Subscale'] = pd.Categorical(df['Subscale']) # creates a fixed order
# create plot
ax = sns.scatterplot(data=df, x="D/L_FAA", y="D/L_THAA", style="Depth",
hue="Subscale", palette="colorblind", markers=True)
# create a dictionary mapping the subscales to their color
handles, labels = ax.get_legend_handles_labels()
index_depth_title = labels.index('Depth')
color_dict = {label: handle.get_facecolor()
for handle, label in zip(handles[1:index_depth_title], labels[1:index_depth_title])}
# loop through the items, assign color via the subscale of the item idem
for handle, label in zip(handles[index_depth_title + 1:], labels[index_depth_title + 1:]):
handle.set_color(color_dict[depth_to_site_dict[label]])
# create a legend only using the items
ax.legend(handles[index_depth_title + 1:], labels[index_depth_title + 1:], title='Item',
bbox_to_anchor=(1.03, 1.02), fontsize=10)
plt.tight_layout()
plt.show()