4

I adjusted the colororder for my plot by rcParams['axes.color_cycle'] = [some nice and carefully chosen colours]

But when I use twinx for a second axes the colororder is reset:

 from matplotlib import pyplot as plt
 from matplotlib import rcParams
 rcParams['axes.color_cycle'] = ['r','g','k']
 fig = plt.figure()
 ax = fig.add_subplot(1,1,1)
 ax1 = plt.twinx(ax) 
 ax.plot([1,2,3],[4,5,6])
 ax.plot([1,2,3],[7,6,4])
 ax1.plot([1,2,3],[5,3,1])

Is there a way to circumvent that? The line plotted on ax1 should be black.

Xan
  • 74,770
  • 16
  • 179
  • 206
Moritz
  • 5,130
  • 10
  • 40
  • 81

3 Answers3

13

Instead of advancing the color cycler of the second axis (as suggested in other answers) you can actually use a single color cycler for both axes:

fig, ax1 = plt.subplots()
ax1.plot(...)

ax2 = ax1.twinx()
ax2._get_lines.prop_cycler = ax1._get_lines.prop_cycler
ax2.plot(...)
Mario
  • 231
  • 2
  • 2
4

As discussed in a more recent answer to Get Matplotlib Color Cycle State, with matplotlib 1.5 there have been changes to color cycling related to a new, more generic "property cycling" feature. The key command in Schorsch's answer now has to be next(ax1._get_lines.prop_cycler).

The strategy still involves poking around behind the scenes, so no guarantee that this also won't break in future versions.

Community
  • 1
  • 1
millikan
  • 781
  • 5
  • 9
3

Here's a way to advance the color-order for the second axis.

from matplotlib import pyplot as plt
from matplotlib import rcParams

rcParams['axes.color_cycle'] = ['r','g','k']
fig = plt.figure()
ax = fig.add_subplot(1,1,1)
ax1 = plt.twinx(ax) 

line = []

line.append(ax.plot([1,2,3],[4,5,6])[0])
line.append(ax.plot([1,2,3],[7,6,4])[0])

for advance in range(len(line)):
    ax1._get_lines.color_cycle.next()

ax1.plot([1,2,3],[5,3,1])

If you run this example, the line on the second axis will be black.


What happens is this:

  • In line you keep track of the numer of lines that you have plotted on the first axis. Note, that you need to only append the first entry of the matplotlib.lines.Line2D object, hence the [0] at the end of ax.plot([1,2,3],[4,5,6])
  • The for-loop may look a bit clumsy. However, it advances your color-cycle of the second axis by the number of lines you already have on the first axis. This is done through calling next() on ax1._get_lines.color_cycle
  • You don't acutally need the loop counter advance, however, it makes the code more readable.
  • Now, any lines on the second axis will continue with the next color in the cycle after the one you left off with on the first axis.
  • If you wanted to go back to the first axis, you'd have to count the number of lines on ax1, too.

An interesting question to read in this context is: Get Matplotlib Color Cycle State

Community
  • 1
  • 1
Schorsch
  • 7,761
  • 6
  • 39
  • 65