【问题标题】:Annotate data points while plotting from Pandas DataFrame从 Pandas DataFrame 绘图时注释数据点
【发布时间】:2013-04-03 08:42:07
【问题描述】:

我想在图上的点旁边用它们的值来注释数据点。我发现的示例仅将 x 和 y 作为向量处理。但是,我想对包含多列的 pandas DataFrame 执行此操作。

ax = plt.figure().add_subplot(1, 1, 1)
df.plot(ax = ax)
plt.show()

为多列 DataFrame 注释所有点的最佳方法是什么?

【问题讨论】:

    标签: matplotlib pandas


    【解决方案1】:

    假设您的df 有多个列,其中三个是xylbl。要使用lbl 注释您的(x,y) 散点图,只需:

    ax = df.plot(kind='scatter',x='x',y='y')
    df[['x','y','lbl']].apply(lambda row: ax.text(*row),axis=1);
    

    【讨论】:

    • 对于第一行,当前的 pandas 将使用 df.plot('x', 'y', kind='scatter')
    【解决方案2】:

    您想使用其他列之一作为注释的文本吗?这是我最近做的。

    从一些示例数据开始

    In [1]: df
    Out[1]: 
               x         y val
     0 -1.015235  0.840049   a
     1 -0.427016  0.880745   b
     2  0.744470 -0.401485   c
     3  1.334952 -0.708141   d
     4  0.127634 -1.335107   e
    

    绘制点。在本例中,我将 y 与 x 绘制成图。

    ax = df.set_index('x')['y'].plot(style='o')
    

    编写一个循环遍历 x、y 和要在该点旁边注释的值的函数。

    def label_point(x, y, val, ax):
        a = pd.concat({'x': x, 'y': y, 'val': val}, axis=1)
        for i, point in a.iterrows():
            ax.text(point['x'], point['y'], str(point['val']))
    
    label_point(df.x, df.y, df.val, ax)
    
    draw()
    

    【讨论】:

      【解决方案3】:

      我发现以前的答案很有帮助,尤其是LondonRob's example,它稍微改进了布局。

      唯一困扰我的是,我不喜欢从 DataFrame 中提取数据然后循环遍历它们。似乎浪费了DataFrame。

      这是一个替代方案,它使用 .apply() 避免循环,并包含更好看的注释(我认为色阶有点过分,无法让颜色条消失):

      ax = df.plot('x', 'y', kind='scatter', s=50 )
      
      def annotate_df(row):  
          ax.annotate(row.name, row.values,
                      xytext=(10,-5), 
                      textcoords='offset points',
                      size=18, 
                      color='darkslategrey')
          
      _ = df.apply(annotate_df, axis=1)
      

      编辑备注

      我最近编辑了我的代码示例。最初它使用相同的:

      fig, ax = plt.subplots()
      

      作为其他暴露轴的帖子,但是这是不必要的,并且使:

      import matplotlib.pyplot as plt
      

      线也不需要。

      另请注意:

      • 如果您尝试重现此示例,并且您的绘图中的点与我们的绘图不同,可能是因为 DataFrame 使用了随机值。如果我们使用固定数据表或随机种子,它可能不会那么混乱。
      • 根据分数,您可能必须使用 xytext 值才能获得更好的展示位置。

      【讨论】:

        【解决方案4】:

        这是Dan Allan's answer 的(非常)稍微简洁的版本:

        import matplotlib.pyplot as plt
        import pandas as pd
        import numpy as np
        import string
        
        df = pd.DataFrame({'x':np.random.rand(10), 'y':np.random.rand(10)}, 
                          index=list(string.ascii_lowercase[:10]))
        

        这给出了:

                  x         y
        a  0.541974  0.042185
        b  0.036188  0.775425
        c  0.950099  0.888305
        d  0.739367  0.638368
        e  0.739910  0.596037
        f  0.974529  0.111819
        g  0.640637  0.161805
        h  0.554600  0.172221
        i  0.718941  0.192932
        j  0.447242  0.172469
        

        然后:

        fig, ax = plt.subplots()
        df.plot('x', 'y', kind='scatter', ax=ax)
        
        for k, v in df.iterrows():
            ax.annotate(k, v)
        

        最后,如果您处于交互模式,您可能需要刷新绘图:

        fig.canvas.draw()
        

        产生:

        或者,因为这看起来非常难看,你可以很容易地美化一些东西:

        from matplotlib import cm
        cmap = cm.get_cmap('Spectral')
        df.plot('x', 'y', kind='scatter', ax=ax, s=120, linewidth=0, 
                c=range(len(df)), colormap=cmap)
        
        for k, v in df.iterrows():
            ax.annotate(k, v,
                        xytext=(10,-5), textcoords='offset points',
                        family='sans-serif', fontsize=18, color='darkslategrey')
        

        看起来好多了:

        【讨论】:

        • 漂亮! (你说的第二个情节......)
        • @LondonRob,有没有你能告诉我我们如何才能只对其他第 n 个标记进行注释?
        • @st19297 创建一个新问题!并包含指向此答案的链接(请参阅“分享”链接),以便人们知道您从哪里开始!
        • 我使用这种方法遇到的问题是,如果标签超出绘图区域,它们会被截断。知道如何解决这个问题吗?
        • @HowardLovatt,您可以使用xlim=[0,1]ax.set(xlim=xlim, ylim=ylim) 重置轴限制,如果您需要动态计算限制,您可以从df[x].max() 开始并通过乘以0.9 进行调整或者1.1,比如说。
        猜你喜欢
        • 1970-01-01
        • 2015-06-12
        • 2013-11-04
        • 2018-02-04
        • 2016-06-17
        • 1970-01-01
        • 2017-12-07
        相关资源
        最近更新 更多