twinx 使刻度标签颜色消失

3 投票
1 回答
3953 浏览
提问于 2025-04-17 04:23

我正在绘制一个双坐标图,有两个y轴。第二个y轴 ax2 是通过 twinx 创建的。问题是,我用 yticks 来给第二个y轴上色时不再有效。相反,我必须单独用 set_color 来设置标签的颜色。以下是相关的代码:

fig = plt.figure()
fill_between(data[:,0], 0, (data[:,2]), color='yellow')
yticks(arange(0.2,1.2,0.2), ['.2', '.4', '.6', '.8', ' 1'], color='yellow')
ax2 = twinx()
ax2.plot(data[:,0], (data[:,1]), 'green')
yticks(arange(0.1,0.6,0.1), ['.1 ', '.2', '.3', '.4', '.5'], color='green')
# color='green' has no effect here ?!
# instead this is needed:
for t in ax2.yaxis.get_ticklabels(): t.set_color('green')
show()

结果如下:

colored_ticklabels

这个问题只在我设置刻度字符串的时候出现。

yticks(arange(0.1,0.6,0.1), ['.1 ', '.2', '.3', '.4', '.5'], color='green')

如果不设置,就像这里这样

yticks(arange(0.1,0.6,0.1), color='green')

那么上色就能正常工作了。

这是个bug吗(我找不到相关的报告),还是一个功能(?!)或者我在这里漏掉了什么?我在ubuntu上使用的是python 2.6.5和matplotlib 0.99.1.1。

1 个回答

2

不管怎样,你的代码在我的系统上运行得很好,即使没有用 for 循环来设置标签颜色。作为参考,这里有一个独立的例子,基本上跟你发的内容一模一样:

import matplotlib.pyplot as plt
import numpy as np

# Generate some data
num = 200
x = np.linspace(501, 1200, num)
yellow_data, green_data = np.random.random((2,num))
green_data -= np.linspace(0, 3, yellow_data.size)

# Plot the yellow data
plt.fill_between(x, yellow_data, 0, color='yellow')
plt.yticks([0.0, 0.5, 1.0], color='yellow')

# Plot the green data
ax2 = plt.twinx()
ax2.plot(x, green_data, 'g-')
plt.yticks([-4, -3, -2, -1, 0, 1], color='green')

plt.show()

enter image description here

我猜你的问题主要是因为混淆了不同对象的引用。我觉得你的代码可能稍微复杂一些,当你调用 plt.yticks 时,ax2 可能不是当前的坐标轴。你可以通过在调用 yticks 之前明确调用 sca(ax2)(把当前坐标轴设置为 ax2)来测试这个想法,看看这样是否会改变结果。

一般来说,最好要么完全使用类似于 matlab 的状态机接口,要么使用面向对象的接口,不要混用太多。(就我个人而言,我更喜欢只使用面向对象的接口。用 pyplot 来设置图形对象和显示图形,其他时候使用坐标轴的方法。不过每个人有自己的偏好。)

无论如何,从 matplotlib 版本 1.0 开始,tick_params 函数让这变得更方便。(我这里也在使用 plt.subplots,这个功能也是从 1.0 版本开始有的。)

import matplotlib.pyplot as plt
import numpy as np

# Generate some data
yellow_data, green_data = np.random.random((2,2000))
yellow_data += np.linspace(0, 3, yellow_data.size)
green_data -= np.linspace(0, 3, yellow_data.size)

# Plot the data
fig, ax1 = plt.subplots()
ax2 = ax1.twinx()

ax1.plot(yellow_data, 'y-')
ax2.plot(green_data, 'g-')

# Change the axis colors...
ax1.tick_params(axis='y', labelcolor='yellow')
ax2.tick_params(axis='y', labelcolor='green')

plt.show()

enter image description here

在旧版本的 matplotlib 中,相应的代码看起来会更像这样:

import matplotlib.pyplot as plt
import numpy as np

# Generate some data
yellow_data, green_data = np.random.random((2,2000))
yellow_data += np.linspace(0, 3, yellow_data.size)
green_data -= np.linspace(0, 3, yellow_data.size)

# Plot the data
fig = plt.figure()
ax1 = fig.add_subplot(1,1,1)
ax2 = ax1.twinx()

ax1.plot(yellow_data, 'y-')
ax2.plot(green_data, 'g-')

# Change the axis colors...
for ax, color in zip([ax1, ax2], ['yellow', 'green']):
    for label in ax.yaxis.get_ticklabels():
        label.set_color(color)

plt.show()

撰写回答