You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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去除插值但没成功,想知道:

  1. 如何绘制出符合需求的图表(保留缺失数据区域,不全局覆盖)
  2. 如何忽略密度为负的行或把这些行设为NaN
  3. 如何用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 13:05:01