将 pandas 数据框重组为底图的网格
restructuring pandas dataframe into meshgrid for basemap
我正在尝试关注 basemap tutorial for SST and ice analysis。我的输入数据与示例中的数据不同,示例中的数据来自 netCDF4
作为掩码数组。
我有一个 pandas
数据框,例如:
val_df[0:5]
Out[47]:
lat lon value
0 0.4 98.7 NaN
1 0.4 98.8 NaN
2 0.4 98.9 0.64
3 0.4 99.0 NaN
4 0.5 98.5 1.23
纬度和经度表示数据点在地图网格上的唯一位置。要创建示例数据框,您可以使用以下代码:
from itertools import product
import pandas as pd
import numpy as np
locations = np.array([x for x in product([1,2,3],[4,5,6])])
data = np.random.random(len(locations))
val_df = pd.DataFrame({'lat':locations[:,0], 'lon':locations[:,1],
'value':data})
我之前所做的是获取此数据框,对其进行透视(使用内置的透视函数),以便 lat
列是索引,lon
列是列和价值观就是价值观。然后我可以使用 m.imshow
绘制结果值。
然而,这似乎是一个糟糕的解决方案。 A) pcolormesh
比 imshow
更推荐,原因我不清楚,B) 似乎人们通常使用 meshgrid,然后使用屏蔽数组。但是,我真的不清楚如何根据底图示例将我的数据构建到 meshgrid 和掩码数组中,因为示例中的数据是预先整形的。
当我创建 lats/lons 的 mesh_grid 时,我执行以下操作:
latmin = np.floor(val_df.lat.min())
latmax = np.ceil(val_df.lat.max())
lonmin = np.floor(val_df.lon.min())
lonmax = np.ceil(val_df.lon.max())
lats = np.arange(latmin, latmax, 0.1)
lons = np.arange(lonmin, lonmax, 0.1)
lats_mesh, lons_mesh = np.meshgrid(lats, lons)
但此时我不清楚如何构建和屏蔽 value
列,以便在我将其提供给 pcolormesh
时,这些值出现在网格的正确位置,如下所示:
from mpl_toolkits.basemap import Basemap
m = Basemap(projection='merc'
, llcrnrlon=lonmin
, llcrnrlat=latmin
, urcrnrlon=lonmax
, urcrnrlat=latmax)
m.drawcoastlines()
m.drawstates()
m.drawcountries()
m.fillcontinents(color='gray', lake_color='white', zorder=0)
m.drawmapboundary(fill_color='white')
pc1 = m.pcolormesh(lons, lats, masked_data, shading='flat', cmap='hot_r', latlon=True)
基本上,我的问题的答案是我需要旋转我的数据框。
val_pivot_df = val_df.pivot(index='lat', columns='lon', values='b_value')
这会旋转数据框,用 NaNs
和 returns 填充没有数据的区域。由于底图不喜欢 pandas 然后我将数据输出为 numpy 数组并绘制它。
lons = val_pivot_df.columns.values
lats = val_pivot_df.index.values
fig, ax = plt.subplots(1, figsize=(8,8))
m = Basemap(projection='merc',
llcrnrlat=val_df.dropna().min().lat-5
, urcrnrlat=val_df.dropna().max().lat+5
, llcrnrlon=val_df.dropna().min().lon-5
, urcrnrlon=val_df.dropna().max().lon+5
, resolution='i', area_thresh=10000
)
m.drawcoastlines()
m.drawstates()
m.drawcountries()
m.fillcontinents(color='gray', lake_color='white')#, zorder=0)
m.drawmapboundary(fill_color='0.3')
x, y = np.meshgrid(lons,lats)
px,py = m(x,y)
data_values = val_pivot_df.values
masked_data = np.ma.masked_invalid(data_values)
cmap = plt.cm.viridis
m.pcolormesh(px, py, masked_data, cmap=cmap, vmin=0, vmax=2, shading='flat')
m.colorbar()
我正在尝试关注 basemap tutorial for SST and ice analysis。我的输入数据与示例中的数据不同,示例中的数据来自 netCDF4
作为掩码数组。
我有一个 pandas
数据框,例如:
val_df[0:5]
Out[47]:
lat lon value
0 0.4 98.7 NaN
1 0.4 98.8 NaN
2 0.4 98.9 0.64
3 0.4 99.0 NaN
4 0.5 98.5 1.23
纬度和经度表示数据点在地图网格上的唯一位置。要创建示例数据框,您可以使用以下代码:
from itertools import product
import pandas as pd
import numpy as np
locations = np.array([x for x in product([1,2,3],[4,5,6])])
data = np.random.random(len(locations))
val_df = pd.DataFrame({'lat':locations[:,0], 'lon':locations[:,1],
'value':data})
我之前所做的是获取此数据框,对其进行透视(使用内置的透视函数),以便 lat
列是索引,lon
列是列和价值观就是价值观。然后我可以使用 m.imshow
绘制结果值。
然而,这似乎是一个糟糕的解决方案。 A) pcolormesh
比 imshow
更推荐,原因我不清楚,B) 似乎人们通常使用 meshgrid,然后使用屏蔽数组。但是,我真的不清楚如何根据底图示例将我的数据构建到 meshgrid 和掩码数组中,因为示例中的数据是预先整形的。
当我创建 lats/lons 的 mesh_grid 时,我执行以下操作:
latmin = np.floor(val_df.lat.min())
latmax = np.ceil(val_df.lat.max())
lonmin = np.floor(val_df.lon.min())
lonmax = np.ceil(val_df.lon.max())
lats = np.arange(latmin, latmax, 0.1)
lons = np.arange(lonmin, lonmax, 0.1)
lats_mesh, lons_mesh = np.meshgrid(lats, lons)
但此时我不清楚如何构建和屏蔽 value
列,以便在我将其提供给 pcolormesh
时,这些值出现在网格的正确位置,如下所示:
from mpl_toolkits.basemap import Basemap
m = Basemap(projection='merc'
, llcrnrlon=lonmin
, llcrnrlat=latmin
, urcrnrlon=lonmax
, urcrnrlat=latmax)
m.drawcoastlines()
m.drawstates()
m.drawcountries()
m.fillcontinents(color='gray', lake_color='white', zorder=0)
m.drawmapboundary(fill_color='white')
pc1 = m.pcolormesh(lons, lats, masked_data, shading='flat', cmap='hot_r', latlon=True)
基本上,我的问题的答案是我需要旋转我的数据框。
val_pivot_df = val_df.pivot(index='lat', columns='lon', values='b_value')
这会旋转数据框,用 NaNs
和 returns 填充没有数据的区域。由于底图不喜欢 pandas 然后我将数据输出为 numpy 数组并绘制它。
lons = val_pivot_df.columns.values
lats = val_pivot_df.index.values
fig, ax = plt.subplots(1, figsize=(8,8))
m = Basemap(projection='merc',
llcrnrlat=val_df.dropna().min().lat-5
, urcrnrlat=val_df.dropna().max().lat+5
, llcrnrlon=val_df.dropna().min().lon-5
, urcrnrlon=val_df.dropna().max().lon+5
, resolution='i', area_thresh=10000
)
m.drawcoastlines()
m.drawstates()
m.drawcountries()
m.fillcontinents(color='gray', lake_color='white')#, zorder=0)
m.drawmapboundary(fill_color='0.3')
x, y = np.meshgrid(lons,lats)
px,py = m(x,y)
data_values = val_pivot_df.values
masked_data = np.ma.masked_invalid(data_values)
cmap = plt.cm.viridis
m.pcolormesh(px, py, masked_data, cmap=cmap, vmin=0, vmax=2, shading='flat')
m.colorbar()