当前位置: 首页 > 面试题库 >

Python:从matplotlib热图及其图例中保留Numpy NaN值

卫招
2023-03-14
问题内容

我有一个numpy数组,需要将其绘制为热图。numpy数组还将包含NaN值,我需要从绘图中排除这些值。在其他帖子中,有人告诉我numpy会自动遮盖图中的NaN值,但是它对我不起作用。这是示例代码

column_labels = list('ABCDEFGH')
row_labels = list('WXYZ')
fig, ax = plt.subplots()
data = np.array([[ 0.96753494,  0.52349944,  0.0254628 ,  0.5104103 ],
         [ 0.07320069,  0.91278731,  0.97094436,  0.70533351],
         [ 0.30162006,  0.49068337,  0.41837729,  0.71139215],
         [ 0.19786101,  0.15882713,  0.59028841,  0.06242765],
         [ 0.51505872,  0.07798389,  0.58790067,  0.44782683],
         [ 0.68975694,  0.53535385,  0.15696023,  0.35641951],
         [ 0.66481995,  0.03576846,  0.9623601 ,  0.96006395],
         [ 0.45865404,  0.50433582,  0.18182575,  0.35126449],])

data[3,:] = np.nan
heatmap = ax.pcolor(data, cmap=plt.cm.seismic)

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

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

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

我想完全避免图例中的NaN值,最好用一些符号(例如 X) 标记它。我怎样才能做到这一点?


问题答案:

所述nans干扰pcolor确定包含在值的范围data,因为

In [72]: data.min(), data.max()
Out[72]: (nan, nan)

您可以通过声明自己使用的值范围来解决此问题,np.nanminnp.nanmax在以下位置找到最小和最大的非NaN值data

heatmap = ax.pcolor(data, cmap=plt.cm.seismic, 
                    vmin=np.nanmin(data), vmax=np.nanmax(data))

以来

In [73]: np.nanmin(data), np.nanmax(data)
Out[73]: (0.025462800000000001, 0.97094435999999995)
import numpy as np
import matplotlib.pyplot as plt

column_labels = list('ABCDEFGH')
row_labels = list('WXYZ')
fig, ax = plt.subplots()
data = np.array([[ 0.96753494,  0.52349944,  0.0254628 ,  0.5104103 ],
         [ 0.07320069,  0.91278731,  0.97094436,  0.70533351],
         [ 0.30162006,  0.49068337,  0.41837729,  0.71139215],
         [ 0.19786101,  0.15882713,  0.59028841,  0.06242765],
         [ 0.51505872,  0.07798389,  0.58790067,  0.44782683],
         [ 0.68975694,  0.53535385,  0.15696023,  0.35641951],
         [ 0.66481995,  0.03576846,  0.9623601 ,  0.96006395],
         [ 0.45865404,  0.50433582,  0.18182575,  0.35126449],])

data[3,:] = np.nan
heatmap = ax.pcolor(data, cmap=plt.cm.seismic, 
                    vmin=np.nanmin(data), vmax=np.nanmax(data))
heatmap.cmap.set_under('black')

bar = fig.colorbar(heatmap, extend='both')

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

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

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

另一个选择基于JoeKington的解决方案是在dataNaN处绘制带有阴影线的矩形补丁。

上面的示例显示,pcolor具有NaN值的单元格中的颜色好像NaN都是非常负的数字。相反,如果你传递pcolor一个 蒙面阵列
pcolor叶蒙版区域透明。因此,您可以在轴背景色块上绘制阴影ax.patch,以在被遮罩的区域上显示阴影。

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

column_labels = list('ABCDEFGH')
row_labels = list('WXYZ')
fig, ax = plt.subplots()
data = np.array([[ 0.96753494,  0.52349944,  0.0254628 ,  0.5104103 ],
         [ 0.07320069,  0.91278731,  0.97094436,  0.70533351],
         [ 0.30162006,  0.49068337,  0.41837729,  0.71139215],
         [ 0.19786101,  0.15882713,  0.59028841,  0.06242765],
         [ 0.51505872,  0.07798389,  0.58790067,  0.44782683],
         [ 0.68975694,  0.53535385,  0.15696023,  0.35641951],
         [ 0.66481995,  0.03576846,  0.9623601 ,  0.96006395],
         [ 0.45865404,  0.50433582,  0.18182575,  0.35126449],])

data[3,:] = np.nan
data = np.ma.masked_invalid(data)

heatmap = ax.pcolor(data, cmap=plt.cm.seismic, 
                    vmin=np.nanmin(data), vmax=np.nanmax(data))
