Построение линий сетки широты и долготы с использованием Matplotlib-Basemap и 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()

Проблема в том, что линии сетки широты и долготы не отображаются.

введите описание изображения здесь

Когда я использую команду меридианов:

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

person Pad    schedule 24.10.2018    source источник
comment
Может быть, ваша сетка слишком разреженная, и ни один из меридианов на самом деле не проходит через нанесенную область?   -  person Thomas Kühn    schedule 26.10.2018
comment
@Thomas Я так не думаю, я попробовал # draw grid plots m.drawmeridians(np.arange(-8.0,2.0,1.0),labels=[1,0,0,0]) #longitudes m.drawparallels(np.arange(51.0,59.0,1.0),labels=[0,0,0,1]) #latitudes и получил ту же ошибку   -  person Pad    schedule 26.10.2018
comment
Можете ли вы опубликовать полную трассировку ошибок?   -  person Thomas Kühn    schedule 26.10.2018
comment
добавлена ​​полная трассировка ошибок!   -  person Pad    schedule 27.10.2018
comment
Хм, это на самом деле очень хорошо для меня: m = Basemap(projection='cyl', lat_0=ds.co2.lat[0], lon_0=ds.co2.lon[len(ds.co2.lon)//2]); m.drawcoastlines(); ds.co2.plot(cmap='viridis'); m.drawmeridians(np.arange(-8.0,2.0,1.0),labels=[1,0,0,0]); #longitudes m.drawparallels(np.arange(51.0,59.0,1.0),labels=[0,0,0,1]); #latitudes. Может быть, попробовать обновить все и убедиться, что m - это объект Basemap?   -  person Michael Delgado    schedule 28.10.2018
comment
По-прежнему получаю ту же ошибку, я обновил Basemap, и он начал вводить новые ошибки (по-видимому, он не работает с ноутбуками jupyter), поэтому мне пришлось вернуться.   -  person Pad    schedule 29.10.2018
comment
можно как-нибудь поделиться файлом данных с рассолом?   -  person Shir    schedule 04.11.2018
comment
@shir Я могу отправить вам ссылку на данные по электронной почте? Его размер превышает 2 ГБ.   -  person Pad    schedule 05.11.2018
comment
Не могли бы вы прислать только небольшую часть? :) Думаю, проблема будет и с 1 МБ :)   -  person Shir    schedule 05.11.2018
comment
Я бы второй запрос @Shir для минимального рабочего примера с включенными данными. Если у вас есть такая же проблема с несколькими пунктами, включите их здесь - так люди могут подтвердить, есть ли у них такая же проблема, и опробовать свои идеи, чтобы исправить ее.   -  person kabdulla    schedule 06.11.2018
comment
Это действительно работает для меня, используя ваш небольшой набор данных. Можете ли вы попробовать с ним и сказать, работает ли?   -  person Shir    schedule 06.11.2018


Ответы (2)


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, и у меня возникло множество проблем. В конце концов, я удалил matplotlib с помощью conda (conda uninstall matplotlib), переустановил его с помощью pip (pip install matplotlib --upgrade --force-reinstall) и вручную установил базовую карту, как описано в этом ответе. Я использовал basemap‑1.2.0‑cp27‑cp27m‑win_amd64.whl файл.

Я действительно не уверен, что это было умно, и я не напортачил с conda, но это было единственное, что у меня сработало. Возможно, попробуйте сначала удалить только базовую карту, а не matplotlib (я сделал это, потому что я уже все испортил ...)

person Shir    schedule 06.11.2018
comment
Спасибо вам большое за это. Я думаю, что вы правы насчет проблемы с пакетом, Basemap, кажется, возвращает все назад, что является проблемой и для других скриптов, которые я запускаю. Я мог бы полностью избежать использования Basemap, чтобы не испортить другой код! Однако ваш ответ отвечает на мой вопрос! - person Pad; 06.11.2018

Попробуйте использовать cartopy вместо Basemap. См. Связанную проблему здесь.

person Ales    schedule 05.11.2018
comment
Спасибо, но это дает мне ошибку ImportError: DLL load failed: The specified module could not be found. - я переустановил все пакеты и обновил их, ошибка сохраняется :( - person Pad; 05.11.2018
comment
Пробуя Python 3.6, я получаю сообщение об ошибке ValueError: Can't use axes when making faceted plots. - person Pad; 05.11.2018