使用matplotlib和plot color创建自己的颜色映射

2024-05-21 04:51:35 发布

您现在位置:Python中文网/ 问答频道 /正文

我有以下问题,我想创建我自己的颜色映射(红色混合紫色混合蓝色),映射到-2和+2之间的值,并想使用它在我的绘图中的颜色点。 然后,该图的色阶应在右侧。

这就是我目前创建地图的方式。但我不确定它是否混合了颜色。

cmap = matplotlib.colors.ListedColormap(["red","violet","blue"], name='from_list', N=None)
m = cm.ScalarMappable(norm=norm, cmap=cmap)


这样我将颜色映射到值。

colors = itertools.cycle([m.to_rgba(1.22), ..])


然后绘制:

for i in range(0, len(array_dg)):
  plt.plot(array_dg[i], markers.next(),alpha=alpha[i], c=colors.next())


我的问题是:
一。我无法绘制色阶。
2。我不完全确定我的比例是否正在创建一个连续(平滑)色阶。


Tags: alpha绘图norm颜色绘制arraynext蓝色
3条回答

这里有一个how to create custom colormaps here的示例。 docstring对于理解 cdict。一旦你把它放在腰带下面,你可能会使用这样的cdict

cdict = {'red':   ((0.0, 1.0, 1.0), 
                   (0.1, 1.0, 1.0),  # red 
                   (0.4, 1.0, 1.0),  # violet
                   (1.0, 0.0, 0.0)), # blue

         'green': ((0.0, 0.0, 0.0),
                   (1.0, 0.0, 0.0)),

         'blue':  ((0.0, 0.0, 0.0),
                   (0.1, 0.0, 0.0),  # red
                   (0.4, 1.0, 1.0),  # violet
                   (1.0, 1.0, 0.0))  # blue
          }

尽管cdict格式给了您很大的灵活性,但我发现 渐变它的格式相当不直观。下面是一个实用函数 生成简单的LinearSegmentedColormaps:

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


def make_colormap(seq):
    """Return a LinearSegmentedColormap
    seq: a sequence of floats and RGB-tuples. The floats should be increasing
    and in the interval (0,1).
    """
    seq = [(None,) * 3, 0.0] + list(seq) + [1.0, (None,) * 3]
    cdict = {'red': [], 'green': [], 'blue': []}
    for i, item in enumerate(seq):
        if isinstance(item, float):
            r1, g1, b1 = seq[i - 1]
            r2, g2, b2 = seq[i + 1]
            cdict['red'].append([item, r1, r2])
            cdict['green'].append([item, g1, g2])
            cdict['blue'].append([item, b1, b2])
    return mcolors.LinearSegmentedColormap('CustomMap', cdict)


c = mcolors.ColorConverter().to_rgb
rvb = make_colormap(
    [c('red'), c('violet'), 0.33, c('violet'), c('blue'), 0.66, c('blue')])
N = 1000
array_dg = np.random.uniform(0, 10, size=(N, 2))
colors = np.random.uniform(-2, 2, size=(N,))
plt.scatter(array_dg[:, 0], array_dg[:, 1], c=colors, cmap=rvb)
plt.colorbar()
plt.show()

enter image description here


顺便说一下,for-loop

for i in range(0, len(array_dg)):
  plt.plot(array_dg[i], markers.next(),alpha=alpha[i], c=colors.next())

为每次调用plt.plot绘制一个点。这对于少量的点有效,但对于许多点会变得非常缓慢。plt.plot只能绘制一种颜色,但是plt.scatter可以为每个点指定不同的颜色。因此,plt.scatter是一条路。

由于在其他答案中使用的方法对于这样简单的任务来说似乎相当复杂,因此这里有一个新的答案:

与生成离散颜色映射的ListedColormap不同,您可以使用LinearSegmentedColormap。这可以使用from_list方法从列表中轻松创建。

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

x,y,c = zip(*np.random.rand(30,3)*4-2)

norm=plt.Normalize(-2,2)
cmap = matplotlib.colors.LinearSegmentedColormap.from_list("", ["red","violet","blue"])

plt.scatter(x,y,c=c, cmap=cmap, norm=norm)
plt.colorbar()
plt.show()

enter image description here


更一般地,如果您有一个值(例如[-2., -1, 2])和相应颜色(例如["red","violet","blue"])的列表,使得第n个值应该对应于第n个颜色,那么您可以规范化这些值并将它们作为元组提供给from_list方法。

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

x,y,c = zip(*np.random.rand(30,3)*4-2)

cvals  = [-2., -1, 2]
colors = ["red","violet","blue"]

norm=plt.Normalize(min(cvals),max(cvals))
tuples = list(zip(map(norm,cvals), colors))
cmap = matplotlib.colors.LinearSegmentedColormap.from_list("", tuples)

plt.scatter(x,y,c=c, cmap=cmap, norm=norm)
plt.colorbar()
plt.show()

enter image description here

如果您想自动创建一个通常用于surface plots的自定义发散颜色映射,那么这个模块与@unutbu方法相结合,对我来说很好。

def diverge_map(high=(0.565, 0.392, 0.173), low=(0.094, 0.310, 0.635)):
    '''
    low and high are colors that will be used for the two
    ends of the spectrum. they can be either color strings
    or rgb color tuples
    '''
    c = mcolors.ColorConverter().to_rgb
    if isinstance(low, basestring): low = c(low)
    if isinstance(high, basestring): high = c(high)
    return make_colormap([low, c('white'), 0.5, c('white'), high])

高值和低值可以是字符串颜色名称或rgb元组。这是使用surface plot demo的结果: enter image description here

相关问题 更多 >