优雅地更改matplotlib中的绘图框颜色

48 投票
4 回答
80372 浏览
提问于 2025-04-17 04:23

这是一个跟这篇帖子相关的后续问题,帖子里讨论了如何给坐标轴、刻度和标签上色。我希望开一个新的、扩展的问题是可以的。

如果想要改变一个双图(通过 add_subplot 创建的)周围的完整框架(包括刻度和坐标轴)的颜色,涉及到的代码会很多。下面这段代码是用来改变上面图的框架颜色的:

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行代码……结果就是这样:

enter image description here

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

  • matplotlib.rc:在这里讨论过;这种方法是全局改变,不是局部的。我想要不同颜色的其他图。请不要讨论图中颜色太多的问题……:-)

    matplotlib.rc('axes',edgecolor='green')
    
  • 挖掘坐标轴的边框,然后改变它:在这里也讨论过;我觉得这不是很优雅。

    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。

4 个回答

11

也许这样回答自己的问题有点粗糙,但我想分享一下我目前找到的内容。这个版本可以用两种不同的颜色给两个子图上色,分别是 [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()

color_plots

我把这个标记为接受答案,因为这是我目前找到的最简洁的解决方案。不过,我仍然欢迎其他可能更优雅的解决方法。

41

假设你正在使用一个比较新的 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()

在这里输入图片描述

29

对你上面的代码进行重构:

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)

撰写回答