如何在 matplotlib 中的颜色图上强制添加颜色?

How do I force a color on top of a colormap in matplotlib?

我正在开发一款 0 人游戏,其中一个“生物”在地图上移动吃食物以求生存,每转一圈都会消耗能量,吃食物会增加能量。食物地图是一个随机生成的二维 numpy 数组,每个位置上都有随机数量的食物。

food = np.random.randint(0, high=8, size=[10,10])

当生物吃食物时,该位置的食物价值会相应降低。

该生物是一个具有变量“id”、“energy”、“xpos”和“ypos”的对象。 id 是一个整数,表示该生物的“名称”。 (我最终希望这个游戏有多个生物相互竞争。)

class Creature:
    def __init__(self, xpos,ypos, energy):
        self.id = 1
        self.xpos = xpos
        self.ypos = ypos
        self.energy = energy

程序在一个循环中运行,每回合消耗生物 1 点能量。如果它的能量低于某个值,它就会感到饥饿,并试图找到一个有食物的位置,然后开始吃。当生物吃食物时,该位置的食物价值会降低。

我正在尝试使用 matplotlib 直观地显示它。我目前使用它来创建食物的热图,并单独创建一个显示生物位置的网格:

def colormap(data):
    fig, ax = plt.subplots()
    ax.imshow(data)    
    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()

我想用一种与食物地图所用颜色不同的颜色来覆盖食物地图顶部的生物位置。

我不知道下一步该去哪里。也许 matplotlib 不是在这里使用的正确工具。

这是我用来生成两个不同网格的最少代码;一个显示地图上食物的价值,第二个显示该生物的位置。我希望该生物以红色等颜色覆盖在食物地图上,而不管该位置的食物价值。

感谢您的帮助,我意识到我的方法可能有偏差

#Import modules
import random 
import matplotlib.pyplot as plt
import numpy as np

#Create a heatmap grid from an array
def colormap(data):
    fig, ax = plt.subplots()
    ax.imshow(data)    
    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()

#Creatue a new creature object
class Creature:
    def __init__(self,ID, xpos,ypos,energy):
        self.id = 1
        self.xpos = xpos
        self.ypos = ypos
        self.energy = energy


#Create the variables of that creature
xpos = random.randint(0,9)
ypos = random.randint(0,9)
energy = (10)

   

#Now that random attributes have been chosed and it has found a unique location, it spawns
newcreature = Creature(id,xpos,ypos,energy)

#Create an array to hold the ID of the creature occupying each space
occupant = np.full((10,10),0)

#creatue food map
food = np.random.randint(0, high=8, size=[10,10])


#Write the ID of the creature to the map of creature occupying that place in the map
occupant[newcreature.xpos,newcreature.ypos] = newcreature.id

#Display the food map
colormap(food)

#Display the creature map
colormap(occupant)

如果 frame-per-second 不打扰您,Matplotlib 可能是完成这项工作的工具。

你非常接近你的objective:你需要使用颜色图作为食物图,并使用散点图来覆盖生物的位置(还需要使用颜色图来指示能量水平) .下面是修改后的代码,为了让大家更好的理解,我做了注释:

import random 
import matplotlib.pyplot as plt
from matplotlib.colors import Normalize
import matplotlib.cm as cm
import numpy as np

#Create a heatmap grid from an array
def colormap(data, cmap_food, norm_food, pos, energy_cmap, norm_energy, current_energy):
    fig, ax = plt.subplots()
    img = ax.imshow(data, cmap=cmap_food, norm=norm_food)    
    s = ax.scatter(*pos, s=150, cmap=energy_cmap, norm=norm_energy, c=current_energy, label="energy")
    ax.grid(which='major', axis='both', linestyle='-', color='k', linewidth=2)
    cb_energy = fig.colorbar(s)
    cb_energy.set_label("Energy", rotation=90)
    cb_food = fig.colorbar(img)
    cb_food.set_label("Food", rotation=90)
    ax.set_xticks(np.arange(-.5, 10, 1));
    ax.set_yticks(np.arange(-.5, 10, 1));
    plt.show()

#Creatue a new creature object
class Creature:
    def __init__(self,ID, xpos,ypos,energy):
        self.id = 1
        self.xpos = xpos
        self.ypos = ypos
        self.energy = energy


#Create the variables of that creature
xpos = random.randint(0,9)
ypos = random.randint(0,9)
energy = 10

#Now that random attributes have been chosed and it has found a unique location, it spawns
newcreature = Creature(id,xpos,ypos,energy)

#creatue food map
max_food = 8
food = np.random.randint(0, high=max_food, size=[10,10])

# colormap used to visualize food
# You can explore more colormaps at:
# https://matplotlib.org/stable/tutorials/colors/colormaps.html
cmap_food = cm.YlGn

# Normalize the colors
# If we think that the food colormap is too intesense, we can either
# change the food colormap, or increase vmax to a number greater than
# max_food.
# Maybe, we would like the minimum food location not to be white:
# then we can change vmin to a negative number.
norm_food = Normalize(vmin=0, vmax=max_food)

# Choose an appropriate colormap, one that should be visible at
# every energy/food level on top of the food colormap.
energy_cmap = cm.cool_r
# normalize the energy of the creature between the minimum and maximum
norm_energy = Normalize(vmin=0, vmax=energy)
# position of the creature
pos = (newcreature.xpos, newcreature.ypos)

#Display the food map
colormap(food, cmap_food, norm_food, pos, energy_cmap, norm_energy, newcreature.energy)

理解这段代码后,您就可以开始选择更好的颜色图并在 Normalize 对象中设置更好的值。