将特定字符串值映射到中的特定颜色matplotlib.pyplot.imshow()

2024-09-30 04:31:19 发布

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

我有一个pandas.dataframe,看起来像这样:

columns    0    1   2   3   4   5
           A    A   A   A   B   B
           B    B   B   C   C   D
           D    D   E   E   F   F

我想使用pyplot.imshow()绘制此图,并指定以下颜色映射:

^{pr2}$

如果我正在绘制barscatter,我可以用参数color=a_list_of_colors调用,但这对imshow()无效。在

相反,我需要调用一个cmap,但据我所知,不可能创建一个cmap,其中特定的颜色映射到一个值。在

这意味着我需要创建如下颜色贴图:

    from matplotlib.colors import ListedColormap 

    _colors = ["#DA291E", "DA291E", "DA291E", "DA291E" 
               "#83DF39", "#83DF39", "#83DF39", "#83DF39", "#83DF39", #...and so on]
    cmap = ListedColormap(_colors, name="custom_cmap")

但是有没有更好的方法来解决这个问题呢?在


我以为我可以实现上述方法,但由于某些原因,它不起作用,我似乎不知道为什么。在

我首先根据上面我的series长版本创建一个颜色列表,然后将该列表转换为颜色映射:

color_list = list(series.map(color_dict))
custom_cmap = ListedColormap(color_list, name="custom_cmap")

series基本上如下所示:

A
A
A
A
B
B
B
B
B
C
#...and so on

我的df中的第五个元素是B,当我打印custom_cmap.__dict__.colors[4]时,我得到了#83DF39,它与我的df中的字符串值B相对应。所以地图是正确的。在

当我用cmap=custom_cmap调用plt.imshow()时,问题就出现了,因为它没有跟随cmap某些值的颜色不正确。在

我的第一个想法是我弄乱了顺序,这意味着color_list没有遵循{}的顺序,但它确实是这样。在

上面的df包含18个值,颜色列表也包含18个值。df中的最后一个值是F,这意味着color_list中的最后一个颜色应该是#52BFEC,它就是这样。在


添加更多代码。在

# Begin by converting strings to any number since plt.imshow() needs numbers
float_dict = {
    'A': 0.0,
    'B': 1.0,
    'C': 2.0,
    'D': 3.0,
    'E': 4.0,
    'F': 5.0,
    'G': 6.0,
    'H': 7.0,
    'I': 8.0
}

converted_series = series.map(float_dict).copy()

# Map each float to a specific color
color_dict = {
    0.0: '#DA291E',
    1.0: '#E7112d',
    2.0: '#83CD39',
    3.0: '#009934',
    4.0: '#007AB3',
    5.0: '#54BDEC',
    6.0: '#000066',
    7.0: '#DDDD11',
    8.0: '#572B84',
}

# Create a cmap from a color list
color_list = list(converted_series.map(color_dict))
custom_cmap = ListedColormap(color_list, name="custom_cmap")

# Widen the series into a df
df = series_to_wide_df(converted_series, n_columns=8)

# Plot it
plt.imshow(df, cmap=custom_cmap, interpolation='none')

上面的结果如下图所示。在

enter image description here

  • 请注意,此图像中的数据与原始文章中df中的数据不同。在

我测试了一个不同的color_dict

color_dict = {
    0.0: '#FF0000',
    1.0: '#FF0000',
    2.0: '#FF0000',
    3.0: '#FF0000',
    4.0: '#FF0000',
    5.0: '#000000',
    6.0: '#000000',
    7.0: '#000000',
    8.0: '#000000'
}

但是颜色仍然不能正确映射。使用这些颜色,1.02.06.07.0和一些{}得到红色。在


Tags: namedf列表颜色customdictlistcolor
1条回答
网友
1楼 · 发布于 2024-09-30 04:31:19

如果没有自己运行的话,很难看到建议的代码出了什么问题。在

下面将创建一个将字母映射到数字的字典,并将其应用于dataframe。然后它将创建一个colormap,其中包含数据帧中(可能的)值的尽可能多的颜色。然后,当colormap在0和colormap中的元素数量之间被规范化时,使用imshow进行绘图可以很好地工作。(如果并非所有可能的值都实际出现在要绘制的特定数据帧中,例如字母A和H将丢失,则此规范化可能有用。)

import numpy as np; np.random.seed(42)
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap


df = pd.DataFrame(np.random.choice(list("ABCDEFGH"), size=(8,8)))
print(df)

#mapping from letters to numbers
letter2num = dict(zip(list("ABCDEFGH"), np.arange(8)))
df2 = pd.DataFrame(np.array( [letter2num[i] for i in df.values.flat] ).reshape(df.shape))


#produce colormap with as many colors as there are unique values in df
colors = ["pink", "red", "violet", "blue", 
          "turquoise", "limegreen", "gold", "brown"]  # use hex colors here, if desired.
cmap = ListedColormap(colors)

fig, ax = plt.subplots()
ax.imshow(df2.values, vmin=0, vmax=len(cmap.colors), cmap=cmap)


for i in range(len(df2)):
    for j in range(len(df2.columns)):
        ax.text(j,i, df.values[i,j], ha="center", va="center")
plt.show()

enter image description here

相关问题 更多 >

    热门问题