Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Increment matplotlib color cycle

Is there a simple way to increment the matplotlib color cycle without digging into axes internals?

When plotting interactively a common pattern I use is:

import matplotlib.pyplot as plt

plt.figure()
plt.plot(x,y1)
plt.twinx()
plt.plot(x,y2)

The plt.twinx() in necessary to get different y-scales for y1 and y2 but both plots are drawn with the first color in the default colorcycle making it necessary to manually declare the color for each plot.

There must be a shorthand way to instruct the second plot to increment the color cycle rather than explicitly giving the color. It is easy of course to set color='b' or color='r' for the two plots but when using a custom style like ggplot you would need need to lookup the color codes from the current colorcycle which is cumbersome for interactive use.

like image 749
Mike Avatar asked Jun 17 '16 21:06

Mike


3 Answers

You could call

ax2._get_lines.get_next_color()

to advance the color cycler on color. Unfortunately, this accesses the private attribute ._get_lines, so this is not part of the official public API and not guaranteed to work in future versions of matplotlib.

A safer but less direct way of advance the color cycler would be to plot a null plot:

ax2.plot([], [])

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(10)
y1 = np.random.randint(10, size=10)
y2 = np.random.randint(10, size=10)*100
fig, ax = plt.subplots()
ax.plot(x, y1, label='first')
ax2 = ax.twinx()
ax2._get_lines.get_next_color()
# ax2.plot([], [])
ax2.plot(x,y2, label='second')

handles1, labels1 = ax.get_legend_handles_labels()
handles2, labels2 = ax2.get_legend_handles_labels()
ax.legend(handles1+handles2, labels1+labels2, loc='best')  

plt.show()

enter image description here

like image 89
unutbu Avatar answered Oct 07 '22 06:10

unutbu


There are several colour schemes available in Pyplot. You can read more on the matplotlib tutorial Specifying Colors.

From these docs:

a "CN" color spec, i.e. 'C' followed by a number, which is an index into the
default property cycle (matplotlib.rcParams['axes.prop_cycle']); the indexing
is intended to occur at rendering time, and defaults to black if the cycle
does not include color.

You can cycle through the colour scheme as follows:

fig, ax = plt.subplots()

# Import Python cycling library
from itertools import cycle

# Create a colour code cycler e.g. 'C0', 'C1', etc.
colour_codes = map('C{}'.format, cycle(range(10)))

# Iterate over series, cycling coloour codes
for y in my_data:
    ax.plot(x, y, color=next(color_codes))

This could be improved by cycling over matplotlib.rcParams['axes.prop_cycle'] directly.

like image 34
Joe Heffer Avatar answered Oct 07 '22 07:10

Joe Heffer


Similar to the other answers but using matplotlib color cycler:

import matplotlib.pyplot as plt
from itertools import cycle

prop_cycle = plt.rcParams['axes.prop_cycle']
colors = cycle(prop_cycle.by_key()['color'])
for data in my_data:
    ax.plot(data.x, data.y, color=next(colors))
like image 27
Michele Avatar answered Oct 07 '22 07:10

Michele