【问题标题】:Plotting values from two datasets for comparison绘制来自两个数据集的值以进行比较
【发布时间】:2020-12-25 03:52:43
【问题描述】:

我想绘制两个数据框以比较结果。我的第一选择是仅根据两个数据框中的一列绘制折线图。

df
       Name Surname P   R   F   
    0   B   N   0.41    0.76    0.53
    1   B   L   0.62    0.67    0.61
    2   B   SV  0.63    0.53    0.52
    3   B   SG  0.43    0.61    0.53
    4   B   R   0.81    0.51    0.53
    5   T   N   0.32    0.82    0.53
    6   T   L   0.58    0.69    0.62
    7   T   SV  0.67    0.61    0.64
    8   T   SG  0.53    0.63    0.57
    9   T   R   0.74    0.48    0.58

data = [['B','N',0.41,0.72,0.51], 
['B','L',0.66,0.67,0.62],
['B','SV',0.63,0.51,0.51],
['B','SG',0.44,0.63,0.51],
['B','R',0.81,0.51,0.62],
['T','N',0.33,0.80,0.47],
['T','L',0.58,0.61,0.63],
['T','SV',0.68,0.61,0.64],
['T','SG',0.53,0.63,0.57],
['T','R',0.74,0.48,0.58]]

df1 = pd.DataFrame(data, columns = ['Name','Surname','P','R','F']) 

我想根据 F 值创建一个图,保留 B/T 和 R、N、L、SV、SG 的信息(在图例/标签中)。

我尝试过使用条形图,但这没有考虑标签/图例。

我正在寻找这样的东西:

fig, ax = plt.subplots()
ax2 = ax.twinx()

df.plot(x="Name", y=["F"], ax=ax)
df1.plot(x="Name", y=["F"], ax=ax2, ls="--")

但是这缺少标签和图例。

我也尝试过:

ax = df.plot()
l = ax.get_lines()
df1.plot(ax=ax, linestyle='--', color=(i.get_color() for i in l))

但我无法区分姓名、姓氏和数据框(在 x 轴上应该有姓氏)。 也可以单独绘制值(P、R 和 F),如下所示:

ax = df[['P']].plot()
l = ax.get_lines()
df1[['P']].plot(ax=ax, linestyle='--', color=(i.get_color() for i in l))

我应该根据姓名和姓氏比较两个地块的 F 值。 任何帮助将不胜感激。

【问题讨论】:

  • 也许使用fig.legend..

标签: python matplotlib


【解决方案1】:

IIUC,

fig, ax = plt.subplots()
ax2 = ax.twinx()

df.plot(x="Name", y=["F"], ax=ax)
df1.plot(x="Name", y=["F"], ax=ax2, ls="--")
fig.legend(loc="upper right", bbox_to_anchor=(1,1), bbox_transform=ax.transAxes)

输出:

【讨论】:

    【解决方案2】:

    向图形添加有关其他参数的信息的最简单方法是在循环中使用 ax.text 或 ax.annotate 等函数。代码应如下所示:

    fig, ax = plt.subplots()
    data1 = ax.bar(20*index, df["F"], bar_width)
    data2 = ax.bar(20*index+bar_width, df1["F"],bar_width)
    
    for i in index:
        ax.text(i*20-5,0,df['Surname'][i],)
        ax.text(i*20-5,0.05,df['Name'][i])
        ax.text(i*20+bar_width-5,0,df1['Surname'][i])
        ax.text(i*20+bar_width-5,0.05,df1['Name'][i])
    plt.show()
    

    有用的链接: Official Documentation for Text in Matplotlib Plots

    编辑: 大概类似的问题:Different text at each point

    编辑 2: 无索引代码:

    fig, ax = plt.subplots()
    data1 = ax.plot(df["F"])
    data2 = ax.plot(df1["F"])
    
    for i in range(1,10):
        ax.text(i,df["F"][i],df['Name'][i]+" "+df['Surname'][i],)
        ax.text(i,df["F"][i],df['Name'][i]+" "+df['Surname'][i],)
    plt.show()
    

    【讨论】:

    • @Val 前一个错误即将到来,因为您可能尚未定义用于绘图的名为 index 的变量。您可以使用 index = np.arange(n)*bar_width*2 之类的东西,其中 n 是数据的长度(在您的情况下为 10),并且还将 bar_width 定义为条的宽度。 matplotlib 中没有单独的功能可以在单独的窗口中获取图例。我建议您将文本移动到您想要的任何位置。如果要在同一窗口中显示图例,请参阅 matplotlib.org/3.1.1/api/_as_gen/matplotlib.pyplot.legend.html 。如果有什么问题你可以再问!
    • index 存储橙色条的 x 值。但如果您使用折线图,您可以从代码中删除索引,代码变为 data1 = plt.plot(df["F"]);data2 = plt.plot(df1["F"])。还有你提到的另一个错误,错误信息是什么?
    • @Val 我的代码在第 2,3 和 5 行中使用了变量 'index'。您需要定义它或从代码中删除它以避免错误。
    • 您可以为每条线设置不同的颜色和/或形状参数。查看文档matplotlib.org/3.3.3/api/_as_gen/matplotlib.pyplot.plot.html 了解确切用法。
    • 是的,你可以。它只是一个不同的函数:ax.legend()。文档:matplotlib.org/3.1.1/api/_as_gen/matplotlib.pyplot.legend.html
    猜你喜欢
    • 1970-01-01
    • 2021-05-05
    • 1970-01-01
    • 1970-01-01
    • 2013-08-13
    • 2018-02-13
    • 2022-01-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多