seaborn jointplot 打印部分图例

seaborn jointplot prints partial legend

我对 seaborn jointplot 中的图例感到有些奇怪。我想为 8 个不同的数据集绘制一些数量 y 作为数量 x 的函数。这些数据集只有 xy 两列以及不同的行数。首先,我使用 numpy

连接所有数据集的所有行
y = np.concatenate(((data1[:,1]), (data2[:,1]), (data3[:,1]), (data4[:,1]),(data5[:,1]), (data6[:,1]), (data7[:,1]), (data8[:,1])), axis=0)
x = np.concatenate(((data1[:,0]), (data2[:,0]), (data3[:,0]), (data4[:,0]), (data5[:,0]), (data6[:,0]), (data7[:,0]), (data8[:,0])), axis=0)

然后我创建值数组,我将在联合图中将其用于参数“hue”,这将区分 legend/colors 中的几个数据集。我通过为每个数据集分配一个从 1 到 8 的数字来做到这一点,对累积数据集的每一行重复该数字:

indexes = np.concatenate((np.ones(len(data1[:,0])), 2*np.ones(len(data2[:,0])), 3*np.ones(len(data3[:,0])), 4*np.ones(len(data4[:,0])), 5*np.ones(len(data5[:,0])), 6*np.ones(len(data6[:,0])), 7*np.ones(len(data7[:,0])), 8*np.ones(len(data8[:,0]))), axis=0)

然后我创建数据集:

all_together = np.column_stack((x, y, indexes))
df = pd.DataFrame(all_together, columns = ['x','y','Dataset'])

现在我可以创建联合图了。这只需通过以下方式完成:

g = sns.jointplot(y="y", x="x", data=df, hue="Dataset", palette='turbo') 
handles, labels = g.ax_joint.get_legend_handles_labels()
g.ax_joint.legend(handles=handles, labels=['data1', 'data2', 'data3', 'data4', 'data5', 'data6', 'data7', 'data8'], fontsize=10)

在这一点上,问题是:所有点都被绘制出来(至少我认为),但图例只显示:data1、data2、data3、data4 和 data5。我不明白为什么它不显示其他三个标签,这样情节就很难阅读了。我已经检查过,累积数据集 df 的形状正确。有什么想法吗?

您可以添加legend='full'以获得完整的图例。默认情况下,sns.jointplot uses sns.scatterplot 用于中心图。 jointplot 未使用的关键字参数被发送到 scatterplot。图例参数可以是“auto”、“brief”、“full”或“False”。

来自文档:

如果“brief”,数字色调和大小变量将用均匀间隔值的样本表示。如果“已满”,则每个组都会在图例中获得一个条目。如果是“自动”,则根据级别数在简短或完整表示之间进行选择。如果为False,则不添加图例数据,也不绘制图例。

以下代码是用seaborn 0.11.2测试的:

import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import numpy as np

N = 200
k = np.repeat(np.arange(1, 9), N // 8)
df = pd.DataFrame({'x': 5 * np.cos(2 * k * np.pi / 8) + np.random.randn(N),
                   'y': 5 * np.sin(2 * k * np.pi / 8) + np.random.randn(N),
                   'Dataset': k})
g = sns.jointplot(y="y", x="x", data=df, hue="Dataset", palette='turbo', legend='full')
plt.show()