Python处理csv文件,具有经纬度的站点数据配合shp文件在地图上绘制温度数据的填色图,无geopandas库
时间: 2025-07-05 17:43:37 浏览: 10
<think>好的,用户想用Python处理CSV文件里的站点数据,里面有经纬度和温度信息,然后用shp文件在地图上画温度填色图,但不能用geopandas库。我得想想怎么不用geopandas实现这个需求。
首先,处理CSV应该没问题,用pandas读取就可以了。然后,shp文件的话,可能需要其他库来读取,比如pyshp(shapefile库)。接着,绘制地图填色图,可能需要matplotlib和basemap或者cartopy?不过用户可能没有安装这些库,但cartopy安装起来可能有点麻烦,特别是如果不用geopandas的话,basemap可能已经过时了。不过basemap可能还是可以用的,虽然官方推荐cartopy了。或者有没有其他方法?
或者,不用这些地图库,直接用matplotlib的散点图或者tricontourf?比如,用站点经纬度生成三角网格,然后填充颜色。但这样可能无法和shp文件里的地理边界叠加。用户需要配合shp文件,所以必须得画出地理边界。
那可能需要用pyshp读取shp文件,获取边界的坐标,然后在matplotlib里画出这些边界线。比如,读取每个shape的points,然后plot出来。这样即使不用geopandas也能显示地理边界。
接下来,填色图的话,可以用griddata进行插值,生成网格数据,然后用contourf或者pcolormesh绘制。但需要注意投影的问题,如果shp文件和经纬度的投影不一致的话,可能会有偏差。但假设shp文件是WGS84的经纬度坐标,那可能可以直接用。
所以步骤大概是:
1. 读取CSV数据,获取经纬度和温度。
2. 读取shp文件,提取地理边界。
3. 创建网格,插值温度数据到网格。
4. 绘制填色图,叠加shp的边界。
现在检查需要哪些库:pandas、shapefile(pyshp)、matplotlib、numpy、scipy.interpolate.griddata。这些库都是比较常用的,应该没问题。
可能需要处理不同shapefile的结构,比如可能有多个记录,每个记录对应一个多边形,需要循环画出每个部分。
然后,关于插值,可能需要调整方法,比如线性插值或者立方插值,但用户可能需要根据数据情况调整。
另外,需要注意地图的范围,可能需要根据数据的经纬度范围来设定插值网格的范围和密度。
最后,确保颜色图例,坐标轴标签,标题等元素都正确显示。
可能遇到的问题:shp文件的投影不是经纬度,这时候直接绘制可能会变形,但用户提供的站点数据是经纬度,所以假设shp文件也是同样的坐标系。如果不同的话,可能需要转换,但不用geopandas的话可能比较麻烦,这里暂时假设是相同的。
现在,将这些步骤整理成代码框架,并给出必要的解释。确保每个步骤清晰,用户能理解如何替换自己的文件路径和参数。</think>以下是使用Python处理CSV和SHP文件绘制温度填色图的步骤,**无需geopandas**,基于`matplotlib`、`pyshp`和`scipy`实现:
---
### **1. 准备工具库**
安装所需库:
```bash
pip install pandas matplotlib pyshp numpy scipy
```
---
### **2. 读取CSV站点数据**
使用`pandas`读取含经纬度和温度的CSV文件:
```python
import pandas as pd
# 读取CSV文件(假设列名为lon, lat, temp)
df = pd.read_csv('stations.csv')
lons = df['lon'].values
lats = df['lat'].values
temps = df['temp'].values
```
---
### **3. 读取SHP边界文件**
使用`pyshp`解析地理边界:
```python
import shapefile
# 读取SHP文件
sf = shapefile.Reader("map_boundary.shp")
# 提取所有边界的坐标
shapes = sf.shapes()
for shape in shapes:
parts = shape.parts # 多边形的分段索引
points = shape.points # 所有点的坐标
# 处理每个多边形(例如闭合曲线)
for i in range(len(parts)):
start = parts[i]
if i < len(parts)-1:
end = parts[i+1]
else:
end = len(points)
segment = points[start:end]
x_segment = [p[0] for p in segment]
y_segment = [p[1] for p in segment]
```
---
### **4. 插值生成网格温度数据**
用`scipy.interpolate.griddata`将离散站点数据插值为网格:
```python
import numpy as np
from scipy.interpolate import griddata
# 生成网格点坐标
grid_lon = np.linspace(min(lons), max(lons), 500)
grid_lat = np.linspace(min(lats), max(lats), 500)
grid_x, grid_y = np.meshgrid(grid_lon, grid_lat)
# 插值(选择线性/三次方法)
grid_temp = griddata(
(lons, lats), temps,
(grid_x, grid_y), method='linear'
)
```
---
### **5. 绘制填色图并叠加边界**
结合`matplotlib`绘制温度分布和SHP边界:
```python
import matplotlib.pyplot as plt
# 创建画布和坐标轴
fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111)
# 绘制填色图
contour = ax.contourf(grid_x, grid_y, grid_temp, cmap='viridis')
plt.colorbar(contour, label='Temperature (°C)')
# 叠加SHP边界
for shape in sf.shapeRecords():
x = [i[0] for i in shape.shape.points[:]]
y = [i[1] for i in shape.shape.points[:]]
ax.plot(x, y, 'k-', linewidth=0.5) # 黑色边界线
# 设置标题和坐标轴
ax.set_title("Temperature Distribution")
ax.set_xlabel("Longitude")
ax.set_ylabel("Latitude")
plt.show()
```
---
### **6. 关键问题处理**
- **插值优化**:若数据稀疏,尝试调整`method='cubic'`或增加网格密度(如`1000x1000`)。
- **边界闭合**:确保SHP多边形首尾点相同,否则用`np.append(x, x[0])`闭合。
- **性能平衡**:网格过密可能导致内存不足,建议根据数据量调整。
效果示意图:
$$ \text{温度颜色映射} + \text{SHP黑色边界线} + \text{经纬度坐标轴} $$
---
### **完整代码示例**
[将上述代码片段按顺序合并,替换文件路径即可运行]
阅读全文
相关推荐


















