matplotlib imshow一个数据矩阵有白色,画一个函数y=f(x)的热图

vhmi4jdf  于 2023-03-09  发布在  其他
关注(0)|答案(1)|浏览(151)

我想画一个函数y = f(x)的热图,y在[0,1]中,x在[0,2]中,当x〈= 1时,f(x)=1;并且当x〉1时,f(x)= y。
首先,我生成了一个网格大小为0. 1的数据矩阵,看起来很好,但是我想让颜色变化平滑,所以我把网格大小减小到了0. 02和0. 01,奇怪的是现在图上出现了一些怪异的白色。
我在网上搜索了一些解决方案(例如How to get rid of white lines in confusion matrix?),比如plt.grid(None)ax.grid(None)plt.rcParams["axes.grid"] = False。我尝试了所有的解决方案,但是没有一个适合我。下面是我在gridsize = 0.01时绘制Map的代码。

import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap, LinearSegmentedColormap
plt.rcParams["axes.grid"] = False

if __name__ == '__main__':

    heat_results = np.empty((101, 101))
    heat_results[:, :] = np.nan
    for x in np.arange(0.0, 1.01, 0.01):
         for y in np.arange(0.0, 2.02, 0.02):
              ind_x = int(x*100)
              ind_y = int(y*50)
              if y <= 1.0: heat_results[ind_x][ind_y] = 1.0
              else: heat_results[ind_x][ind_y] = x

    minv = np.nanmin(heat_results)
    maxv = np.nanmax(heat_results)

    # print('minv, maxv:')

    # print(minv)
    # print(maxv)

    colors = ["lime", "saddlebrown"]
    cmap = LinearSegmentedColormap.from_list("mycmap", colors)

    heat_results = (heat_results - minv) / (maxv - minv)

    fig, ax = plt.subplots()
    ax.grid(False)
    plt.grid(None)
    plt.grid(False)
    im = ax.imshow(heat_results, origin='lower',cmap=cmap)
    ax.grid(False)
    plt.grid(None)
    plt.grid(False)

    cbar = ax.figure.colorbar(im, ax=ax)

    plt.xticks(np.arange(0, 101, 10), np.array([0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0]))
    plt.yticks(np.arange(0, 101, 10), np.array([0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]))

    plt.xlabel('t')
    plt.ylabel('x')

    plt.savefig('fig/heat.pdf')
    plt.close()

我还附上了我的三个数字在这里,你可以看到白色是如何出现时,我减少步长(平滑颜色变化)。
关于为什么当我减小网格大小时会出现这些白色有什么想法吗?或者关于除了生成数据矩阵之外,如何绘制我之前描述的函数的热图有什么想法吗?基本上,我想要一个看起来像第一个图但颜色变化平滑的图(类似于颜色条中的颜色变化),并且图的左部和右部的分离正好发生在1.0处(图1不位于1.0处,因为网格尺寸太大)。

nvbavucw

nvbavucw1#

你的白色与网格无关。这些是NaN值,仍然在heat_results中。由于浮点近似误差,int(x*100)有时会得到一个较低的值。在你的情况下,你可以使用int(round(x*100)),但最好完全使用numpy函数。这些函数速度更快(一旦你习惯了,也更容易阅读)。
自动为热图设置刻度标签的推荐方法是使用extent=[x0,x1,y0,y1]
使用numpy的broadcasting可以简化填充数组,对于if测试,numpy使用np.where

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

x = np.linspace(0, 1, 101)
y = np.linspace(0, 2, 101)
ys, xs = np.meshgrid(y, x)

heat_results = np.where(ys <= 1, 1.0, xs)

colors = ["lime", "saddlebrown"]
cmap = LinearSegmentedColormap.from_list("mycmap", colors)

fig, ax = plt.subplots()
im = ax.imshow(heat_results, origin='lower', cmap=cmap, extent=[y.min(), y.max(), x.min(), x.max()], aspect='auto')

cbar = ax.figure.colorbar(im, ax=ax)

plt.xlabel('t')
plt.ylabel('x')
plt.show()

相关问题