Matplotlib:如何为数组中的每个特定值选择颜色?

时间:2018-01-02 19:40:56

标签: python matplotlib graph

我搜索并发现我可以创建一个色彩图,但我觉得这对我想做的事情来说太过分了。 这是我的代码:

import numpy as np
import matplotlib.pyplot as plt
A=[1,1,1,1,1]
B=[0,0,0,0,0]
C=[0,0,3,0,0]
D=[0,0,0,0,0]
E=[2,2,2,2,2]
plateau=np.array([E,D,C,B,A])

def aff_graph():
    ax=np.arange(-0.5,5,1)
    plt.matshow(plateau)
    for z in ax:
        plt.plot((z,z),(ax[0],ax[5]),'k-')
        plt.plot((ax[0],ax[5]),(z,z),'k-')
    plt.axis('off')
    plt.show()

它给了我这个:graph

但实际上我想这样设置:

0→白

1→绿色

2→红色

3→黑

我只需要这个,而不是某个时间间隔内的值的颜色映射。我怎么能以最简单的方式做到?

奖金问题:有没有办法让所有方块都变白,里面有彩色圆圈?由于它是游戏的板,我认为它会更好地传达。 谢谢!

2 个答案:

答案 0 :(得分:3)

可以通过以下方式实现:

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

A=[1,1,1,1,1]
B=[0,0,0,0,0]
C=[0,0,3,0,0]
D=[0,0,0,0,0]
E=[2,2,2,2,2]

plateau=np.array([E,D,C,B,A])

c = mpl.colors.ListedColormap(['white', 'green', 'red', 'black'])
n = mpl.colors.Normalize(vmin=0,vmax=3)

def aff_graph():
    ax=np.arange(-0.5,5,1)
    plt.matshow(plateau,cmap=c,norm=n)
    for z in ax:
        plt.plot((z,z),(ax[0],ax[5]),'k-')
        plt.plot((ax[0],ax[5]),(z,z),'k-')
    plt.axis('off')
    plt.show()
aff_graph()

我添加了两行代码:第一行使用您询问的颜色创建所需的色彩映射。有了它,你的例子已经可以正常工作了。

但是,让我们说给定的高原不包含数字3,而只包含0s,1s和2s。这将导致以下不期望的颜色分配:

  

0→白色
1→红色2→黑色

我添加的第二行处理了这个问题。它定义了要使用的规范化,确保颜色方案是可靠的。如果所有四种颜色都在那里,你可能甚至不需要它(不知道游戏是如何工作的)。

当然,请确保在调用 matshow 时设置 cmap norm 选项。现在,即使并非所有颜色都存在,您仍然可以得到您想要的结果: enter image description here

答案 1 :(得分:1)

我只参加红利问题:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches


A=[1,1,1,1,1]
B=[0,0,0,0,0]
C=[0,0,3,0,0]
D=[0,0,0,0,0]
E=[2,2,2,2,2]
plateau=np.array([E,D,C,B,A])

plt.figure()
plt.axis('off')
plt.gca().set(aspect='equal')

for i in range(6):
    plt.plot([i,i],[0,5],'k')
    plt.plot([0,5],[i,i],'k')

for i1 in range(5):
    for i2 in range(5):
        color_idx = plateau[i1, i2]
        if color_idx == 1:
            plt.gca().add_patch(mpatches.Circle((i2+0.5,i1+0.5), 0.3, fc='green'))
        if color_idx == 2:
            plt.gca().add_patch(mpatches.Circle((i2+0.5,i1+0.5), 0.3, fc='red'))
        if color_idx == 3:
            plt.gca().add_patch(mpatches.Circle((i2+0.5,i1+0.5), 0.3, fc='black'))    

plt.show()

给出了

this

编辑:

为了能够更新图形,您可以将圆形图绘制成一个函数。每次调用该函数时,它应首先删除所有旧圆圈,然后再绘制新函数,如下所示:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
from time import sleep

# initialize figure and grid
fig = plt.figure()
plt.axis('off')
plt.gca().set(aspect='equal')
for i in range(6):
    plt.plot([i,i], [0,5], 'k')
    plt.plot([0,5], [i,i], 'k')


def draw_circles(plateau):
    # remove all circles
    for child in plt.gca().get_children():
        if type(child).__name__ == 'Circle':
            child.remove()

    # draw new circles
    for i1 in range(5):
        for i2 in range(5):
            color_idx = plateau[i1, i2]
            if color_idx == 1:
                circle = mpatches.Circle((i2+0.5, i1+0.5), 0.3, fc='green')
            if color_idx == 2:
                circle = mpatches.Circle((i2+0.5, i1+0.5), 0.3, fc='red')
            if color_idx == 3:
                circle = mpatches.Circle((i2+0.5, i1+0.5), 0.3, fc='black')
            plt.gca().add_patch(circle)

    plt.show(block=False)


# draw for first time
A = [1,1,1,1,1]
B = [0,0,0,0,0]
C = [0,0,3,0,0]
D = [0,0,0,0,0]
E = [2,2,2,2,2]
draw_circles(plateau=np.array([E, D, C, B, A]))

# update after some time
sleep(2)
A = [1,1,1,1,1]
B = [0,0,3,0,0]
C = [0,0,0,0,0]
D = [0,0,0,0,0]
E = [2,2,2,2,2]
draw_circles(plateau=np.array([E, D, C, B, A]))

plt.show()

你可以每隔n秒调用一次这个函数,或者让它由某种事件触发,比如某个按钮点击回调左右。但是我需要补充一点,我并不是真的理解plt.show(block=False)命令的行为,事实上,在数字冻结之前,我无法重绘两次以上的数字...如果你有也有问题,可能值得问一个单独的问题。