【问题标题】:Elegantly changing the color of a plot frame in matplotlib在 matplotlib 中优雅地更改图框的颜色
【发布时间】:2011-12-08 09:37:53
【问题描述】:

这是this 帖子的一种后续问题,其中讨论了轴、刻度和标签的颜色。我希望可以为此打开一个新的扩展问题。

使用轴 [ax1, ax2] 围绕双图(通过add_subplot)更改完整框架(刻度和轴)的颜色会导致大量代码。这个 sn-p 改变了 上图的框架的颜色

ax1.spines['bottom'].set_color('green')
ax1.spines['top'].set_color('green')
ax1.spines['left'].set_color('green')
ax1.spines['right'].set_color('green')
for t in ax1.xaxis.get_ticklines(): t.set_color('green')
for t in ax1.yaxis.get_ticklines(): t.set_color('green')
for t in ax2.xaxis.get_ticklines(): t.set_color('green')
for t in ax2.yaxis.get_ticklines(): t.set_color('green')

因此,要更改两个带有两个 y 轴的图的框架颜色,我需要 16(!) 行代码...这就是它的样子:

到目前为止我挖掘的其他方法:

  • matplotlib.rc:讨论过here;全局变化,而不是局部变化。我想要其他一些不同颜色的图。请不要讨论情节中的颜色过多... :-)

    matplotlib.rc('axes',edgecolor='green')
    
  • 挖出轴的刺,然后改变它:还讨论了here;我认为不是很优雅。

    for child in ax.get_children():
        if isinstance(child, matplotlib.spines.Spine):
            child.set_color('#dddddd')
    

有没有一种优雅的方式来浓缩上面的块,东西 更多“pythonic”?

我在 ubuntu 下使用 python 2.6.5 和 matplotlib 0.99.1.1。

【问题讨论】:

    标签: python colors matplotlib


    【解决方案1】:

    假设您使用的是最新版本的 matplotlib (>= 1.0),不妨试试这样:

    import matplotlib.pyplot as plt
    
    # Make the plot...
    fig, axes = plt.subplots(nrows=2)
    axes[0].plot(range(10), 'r-')
    axes[1].plot(range(10), 'bo-')
    
    # Set the borders to a given color...
    for ax in axes:
        ax.tick_params(color='green', labelcolor='green')
        for spine in ax.spines.values():
            spine.set_edgecolor('green')
    
    plt.show()
    

    【讨论】:

    • 我运行 matplotlib 0.99.1.1(天哪!)。我也没有很好地解释双重情节。我更新了最初的问题并添加了一个图形。您展示了另一种轴着色的可能性,我可以将其添加到我的列表中(如果运行最新版本的 m.p.l.)。如果您在一个图中为具有两个 y 轴的框架着色,您的框架是否仍然更短?
    【解决方案2】:

    也许回答我自己的问题有点粗鲁,但我想分享一下到目前为止我能找到的东西。这个版本可以用两种不同的颜色为两个带有轴[ax1, ax2][ax3, ax4] 的子图着色。它比我在上面的问题中所说的 16 行短很多。它的灵感来自 Joe Kington 在此处和 twinx kills tick label color 中的回答。

    import matplotlib.pyplot as plt
    import numpy as np
    
    # Generate some data
    num = 200
    x = np.linspace(501, 1200, num)
    yellow_data, green_data , blue_data= np.random.random((3,num))
    green_data += np.linspace(0, 3, yellow_data.size)/2
    blue_data += np.linspace(0, 3, yellow_data.size)/2
    
    fig = plt.figure()
    plt.subplot(211) # Upper Plot
    ax1 = fig.add_subplot(211)
    ax1.fill_between(x, 0, yellow_data, color='yellow')
    ax2 = ax1.twinx()
    ax2.plot(x, green_data, 'green')
    plt.setp(plt.gca(), xticklabels=[])
    plt.subplot(212) # Lower Plot
    ax3 = fig.add_subplot(212)
    ax3.fill_between(x, 0, yellow_data, color='yellow')
    ax4 = ax3.twinx()
    ax4.plot(x, blue_data, 'blue')
    
    # Start coloring
    for ax, color in zip([ax1, ax2, ax3, ax4], ['green', 'green', 'blue', 'blue']):
        for ticks in ax.xaxis.get_ticklines() + ax.yaxis.get_ticklines():
            ticks.set_color(color)
        for pos in ['top', 'bottom', 'right', 'left']:
            ax.spines[pos].set_edgecolor(color)
    # End coloring
    
    plt.show()
    

    我将此标记为已接受,因为它是迄今为止我能找到的最紧凑的解决方案。不过,我愿意接受其他可能更优雅的方法来解决它。

    【讨论】:

      【解决方案3】:

      重构上面的代码:

      import matplotlib.pyplot as plt
      
      for ax, color in zip([ax1, ax2, ax3, ax4], ['green', 'green', 'blue', 'blue']):
          plt.setp(ax.spines.values(), color=color)
          plt.setp([ax.get_xticklines(), ax.get_yticklines()], color=color)
      

      【讨论】:

      • 不错的一个。请包括两种颜色,我会“接受”你的答案。 (如:for ax, color in zip([ax1, ax2, ax3, ax4], ['green', 'green', 'blue', 'blue']): plt.setp(ax.spines.values(), color=color); plt.setp([ax.get_xticklines(), ax.get_yticklines()], color=color)
      • 在你的最后一行我认为你的意思是 ax1 只是 ax
      • 确实是@Joel。 :) 我现在已经更正了(4 年多之后)。
      • 仅供参考,ax.spines.values() 在 Py3 中不起作用,因为plt.setp 只接受可索引对象。字典值是可迭代的,但在 Py3 中不可索引。我正在做一个 PR 来为后代解决这个问题(我的意思是让 setp 接受任何可迭代的,而不是在 Py3 中修复 values())。
      • @MadPhysicist 谢谢,是的,现在我只使用tuple(ax.spines.values()) 来更改它们的颜色和plt.setp。如果它适用于任意迭代,那将非常有用。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-01-07
      • 2013-12-01
      • 2017-03-17
      • 2013-07-21
      • 1970-01-01
      • 2021-11-30
      • 2017-05-13
      相关资源
      最近更新 更多