使用 Matplotlib-Basemap 和 Xarray 绘制 lat/lon 网格线
Plotting lat/lon gridlines using Matplotlib-Basemap and Xarray
我有一个 xarray DataArray da
,其中包含爱尔兰的一段数据,如下所示:
<xarray.DataArray 'co2' (lat: 733, lon: 720)>
array([[nan, nan, nan, ..., nan, nan, nan],
[nan, nan, nan, ..., nan, nan, nan],
[nan, nan, nan, ..., nan, nan, nan],
...,
[nan, nan, nan, ..., nan, nan, nan],
[nan, nan, nan, ..., nan, nan, nan],
[nan, nan, nan, ..., nan, nan, nan]])
Coordinates:
* lat (lat) float32 49.9 49.908333 49.916664 49.924995 49.933327 ...
* lon (lon) float32 -11.0 -10.991667 -10.983334 -10.975 -10.966667 ...
我可以这样映射:
import matplotlib.pyplot as plt
import xarray
import os
from mpl_toolkits.basemap import Basemap, cm
m= Basemap(projection='cyl',lat_0=ds.co2.lat[0],lon_0=ds.co2.lon[len(ds.co2.lon)/2])
m.drawcoastlines()
da.plot()
问题是 lat/lon 网格线不绘制。
当我使用经络命令时:
meridians = np.arange(10.,351.,20.)
m.drawmeridians(meridians,labels=[True,False,False,True])
我收到以下错误:
ValueError: dimensions () must have the same length as the number of data dimensions, ndim=1
我不知道接下来要尝试什么。
编辑:完整错误跟踪:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-46-45a293c8bb99> in <module>()
4
5 # draw grid plots
----> 6 m.drawmeridians(np.arange(-8.0,2.0,1.0),labels=[1,0,0,0]) #longitudes
7 m.drawparallels(np.arange(51.0,59.0,1.0),labels=[0,0,0,1]) #latitudes
8
C:\Users\AppData\Local\Continuum\Anaconda\lib\site- packages\mpl_toolkits\basemap\__init__.pyc in drawmeridians(self, meridians, color, linewidth, zorder, dashes, labels, labelstyle, fmt, xoffset, yoffset, ax, latmax, **kwargs)
2593 # don't really know why, but this appears to be needed to
2594 # or lines sometimes don't reach edge of plot.
-> 2595 testx = np.logical_and(x>=self.xmin-3*xdelta,x<=self.xmax+3*xdelta)
2596 x = np.compress(testx, x)
2597 y = np.compress(testx, y)
C:\Users\AppData\Local\Continuum\Anaconda\lib\site-packages\xarray\core\dataarray.pyc in func(self, other)
1550
1551 variable = (f(self.variable, other_variable)
-> 1552 if not reflexive
1553 else f(other_variable, self.variable))
1554 coords = self.coords._merge_raw(other_coords)
C:\Users\AppData\Local\Continuum\Anaconda\lib\site-packages\xarray\core\variable.pyc in func(self, other)
1164 if not reflexive
1165 else f(other_data, self_data))
-> 1166 result = Variable(dims, new_data)
1167 return result
1168 return func
C:\Users\AppData\Local\Continuum\Anaconda\lib\site-packages\xarray\core\variable.pyc in __init__(self, dims, data, attrs, encoding, fastpath)
255 """
256 self._data = as_compatible_data(data, fastpath=fastpath)
--> 257 self._dims = self._parse_dimensions(dims)
258 self._attrs = None
259 self._encoding = None
C:\Users\AppData\Local\Continuum\Anaconda\lib\site-packages\xarray\core\variable.pyc in _parse_dimensions(self, dims)
364 raise ValueError('dimensions %s must have the same length as the '
365 'number of data dimensions, ndim=%s'
--> 366 % (dims, self.ndim))
367 return dims
368
ValueError: dimensions () must have the same length as the number of data dimensions, ndim=1
尝试使用cartopy instead of Basemap
. See related issue .
TL:DR-我在你的数据集上使用你的代码没有问题,让我们找出原因
我用了你的小数据集,这段代码:
ds=xarray.open_dataset(r"C:\Users\SHIR\Downloads\OneYear.nc")
da=ds.co2
m= Basemap(projection='cyl',lat_0=ds.co2.lat[0],lon_0=ds.co2.lon[len(ds.co2.lon)/2])
m.drawcoastlines()
da.plot()
plt.show()
我得到这张图:
添加经络时,使用:
ds=xarray.open_dataset(r"C:\Users\SHIR\Downloads\OneYear.nc")
da=ds.co2
m= Basemap(projection='cyl',lat_0=ds.co2.lat[0],lon_0=ds.co2.lon[len(ds.co2.lon)/2])
m.drawcoastlines()
meridians = np.arange(10.,351.,20.)
m.drawmeridians(meridians,labels=[True,False,False,True])
da.plot()
plt.show()
我得到了-
我能想到的造成我们之间差异的原因:
首先-较小的数据集-请尝试您发送给我的较小的数据集,如果您再次遇到错误,请告诉我
其次- 软件包和版本- 我正在使用 python 2.7。我之前没有底图,所以我尝试使用conda安装它,但遇到了很多问题。最后,我使用 conda (conda uninstall matplotlib
) 卸载了 matplotlib,使用 pip (pip install matplotlib --upgrade --force-reinstall
) 重新安装了它,并按照 中的描述手动安装了底图。我使用了 basemap‑1.2.0‑cp27‑cp27m‑win_amd64.whl
文件。
我真的不确定它是否聪明,我没有用 conda 搞砸,但这是唯一对我有用的东西。也许首先尝试只卸载底图,而不是 matplotlib(我这样做是因为我已经把它搞砸了......)
我有一个 xarray DataArray da
,其中包含爱尔兰的一段数据,如下所示:
<xarray.DataArray 'co2' (lat: 733, lon: 720)>
array([[nan, nan, nan, ..., nan, nan, nan],
[nan, nan, nan, ..., nan, nan, nan],
[nan, nan, nan, ..., nan, nan, nan],
...,
[nan, nan, nan, ..., nan, nan, nan],
[nan, nan, nan, ..., nan, nan, nan],
[nan, nan, nan, ..., nan, nan, nan]])
Coordinates:
* lat (lat) float32 49.9 49.908333 49.916664 49.924995 49.933327 ...
* lon (lon) float32 -11.0 -10.991667 -10.983334 -10.975 -10.966667 ...
我可以这样映射:
import matplotlib.pyplot as plt
import xarray
import os
from mpl_toolkits.basemap import Basemap, cm
m= Basemap(projection='cyl',lat_0=ds.co2.lat[0],lon_0=ds.co2.lon[len(ds.co2.lon)/2])
m.drawcoastlines()
da.plot()
问题是 lat/lon 网格线不绘制。
当我使用经络命令时:
meridians = np.arange(10.,351.,20.)
m.drawmeridians(meridians,labels=[True,False,False,True])
我收到以下错误:
ValueError: dimensions () must have the same length as the number of data dimensions, ndim=1
我不知道接下来要尝试什么。
编辑:完整错误跟踪:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-46-45a293c8bb99> in <module>()
4
5 # draw grid plots
----> 6 m.drawmeridians(np.arange(-8.0,2.0,1.0),labels=[1,0,0,0]) #longitudes
7 m.drawparallels(np.arange(51.0,59.0,1.0),labels=[0,0,0,1]) #latitudes
8
C:\Users\AppData\Local\Continuum\Anaconda\lib\site- packages\mpl_toolkits\basemap\__init__.pyc in drawmeridians(self, meridians, color, linewidth, zorder, dashes, labels, labelstyle, fmt, xoffset, yoffset, ax, latmax, **kwargs)
2593 # don't really know why, but this appears to be needed to
2594 # or lines sometimes don't reach edge of plot.
-> 2595 testx = np.logical_and(x>=self.xmin-3*xdelta,x<=self.xmax+3*xdelta)
2596 x = np.compress(testx, x)
2597 y = np.compress(testx, y)
C:\Users\AppData\Local\Continuum\Anaconda\lib\site-packages\xarray\core\dataarray.pyc in func(self, other)
1550
1551 variable = (f(self.variable, other_variable)
-> 1552 if not reflexive
1553 else f(other_variable, self.variable))
1554 coords = self.coords._merge_raw(other_coords)
C:\Users\AppData\Local\Continuum\Anaconda\lib\site-packages\xarray\core\variable.pyc in func(self, other)
1164 if not reflexive
1165 else f(other_data, self_data))
-> 1166 result = Variable(dims, new_data)
1167 return result
1168 return func
C:\Users\AppData\Local\Continuum\Anaconda\lib\site-packages\xarray\core\variable.pyc in __init__(self, dims, data, attrs, encoding, fastpath)
255 """
256 self._data = as_compatible_data(data, fastpath=fastpath)
--> 257 self._dims = self._parse_dimensions(dims)
258 self._attrs = None
259 self._encoding = None
C:\Users\AppData\Local\Continuum\Anaconda\lib\site-packages\xarray\core\variable.pyc in _parse_dimensions(self, dims)
364 raise ValueError('dimensions %s must have the same length as the '
365 'number of data dimensions, ndim=%s'
--> 366 % (dims, self.ndim))
367 return dims
368
ValueError: dimensions () must have the same length as the number of data dimensions, ndim=1
尝试使用cartopy instead of Basemap
. See related issue
TL:DR-我在你的数据集上使用你的代码没有问题,让我们找出原因
我用了你的小数据集,这段代码:
ds=xarray.open_dataset(r"C:\Users\SHIR\Downloads\OneYear.nc")
da=ds.co2
m= Basemap(projection='cyl',lat_0=ds.co2.lat[0],lon_0=ds.co2.lon[len(ds.co2.lon)/2])
m.drawcoastlines()
da.plot()
plt.show()
我得到这张图:
添加经络时,使用:
ds=xarray.open_dataset(r"C:\Users\SHIR\Downloads\OneYear.nc")
da=ds.co2
m= Basemap(projection='cyl',lat_0=ds.co2.lat[0],lon_0=ds.co2.lon[len(ds.co2.lon)/2])
m.drawcoastlines()
meridians = np.arange(10.,351.,20.)
m.drawmeridians(meridians,labels=[True,False,False,True])
da.plot()
plt.show()
我得到了-
我能想到的造成我们之间差异的原因:
首先-较小的数据集-请尝试您发送给我的较小的数据集,如果您再次遇到错误,请告诉我
其次- 软件包和版本- 我正在使用 python 2.7。我之前没有底图,所以我尝试使用conda安装它,但遇到了很多问题。最后,我使用 conda (conda uninstall matplotlib
) 卸载了 matplotlib,使用 pip (pip install matplotlib --upgrade --force-reinstall
) 重新安装了它,并按照 basemap‑1.2.0‑cp27‑cp27m‑win_amd64.whl
文件。
我真的不确定它是否聪明,我没有用 conda 搞砸,但这是唯一对我有用的东西。也许首先尝试只卸载底图,而不是 matplotlib(我这样做是因为我已经把它搞砸了......)