3

I am plotting a double plot with two y-axes. The second axis ax2 is created by twinx. The problem is that the coloring of the second y-axis via yticks is not working anymore. Instead I have to set_color the labels individually. Here is the relevant code:

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()

Resulting in:

colored_ticklabels

This issue only occurs if I set the tick strings.

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

Omit it, like here

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

and the coloring works fine.

Is that a bug (could not find any reports to this), a feature (?!) or am I missing something here? I am using python 2.6.5 with matplotlib 0.99.1.1 on ubuntu.

Boffin
  • 1,197
  • 2
  • 11
  • 18
  • I'm not quite clear what you're doing... (What exactly do you mean by "double plot"? `twinx`/`twiny`, subplots, or something else entirely?) Can you post some example code or an example image of the problem and/or what you expect to happen? – Joe Kington Oct 15 '11 at 22:20
  • Sorry for the unclear description. I tracked down the problem to the use of `twinx` and condensed the question description. Also a graphic is added. – Boffin Oct 16 '11 at 01:21

1 Answers1

2

For whatever it's worth, you code works fine on my system even without the for loop to set the label colors. Just as a reference, here's a stand-alone example trying to follow essentially exactly what you posted:

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

My guess is that your problem is mostly coming from mixing up references to different objects. I'm guessing that your code is a bit more complex, and that when you call plt.yticks, ax2 is not the current axis. You can test that idea by explicitly calling sca(ax2) (set the current axis to ax2) before calling yticks and see if that changes things.

Generally speaking, it's best to stick to either entirely the matlab-ish state machine interface or the OO interface, and don't mix them too much. (Personally, I prefer just sticking to the OO interface. Use pyplot to set up figure objects and for show, and use the axes methods otherwise. To each his own, though.)

At any rate, with matplotlib >= 1.0, the tick_params function makes this a bit more convenient. (I'm also using plt.subplots here, which is only in >= 1.0, as well.)

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

The equivalent code for older versions of matplotlib would look more like this:

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()
Joe Kington
  • 275,208
  • 71
  • 604
  • 463
  • The issue with the ignored `color=` tag occurs (oddly) only when I explicitly set the label strings: `yticks(arange(0.1,0.4,0.1), ['.1 ', '.2', '.3'], color='green')`. The set strings work, the color does not. Does your first minimal example also work if you specify it? E.g. `plt.yticks([-4, -3, -2, -1, 0, 1], ['foo', 'bar'], color='green')`. Thanks for pointing out the different matplotlib styles (matlab vs. oo). I will read it up a bit more to improve the consistency of my code. – Boffin Oct 23 '11 at 16:09