【问题标题】:Pandas plot: Assign Colors熊猫图:分配颜色
【发布时间】:2015-03-23 23:46:22
【问题描述】:

我正在为演示文稿绘制许多数据框。这些都有不同的列,但都包含相同的附加列foobar。目前,我正在使用

绘制这些不同的数据框
df.plot(secondary_y='foobar')

不幸的是,由于这些数据框都有不同的附加列,顺序不同,foobar 的颜色总是不同的。这使得演示幻灯片不必要的复杂。我想,在整个不同的情节中,指定foobar 被绘制为粗体和黑色。

查看the docs,唯一接近的似乎是参数colormap - 我需要确保颜色图中的xth 颜色始终为黑色,其中x 是顺序数据框中的foobar。似乎比它应该的更复杂,这也不会使它变得粗体。

有(更好的)方法吗?

【问题讨论】:

    标签: python pandas matplotlib


    【解决方案1】:

    我建议直接使用matplotlib 而不是数据框绘图方法。如果 df.plot 返回它添加的艺术家而不是 Axes 对象,那么在绘制后更改线条的颜色也不会太糟糕。

    import matplotlib.pyplot as plt
    import pandas as pd
    import numpy as np
    
    def pandas_plot(ax, df, callout_key):
        """
        Parameters
        ----------
        ax : mpl.Axes
            The axes to draw to
    
        df : DataFrame
            Data to plot
    
        callout_key : str
            key to highlight
    
        """
        artists = {}
    
        x = df.index.values
        for k, v in df.iteritems():
            style_kwargs = {}
            if k == callout_key:
                style_kwargs['c'] = 'k'
                style_kwargs['lw'] = 2
            ln, = ax.plot(x, v.values, **style_kwargs)
            artists[k] = ln
    
        ax.legend()
        ax.set_xlim(np.min(x), np.max(x))
    
        return artists
    

    用法:

    fig, ax = plt.subplots()
    ax2 = ax.twinx()
    
    th = np.linspace(0, 2*np.pi, 1024)
    df = pd.DataFrame({'cos': np.cos(th), 'sin': np.sin(th),
                      'foo': np.sin(th + 1), 'bar': np.cos(th +1)}, index=th)
    df2 = pd.DataFrame({'cos': -np.cos(th), 'sin': -np.sin(th)}, index=th)
    
    pandas_plot(ax, df, 'sin')
    pandas_plot(ax2, df2, 'sin')
    

    【讨论】:

      【解决方案2】:

      也许您可以在单独的plot 调用中定义一个处理特殊列的函数:

      def emphasize_plot(ax, df, col, **emphargs):
          columns = [c for c in df.columns if c != col]
          df[columns].plot(ax=ax)
          df[col].plot(ax=ax, **emphargs)
      

      使用 tcaswell 示例中的代码,

      import numpy as np
      import pandas as pd
      import matplotlib.pyplot as plt
      
      def emphasize_plot(ax, df, col, **emphargs):
          columns = [c for c in df.columns if c != col]
          df[columns].plot(ax=ax)
          df[col].plot(ax=ax, **emphargs)
      
      fig, ax = plt.subplots()
      th = np.linspace(0, 2*np.pi, 1024)
      df = pd.DataFrame({'cos': np.cos(th), 'foobar': np.sin(th),
                        'foo': np.sin(th + 1), 'bar': np.cos(th +1)}, index=th)
      df2 = pd.DataFrame({'cos': -np.cos(th), 'foobar': -np.sin(th)}, index=th)
      
      emphasize_plot(ax, df, 'foobar', lw=2, c='k')
      emphasize_plot(ax, df2, 'foobar', lw=2, c='k')
      plt.show()
      

      产量

      【讨论】:

        【解决方案3】:

        我使用了@unutbut 的答案并将其扩展为允许辅助 y 轴和正确的图例:

        def emphasize_plot(ax, df, col, **emphargs):
            columns = [c for c in df.columns if c != col]
            ax2 = ax.twinx()
            df[columns].plot(ax=ax)
            df[col].plot(ax=ax2, **emphargs)
            lines, labels = ax.get_legend_handles_labels()
            lines2, labels2 = ax2.get_legend_handles_labels()
            ax2.legend(lines + lines2, labels + labels2, loc=0)
        

        【讨论】:

          猜你喜欢
          • 2015-12-08
          • 2020-08-31
          • 2014-06-01
          • 1970-01-01
          • 2020-02-01
          • 2019-01-23
          • 2021-02-09
          • 2021-08-15
          相关资源
          最近更新 更多