matplotlib-绘制热图/像素图,能够编辑单个像素颜色(按行绘制不同的颜色图)

matplotlib-绘制热图/像素图,能够编辑单个像素颜色(按行绘制不同的颜色图),matplotlib,highlight,heatmap,Matplotlib,Highlight,Heatmap,我正在尝试使用matplotlib绘制矩阵的热图/像素图表示。我目前有以下代码,根据需要提供像素图(改编自): 它给出了以下曲线图: 但是,我想扩展这一点,以便在鼠标单击时,我可以以绿色突出显示像素图中的一行,例如,如果用户选择了行“C”,我会这样做(我知道对于值为0的像素,绿色突出显示不清晰): 我知道如何处理鼠标事件,但我不知道如何修改pixelmap中一行的颜色。如果我可以为像素地图的各个像素设置标签,以便在鼠标单击时检索,而不是使用鼠标x/y位置为标签列表编制索引,这也会有所帮助。在

我正在尝试使用matplotlib绘制矩阵的热图/像素图表示。我目前有以下代码,根据需要提供像素图(改编自):

它给出了以下曲线图:

但是,我想扩展这一点,以便在鼠标单击时,我可以以绿色突出显示像素图中的一行,例如,如果用户选择了行“C”,我会这样做(我知道对于值为0的像素,绿色突出显示不清晰):


我知道如何处理鼠标事件,但我不知道如何修改pixelmap中一行的颜色。如果我可以为像素地图的各个像素设置标签,以便在鼠标单击时检索,而不是使用鼠标x/y位置为标签列表编制索引,这也会有所帮助。

在这个问题的帮助下,我已经解决了自己的问题:

代码如下,注释应清楚地解释所采取的步骤

import matplotlib.pyplot as plt
import numpy as np
from numpy.ma import masked_array
import matplotlib.cm as cm
from matplotlib.ticker import AutoMinorLocator

column_labels = list('ABCD')
row_labels = list('0123')
data = np.array([[0,1,2,0],
                 [1,0,1,1],
                 [1,2,0,0],
                 [0,0,0,1]])

fig, ax = plt.subplots()

# List to keep track of handles for each pixel row
pixelrows = []

# Lets create a normalizer for the whole data array
norm = plt.Normalize(vmin = np.min(data), vmax = np.max(data))

# Let's loop through and plot each pixel row
for i, row in enumerate(data):
    # First create a mask to ignore all others rows than the current
    zerosarray = np.ones_like(data)
    zerosarray[i, :] = 0

    plotarray = masked_array(data, mask=zerosarray)

    # If we are not on the 3rd row down let's use the red colormap
    if i != 2:
        pixelrows.append(ax.matshow(plotarray, norm=norm, cmap=cm.Reds))

    # Otherwise if we are at the 3rd row use the green colormap
    else:
        pixelrows.append(ax.matshow(plotarray, norm=norm, cmap=cm.Greens))

# put the major ticks at the middle of each cell
ax.set_xticks(np.arange(data.shape[0]), minor=False)
ax.set_yticks(np.arange(data.shape[1]), minor=False)

# want a more natural, table-like display
ax.xaxis.tick_top()

ax.set_xticklabels(row_labels, minor=False)
ax.set_yticklabels(column_labels, minor=False)

ax.yaxis.grid(True, which='minor', linestyle='-', color='k', linewidth = 0.3, alpha = 0.5)
ax.xaxis.grid(True, which='minor', linestyle='-', color='k', linewidth = 0.3, alpha = 0.5)

# Set the location of the minor ticks to the edge of pixels for the x grid
minor_locator = AutoMinorLocator(2)
ax.xaxis.set_minor_locator(minor_locator)

# Lets turn of the actual minor tick marks though
for tickmark in ax.xaxis.get_minor_ticks():
    tickmark.tick1On = tickmark.tick2On = False

# Set the location of the minor ticks to the edge of pixels for the y grid
minor_locator = AutoMinorLocator(2)
ax.yaxis.set_minor_locator(minor_locator)

# Lets turn of the actual minor tick marks though
for tickmark in ax.yaxis.get_minor_ticks():
    tickmark.tick1On = tickmark.tick2On = False

plt.show()
import matplotlib.pyplot as plt
import numpy as np
from numpy.ma import masked_array
import matplotlib.cm as cm
from matplotlib.ticker import AutoMinorLocator

column_labels = list('ABCD')
row_labels = list('0123')
data = np.array([[0,1,2,0],
                 [1,0,1,1],
                 [1,2,0,0],
                 [0,0,0,1]])

fig, ax = plt.subplots()

# List to keep track of handles for each pixel row
pixelrows = []

# Lets create a normalizer for the whole data array
norm = plt.Normalize(vmin = np.min(data), vmax = np.max(data))

# Let's loop through and plot each pixel row
for i, row in enumerate(data):
    # First create a mask to ignore all others rows than the current
    zerosarray = np.ones_like(data)
    zerosarray[i, :] = 0

    plotarray = masked_array(data, mask=zerosarray)

    # If we are not on the 3rd row down let's use the red colormap
    if i != 2:
        pixelrows.append(ax.matshow(plotarray, norm=norm, cmap=cm.Reds))

    # Otherwise if we are at the 3rd row use the green colormap
    else:
        pixelrows.append(ax.matshow(plotarray, norm=norm, cmap=cm.Greens))

# put the major ticks at the middle of each cell
ax.set_xticks(np.arange(data.shape[0]), minor=False)
ax.set_yticks(np.arange(data.shape[1]), minor=False)

# want a more natural, table-like display
ax.xaxis.tick_top()

ax.set_xticklabels(row_labels, minor=False)
ax.set_yticklabels(column_labels, minor=False)

ax.yaxis.grid(True, which='minor', linestyle='-', color='k', linewidth = 0.3, alpha = 0.5)
ax.xaxis.grid(True, which='minor', linestyle='-', color='k', linewidth = 0.3, alpha = 0.5)

# Set the location of the minor ticks to the edge of pixels for the x grid
minor_locator = AutoMinorLocator(2)
ax.xaxis.set_minor_locator(minor_locator)

# Lets turn of the actual minor tick marks though
for tickmark in ax.xaxis.get_minor_ticks():
    tickmark.tick1On = tickmark.tick2On = False

# Set the location of the minor ticks to the edge of pixels for the y grid
minor_locator = AutoMinorLocator(2)
ax.yaxis.set_minor_locator(minor_locator)

# Lets turn of the actual minor tick marks though
for tickmark in ax.yaxis.get_minor_ticks():
    tickmark.tick1On = tickmark.tick2On = False

plt.show()