Python - 基于数值绘制彩色网格

21

我一直在这里和网上搜寻,虽然找到了与我所需内容类似的问题/回答,但仍未能达到我想要的结果。

我有一个长度为100的数组,数组中的值范围从0到100。

我想将此数组作为网格绘制出来,并根据数组中的值填充方格。

我目前发现的解决方案如下:

在matplotlib中绘制网格图案

自定义matplotlib图表:像棋盘一样的带有彩色单元格的表格

在我提到的例子中,颜色的范围是不固定的,而且颜色的种类也不同。

然而,我想知道的是,是否可以为特定的值和颜色设置范围?例如,如果值介于10和20之间,则让网格方格的颜色为红色。如果值介于20和30之间,则让颜色为蓝色,等等。

如何在Python中实现呢?

3个回答

58
你可以创建一个ListedColormap,用于自定义颜色,并使用BoundaryNorms来分段阈值处理这些值。

ListedColormapBoundaryNorms

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

data = np.random.rand(10, 10) * 20

# create discrete colormap
cmap = colors.ListedColormap(['red', 'blue'])
bounds = [0,10,20]
norm = colors.BoundaryNorm(bounds, cmap.N)

fig, ax = plt.subplots()
ax.imshow(data, cmap=cmap, norm=norm)

# draw gridlines
ax.grid(which='major', axis='both', linestyle='-', color='k', linewidth=2)
ax.set_xticks(np.arange(-.5, 10, 1));
ax.set_yticks(np.arange(-.5, 10, 1));

plt.show()

导致的结果; 带有BoundaryNorms的图形

更多内容,请查看此matplotlib示例


2

基于@umotto的答案,这里提供一个更为复杂的版本:

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

def plot_colored_grid(data, colors=['white', 'green'], bounds=[0, 0.5, 1], grid=True, labels=False, frame=True):
"""Plot 2d matrix with grid with well-defined colors for specific boundary values.

:param data: 2d matrix
:param colors: colors
:param bounds: bounds between which the respective color will be plotted
:param grid: whether grid should be plotted
:param labels: whether labels should be plotted
:param frame: whether frame should be plotted
"""

# create discrete colormap
cmap = mplt.colors.ListedColormap(colors)
norm = mplt.colors.BoundaryNorm(bounds, cmap.N)

# enable or disable frame
plt.figure(frameon=frame)

# show grid
if grid:
    plt.grid(axis='both', color='k', linewidth=2) 
    plt.xticks(np.arange(0.5, data.shape[1], 1))  # correct grid sizes
    plt.yticks(np.arange(0.5, data.shape[0], 1))

# disable labels
if not labels:
    plt.tick_params(bottom=False, top=False, left=False, right=False, labelbottom=False, labelleft=False) 
# plot data matrix
plt.imshow(data, cmap=cmap, norm=norm)

# display main axis 
plt.show()

如果您想绘制一个二进制矩阵,例如 plot_colored_grid(np.array([[True, False], [False, True]])),将会得到以下结果:
2x2 binary matrix
另外一个例子:
data = np.array([
    [9, 12, 24],
    [5, 2, 33],
    [27, 36, 15]
])

plot_colored_grid(data, colors=['white', 'green', 'purple', 'red'], bounds=[0, 10, 20, 30, 40])

这将导致:

3x3数据矩阵


这个例子帮助我从任意形状的二维数组中得到一个自定义的图表。 - mrtpk

0

这取决于您需要使用哪种单位来表示颜色,但只需一个简单的if语句即可解决问题。

def find_colour(_val):
    # Colour value constants
    _colours = {"blue": [0.0, 0.0, 1.0],
                "green": [0.0, 1.0, 0.00],
                "yellow": [1.0, 1.0, 0.0],
                "red": [1.0, 0.0, 0.0]}

    # Map the value to a colour
    _colour = [0, 0, 0]
    if _val > 30:
        _colour = _colours["red"]
    elif _val > 20:
        _colour = _colours["blue"]
    elif _val > 10:
        _colour = _colours["green"]
    elif _val > 0:
        _colour = _colours["yellow"]

    return tuple(_colour)

只需将该元组转换为所需的任何单位,例如 RGBA(..)。然后,您可以实现看起来已经找到的方法以实现网格。


1
谢谢你的回答。不过,我认为@umutto发布的方法更容易实现。老实说,我不知道如何在绘图中使用该函数(抱歉,我对Python不太了解)。 - philippos

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接