3

It's possible to set the color cycle to match an existing colormap, but this question is asking how to do the inverse: creating a qualitative colormap from the color cycle.

In my specific case, I've got a scatter plot with an associated array of integer class labels. My current plot looks like this:

x,y = np.random.normal(size=(2,250))
theta = np.arctan2(y,x)
c = np.digitize(theta, np.histogram(theta)[1])
plt.scatter(x,y,c=c)

current scatter plot

As you can see, this doesn't do a great job of distinguishing the classes cleanly. Instead, I'd like to somehow plug in a colormap that matches the current color cycle, where label i corresponds to color_cycle[i]. If I have more classes than the color cycle has colors, that's fine, it should just wrap around like normal.

1 Answer 1

1

I don't think there is a public API for obtaining the current color cycle, but by mimicking set_prop_cycle you might define get_prop_cycle this way:

rcParams = plt.matplotlib.rcParams
def get_prop_cycle():
    prop_cycler = rcParams['axes.prop_cycle']
    if prop_cycler is None and 'axes.color_cycle' in rcParams:
        clist = rcParams['axes.color_cycle']
        prop_cycler = cycler('color', clist)
    return prop_cycler

Once you have the colors in prop_cycler, you can map c to colors in the color cycle:

colors = [item['color'] for item in get_prop_cycle()]
c = np.take(colors, c, mode='wrap')

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.rcsetup import cycler

np.random.seed(2016)

rcParams = plt.matplotlib.rcParams
def get_prop_cycle():
    prop_cycler = rcParams['axes.prop_cycle']
    if prop_cycler is None and 'axes.color_cycle' in rcParams:
        clist = rcParams['axes.color_cycle']
        prop_cycler = cycler('color', clist)
    return prop_cycler

fig, ax = plt.subplots(nrows=2)
x,y = np.random.normal(size=(2,250))
theta = np.arctan2(y,x)
c = np.digitize(theta, np.histogram(theta)[1])

ax[0].scatter(x,y,c=c)
ax[0].set_title('using default colormap')

colors = [item['color'] for item in get_prop_cycle()]
c = np.take(colors, c, mode='wrap')

ax[1].scatter(x,y,c=c)
ax[1].set_title('using color cycle')
plt.show()

enter image description here

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, this is exactly what I need! I found it a little simpler to use c = np.take(colors, c, mode='wrap'), instead of the cycle/islice combo.
@perimosocordiae: Thanks for the great improvement.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.