如何用Gnuplot绘制无插值带缺失数据的图及Python实现
问题描述
我有一个结构如下的.csv文件:
- 第1列:密度
- 第2列:海拔
- 第3列:纬度
- 第4列:经度
我需要绘制指定样式的图表,但当前用gnuplot生成的图表是全局覆盖效果,实际数据存在缺失;同时需要忽略密度为负的行。当前使用的gnuplot脚本如下:
set cntrparam levels auto set dgrid3d 150,100,4 set pm3d corners2color c1 set contour unset surface unset key set pm3d map set view map set lmargin 5 set rmargin 6 set tmargin 2 set bmargin 2 splot 'new.csv' using 3:2:1 with pm3d notitle
我尝试用set pm3d corners2color c1去除插值但没成功,想知道:
- 如何绘制出符合需求的图表(保留缺失数据区域,不全局覆盖)
- 如何忽略密度为负的行或把这些行设为NaN
- 如何用Python实现同样的绘图需求
Gnuplot 解决方案
1. 忽略密度为负的行
在using语句中加入条件判断,将负密度值替换为NaN,gnuplot会自动忽略NaN数据:
splot 'new.csv' using 3:2:($1 < 0 ? NaN : $1) with pm3d notitle
2. 关闭全局插值,保留缺失区域
你之前使用的set dgrid3d是强制生成规则网格并插值的命令,这正是导致图表全局覆盖的核心原因,直接移除这条命令即可:
set cntrparam levels auto # 移除set dgrid3d 150,100,4 set pm3d corners2color c1 set contour unset surface unset key set pm3d map set view map set lmargin 5 set rmargin 6 set tmargin 2 set bmargin 2 splot 'new.csv' using 3:2:($1 < 0 ? NaN : $1) with pm3d notitle
set pm3d corners2color c1的作用是用四边形角落颜色插值填充,但只有在关闭dgrid3d后,才会保留原始数据的缺失区域,不会强行补全整个画布。
如果需要更清晰区分缺失区域,可设置NaN区域的颜色:
set pm3d nancolor rgb "#cccccc" # 将缺失区域设为灰色
Python 解决方案
使用pandas处理数据,matplotlib绘图,以下是完整实现:
import pandas as pd import matplotlib.pyplot as plt from matplotlib.colors import Normalize # 1. 读取数据 df = pd.read_csv('new.csv', header=None, names=['density', 'altitude', 'latitude', 'longitude']) # 2. 过滤负密度数据,转为缺失值 df['density'] = df['density'].where(df['density'] >= 0, pd.NA) # 3. 方案1:绘制离散散点图 fig, ax = plt.subplots(figsize=(10, 6)) scatter = ax.scatter(df['longitude'], df['latitude'], c=df['density'], cmap='viridis', norm=Normalize()) plt.colorbar(scatter, label='密度') # 方案2:绘制三角剖分插值面图(仅在有数据区域生成,保留缺失区域) # fig, ax = plt.subplots(figsize=(10, 6)) # contour = ax.tricontourf(df['longitude'], df['latitude'], df['density'], cmap='viridis', levels=20) # plt.colorbar(contour, label='密度') # 设置坐标轴与标题 ax.set_xlabel('经度') ax.set_ylabel('纬度') ax.set_title('密度分布') plt.tight_layout() plt.show()
补充说明
- 若为地理坐标数据,可搭配
cartopy添加地图底图,替换绘图初始化代码:import cartopy.crs as ccrs fig, ax = plt.subplots(figsize=(10, 6), subplot_kw={'projection': ccrs.PlateCarree()}) ax.coastlines() # 添加海岸线 tricontourf基于现有数据做三角剖分插值,只会在有数据的区域生成面,不会覆盖全局,完美适配缺失数据场景。
内容的提问来源于stack exchange,提问作者Rabia Sönmez
相关产品推荐
相关产品推荐