# https://stackoverflow.com/a/16125413/190597 (Joe Kington)
ax.patch.set(hatch='x', edgecolor='black')
fig.colorbar(heatmap)

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

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

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

如果您希望使用多种阴影线标记,例如对NaN说一种,对负值说另一种,那么您可以使用循环来添加阴影阴影的矩形:

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

column_labels = list('ABCDEFGH')
row_labels = list('WXYZ')
fig, ax = plt.subplots()
data = np.array([[ 0.96753494,  0.52349944,  0.0254628 ,  0.5104103 ],
         [ 0.07320069,  0.91278731,  0.97094436,  0.70533351],
         [ 0.30162006,  0.49068337,  0.41837729,  0.71139215],
         [ 0.19786101,  0.15882713,  0.59028841,  0.06242765],
         [ 0.51505872,  0.07798389,  0.58790067,  0.44782683],
         [ 0.68975694,  0.53535385,  0.15696023,  0.35641951],
         [ 0.66481995,  0.03576846,  0.9623601 ,  0.96006395],
         [ 0.45865404,  0.50433582,  0.18182575,  0.35126449],])
data -= 0.5
data[3,:] = np.nan
data = np.ma.masked_invalid(data)
heatmap = ax.pcolor(data, cmap=plt.cm.seismic, 
                    vmin=np.nanmin(data), vmax=np.nanmax(data))

# https://stackoverflow.com/a/16125413/190597 (Joe Kington)
ax.patch.set(hatch='x', edgecolor='black')

# draw a hatched rectangle wherever the data is negative
# http://matthiaseisen.com/pp/patterns/p0203/
mask = data < 0
for j, i in np.column_stack(np.where(mask)):
      ax.add_patch(
          mpatches.Rectangle(
              (i, j),     # (x,y)
              1,          # width
              1,          # height
              fill=False, 
              edgecolor='blue',
              snap=False,
              hatch='x' # the more slashes, the denser the hash lines 
          ))

fig.colorbar(heatmap)

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

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

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


 类似资料:
  • 如何在IPython笔记本内的Matplotlib中将图例添加到xy线图中?我目前的尝试: 这样做,我得到以下错误: /Users/mc/.virtualenvs/kaggle/lib/python2.7/site-packages/matplotlib/legend.py:613:用户警告:图例不支持[]使用代理艺术家代替。 http://matplotlib.sourceforge.net/u

  • 问题内容: 我用这里的数据,用seaborn和 熊猫。 代码: 从csv文件中可以看到,它包含3个离散值:0、-1和1。我 想要一个离散的图例而不是色条。将0标记为A、-1标记为B和1 作为C.我怎么做? 问题答案: 好吧,要做到这一点肯定不止一种方法。在这种情况下, 由于只需要三种颜色,我会选择自己的颜色创建一个 而不是使用“cubehelix\u palete”生成它们。 如果有足够的颜色来保

  • 本文向大家介绍python读取tif图片时保留其16bit的编码格式实例,包括了python读取tif图片时保留其16bit的编码格式实例的使用技巧和注意事项,需要的朋友参考一下 tif图片的编码格式一般是16bit的,在使用python-opencv读取tif文件时,为了保留其编码格式,我们需要用以下的方式: 输出结果为:uint16 对于opencv中imread函数最后的参数解释如下: 当参

  • 听起来像一个简单的任务,但它并不工作,我不知道我做错了什么。我正在尝试创建一个关联热图。我使用下面的代码: 根本没有发生任何事情。当我执行以下操作时: 我得到的输出为: 有人能帮我理解吗?

  • 问题内容: 我有一组X,Y数据点(约10k),很容易将其绘制为散点图,但我想将其表示为热图。 我浏览了MatPlotLib中的示例,它们似乎都已经从热图单元格值开始以生成图像。 有没有一种方法可以将所有不同的x,y转换为热图(其中x,y的频率较高的区域会“变暖”)? 问题答案: 如果你不想要六角形,可以使用的函数: 这将产生的热图。如果你想要,则可以拨打。

  • 问题内容: 我有一个3元组的列表,表示3D空间中的一组点。我想绘制一个覆盖所有这些点的表面。mplot3d软件包中的plot_surface函数需要X,Y和Z作为二维数组作为参数。plot_surface是绘制表面的正确函数,如何将数据转换为所需格式? 问题答案: 对于曲面,它与三元组列表略有不同,您应该为2d数组中的域传递网格。 如果您只拥有3d点列表而不是某些函数f(x, y) -> z,那么