使用 for 循环绘图时,如何跳过图例中的重复标签?

Posted

技术标签:

【中文标题】使用 for 循环绘图时,如何跳过图例中的重复标签?【英文标题】:How can I skip repeated lablels in the legend when I plot using a for-loop? 【发布时间】:2021-01-03 13:32:45 【问题描述】:
import pandas as pd
import matplotlib.pyplot as plt
from random import random

DF = "A":[(random(),random()),(random(),random())],
      "B":[(random(),random()),(random(),random())],
      "C":[(random(),random()),(random(),random())],
      "D":[(random(),random()),(random(),random())]
DF = pd.DataFrame(DF, index=["k=1","k=2"])

我的数据框的每一行都包含一个重复实验的观察结果,每一列代表一组受试者。条目是男性基准和女性基准的元组。所以我想绘制针对群体的观察结果,通过标记形状和颜色来区分性别。我尝试了以下方法,但它产生了太长的传说。 如何只显示两个标签(男、女)?

plt.figure()
for row in DF.index:
    plt.plot(DF.columns, [a for a,b in DF.loc[row,]], 'b.', label="Male")
    plt.plot(DF.columns, [b for a,b in DF.loc[row,]], 'g+', label="Female")
plt.legend(loc="upper right")
plt.show()

顺便说一句,由于值相当接近,我可以在每个点的 x 坐标上添加一点随机噪声(如 R 中的抖动),以便它们更容易辨别吗? p>

【问题讨论】:

您的代码似乎没有运行。 @QuangHoang 对不起。我相信现在可以了。 【参考方案1】:

一个快速的解决方案是只为第一行添加标签。

要向 x 位置添加抖动,您可以遍历生成的元素,获取它们的 x 位置,添加一些随机值并将它们放回去。由于当前距离为 1,添加一个介于 -0.4 和 0.4 之间的数字应该可以。 x轴的限制需要通过relimautoscale重新计算。

import pandas as pd
import matplotlib.pyplot as plt
from random import random

DF = "A": [(random(), random()), (random(), random())],
      "B": [(random(), random()), (random(), random())],
      "C": [(random(), random()), (random(), random())],
      "D": [(random(), random()), (random(), random())]
DF = pd.DataFrame(DF, index=["k=1", "k=2"])

fig, ax = plt.subplots()
for row in DF.index:
    ax.plot(DF.columns, [a for a, b in DF.loc[row,]], 'b.', label="Male" if row == "k=1" else None)
    ax.plot(DF.columns, [b for a, b in DF.loc[row,]], 'g+', label="Female" if row == "k=1" else None)
for elements in ax.lines:
    xs = elements.get_xydata()[:, 0] # get_xdata() returns strings, but get_xydata is fully numeric
    jittered_xs = xs + np.random.uniform(-0.4, 0.4, xs.shape)
    elements.set_xdata(jittered_xs)
ax.relim()
ax.autoscale(enable=True)
plt.legend(loc="upper right")
plt.show()

【讨论】:

非常感谢!是不是也可以在每个点的x坐标上加一点随机噪声? 我更新了代码,有些抖动。 (同样的方法也适用于 Quang Hoang 的方法)【参考方案2】:

让我们在绘图之前尝试重塑您的数据:

s = DF.unstack()
plot_df = pd.DataFrame(list(s.values), columns=['Male','Female'], 
                      index=s.index.get_level_values(0))

styles = ['b.','g+']

plt.figure(figsize=(10,6))
for col,style in zip(plot_df.columns, styles):
    plt.plot(plot_df.index, plot_df[col], style, label=col)
    
plt.legend(loc="upper right")
plt.show()

输出:

【讨论】:

以上是关于使用 for 循环绘图时,如何跳过图例中的重复标签?的主要内容,如果未能解决你的问题,请参考以下文章

来自单元格的 Matlab 图例,用于使用 for 循环创建的绘图

如何使用R中的下一个函数跳过for循环中的迭代[重复]

使用 pandas 绘图时,图例仅显示一个标签

For或While循环跳过输入[重复]

使用多个几何图形时如何消除ggplotly重复的图例条目

seaborn中的图例重叠绘图区域[重复]