Seaborn创建散点图与matplotlib有点不同.这样,散点图可以以更多的方式定制.对于图例,Seaborn 0.13使用自定义的Line2D
个元素(旧版本的Seaborn使用PathCollection
).
以下方法:
- 用一个等价的matplotlib范数替换Seaborn的
hue_norm=(0, 3)
- 创建虚拟
Line2D
个元素作为图例句柄
- 复制所有属性(大小、边缘 colored颜色 、...)Seaborn创建的图例句柄
- 然后根据规范和 colored颜色 映射改变标记 colored颜色
如果散点图不同,方法可能需要一些调整.该代码已经使用Matplotlib 3.8.3和Seaborn 0.13.2(和0.12.2)进行了测试.
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
from matplotlib.lines import Line2D
np.random.seed(123)
x = np.random.randn(500)
y = np.random.randn(500)
z = np.random.exponential(1, 500)
fig, ax = plt.subplots()
hue_norm = plt.Normalize(vmin=0, vmax=3)
sns.scatterplot(x=x, y=y, hue=z, hue_norm=hue_norm, palette='coolwarm', ax=ax)
legend_keys = [0, 1, 2, 3]
handles = [Line2D([], []) for _ in legend_keys]
cmap = plt.get_cmap('coolwarm')
for h, key in zip(handles, legend_keys):
if type(ax.legend_.legend_handles[0]) == Line2D:
h.update_from(ax.legend_.legend_handles[0])
else:
h.set_linestyle('')
h.set_marker('o')
h.set_markeredgecolor(ax.legend_.legend_handles[0].get_edgecolor())
h.set_markeredgewidth(ax.legend_.legend_handles[0].get_linewidth())
h.set_markerfacecolor(cmap(hue_norm(key)))
h.set_label(f'{key}')
ax.legend(handles=handles, title='z')
sns.despine()
plt.show()