-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
DOC: selecting individual colors from a colormap #27678
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
""" | ||
=========================================== | ||
Selecting individual colors from a colormap | ||
=========================================== | ||
|
||
Sometimes we want to use more colors or a different set of colors than the default color | ||
cycle provides. Selecting individual colors from one of the provided colormaps can be a | ||
convenient way to do this. | ||
|
||
Once we have hold of a `.Colormap` instance, the individual colors can be accessed | ||
by passing it an index. If we want a specific number of colors taken at regular | ||
intervals from a continuous colormap, we can create a new colormap using the | ||
`~.Colormap.resampled` method. | ||
|
||
For more details about manipulating colormaps, see :ref:`colormap-manipulation`. | ||
""" | ||
|
||
import matplotlib.pyplot as plt | ||
|
||
import matplotlib as mpl | ||
|
||
n_lines = 21 | ||
|
||
cmap = mpl.colormaps.get_cmap('plasma').resampled(n_lines) | ||
|
||
fig, ax = plt.subplots(layout='constrained') | ||
|
||
for i in range(n_lines): | ||
ax.plot([0, i], color=cmap(i)) | ||
|
||
plt.show() | ||
|
||
# %% | ||
# Instead of passing colors one by one to `~.Axes.plot`, we can replace the default | ||
# color cycle with a different set of colors. Specifying a `~cycler.cycler` instance | ||
# within `.rcParams` achieves that. See :ref:`color_cycle` for details. | ||
|
||
|
||
from cycler import cycler | ||
|
||
cmap = mpl.colormaps.get_cmap('Dark2') | ||
colors = cmap(range(cmap.N)) # cmap.N is number of unique colors in the colormap | ||
Comment on lines
+41
to
+42
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The qualitative colormaps are
Note that this is a significantly different task than selecting N equidistant colors from a continuous map. I'm not clear on the focus we want to set here: #27671 was primaily "I have N lines and want differnt colors", which is the first part here. My comment on a context example was the idea one should mention in the context of the above task that you can make a context so that you don't have to carry the colors explicitly. That's a different direction than focussing on various aspects of getting color values. Both ways are possbile, but we should not mix them. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmmm, I started by using the My thinking for using a qualitative colormap: if someone is changing the color cycle in rcParams then they are using it across several plots which might need different numbers of colors, so getting a specific number of colors out of a continuous map would make less sense there. This is in the context where the user was also asking for an increase in the default cycle. |
||
|
||
with mpl.rc_context({'axes.prop_cycle': cycler(color=colors)}): | ||
|
||
fig, ax = plt.subplots(layout='constrained') | ||
|
||
for i in range(n_lines): | ||
ax.plot([0, i]) | ||
|
||
plt.show() | ||
|
||
# %% | ||
# | ||
# .. admonition:: References | ||
# | ||
# The use of the following functions, methods, classes and modules is shown | ||
# in this example: | ||
# | ||
# - `matplotlib.colors.Colormap` | ||
# - `matplotlib.colors.Colormap.resampled` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would have used
in particular
mpl.colormaps.get_cmap('plasma')
is somewhat unconventional. The ColormapRegistry supports item access for colormap names. That feels more natural to me for just looking up a colormap on the registry.get_cmap()
is similar but has additional functionality like Colormap-passthrough and default-lookup forNone
. I would either usempl.colormaps['plasma']
or just use the pyplot functionplt.get_cmap('plasma')
to save theimport mpl
(technically you could also doplt.colormaps['plasma']
because we re-export the registry in pyplot).cmap
(l.24) and later looking up the color (l.29). They only make sense together but are quite separted. The vectorized approach of mapping an array of floats to colors is more explicit. Note also that you can easily sample parts of the colormap in the vectorized lookup, e.g.mpl.colormaps['RdYlGn'](np.linspace(0.5, 1, n_lines))
to sample only the upper half of a diverging colormap.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @timhoffm. It seems you and @jklymak are in agreement about the integer indexing being “suprising” so we should probably change it!
I did start with
plt.get_cmap
but I thought we were generally supposed to avoidpyplot
for most things.