如何用Python的imshow实现不规则数据点的2D密度图?
用Python实现类似Mathematica的ListDensityPlot功能
我有一批(xi, yi, zi)形式的不规则数据点,想要绘制2D密度图。Mathematica中直接调用ListDensityPlot就能实现,但Python常用的imshow要求输入规则网格格式的数据。已经生成了对应数据,如何编写list_density_plot函数实现类似效果?
Mathematica示例代码
n = 100; xs = RandomReal[1, n]; ys = RandomReal[1, n]; zs = xs + ys; data = Table[{xs[[i]], ys[[i]], zs[[i]]}, {i, n}]; ListDensityPlot[data, PlotRange -> All, PlotLegends -> Automatic]
Python现有数据生成代码
import numpy as np def f(x, y): return x+y N = 100 xs = np.random.random(N) ys = np.random.random(N) zs = f(xs, ys) data = [(xs[i], ys[i], zs[i]) for i in range(N)] list_density_plot(data) # 需要实现这个函数
解决方案:通过插值将不规则数据转为规则网格
核心思路是用插值算法把散点数据转换为规则网格数据,再用imshow或pcolormesh绘制密度图。以下是完整的list_density_plot实现:
实现代码
import numpy as np import matplotlib.pyplot as plt from scipy.interpolate import griddata def list_density_plot(data, grid_size=100, cmap='viridis', show_points=False): # 提取x、y、z数据并转为numpy数组 xs, ys, zs = zip(*data) xs = np.array(xs) ys = np.array(ys) zs = np.array(zs) # 创建覆盖数据范围的规则网格 xi = np.linspace(xs.min(), xs.max(), grid_size) yi = np.linspace(ys.min(), ys.max(), grid_size) xi, yi = np.meshgrid(xi, yi) # 插值生成网格上的z值,可选插值方法:nearest/linear/cubic zi = griddata((xs, ys), zs, (xi, yi), method='cubic') # 绘制密度图 plt.figure(figsize=(8, 6)) im = plt.imshow(zi, extent=(xs.min(), xs.max(), ys.min(), ys.max()), origin='lower', cmap=cmap, aspect='auto') # 添加颜色条和标签 plt.colorbar(im, label='z值') plt.xlabel('x') plt.ylabel('y') plt.title('不规则数据点密度图') # 可选:显示原始数据点 if show_points: plt.scatter(xs, ys, c='white', s=15, alpha=0.6) plt.show()
调用示例
直接用你生成的data调用函数即可:
list_density_plot(data, grid_size=150, cmap='plasma', show_points=True)
插值方法说明
nearest:最近邻插值,速度最快,但结果最粗糙,适合快速预览linear:线性插值,平滑度中等,平衡速度和效果cubic:三次样条插值,结果最平滑,适合需要精细效果的场景,计算耗时稍长
内容的提问来源于stack exchange,提问作者an offer can't refuse
相关产品推荐
相关产品推荐

