How to create a customized colormap and use it for

2019-05-19 01:00发布

Let's say I have data like this:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors

# for reproducibility purposes
np.random.seed(0)

# generate some data
n = 30
x = np.array(range(n))

a1 = np.random.rand(n)
a2 = a1 * 100

and I want to plot these data in two subplots, I can do (variation of this answer)

cmap = matplotlib.colors.LinearSegmentedColormap.from_list("", [(0., '#9696ff'), (0.2, '#f0ffff'), (1.0, '#ff0000')])

fig, (ax1, ax2) = plt.subplots(1, 2)
ax1.scatter(x, a1, c=a1, cmap=cmap)
ax2.scatter(x, a2, c=a2, cmap=cmap)
plt.show()

which gives

enter image description here

The problem I have is that it now looks like these data are identical although the values on the right are 100 times larger.

So, what I would like to have is a colormap which I can use for both plots; instead of

matplotlib.colors.LinearSegmentedColormap.from_list("", [(0., '#9696ff'), (0.2, '#f0ffff'), (1.0, '#ff0000')])

I would like to use something like

min_a1_a2 = min(min(a1), min(a2))
max_a1_a2 = max(max(a1), max(a2))
cmap = matplotlib.colors.LinearSegmentedColormap.from_list("", [(min_a1_a2, '#9696ff'), ((min_a1_a2 + max_a1_a2) / 2., '#f0ffff'), (max_a1_a2, '#ff0000')])

but this always results in the error

ValueError: data mapping points must start with x=0. and end with x=1

when I pass it to scatter (using the same commands as above).

Is there a way to pass arbitrary (value, color) tuples to matplotlib.colors.LinearSegmentedColormap.from_list and then the resulting colormap to e.g. scatter and if so how would one do this?

1条回答
forever°为你锁心
2楼-- · 2019-05-19 01:27

A matplotlib colormap maps the numerical range between 0 and 1 to a range of colors.

If the data ranges over an interval other than [0,1] (which is almost always the case of course), one would normalize to that interval first. This normalization is done internally by the ScalarMappable in use (e.g. the scatter plot in this case).

In cases where a custom normalization is needed, as when two different plots need to share a colorcoding, this can be specified when creating the ScalarMappable.

Either using vmin and vmax

plt.scatter(x,y, c=c, cmap=cmap, vmin=0, vmax=100)

or via a Normalization instance

plt.scatter(x,y, c=c, cmap=cmap, norm=plt.Normalize(0,100))
查看更多
登录 后发表回答