【问题标题】:Pandas error with basemap/proj for map plotting用于地图绘制的底图/项目的 Pandas 错误
【发布时间】:2014-06-01 21:40:19
【问题描述】:

我运行了下面的 Python 代码,它是一本书用于数据分析的 Python 中“绘制地图:可视化海地地震危机数据”的示例。第242-246页

该代码应该创建一个海地的绘图地图,但我收到如下错误:

Traceback (most recent call last):
  File "Haiti.py", line 74, in <module>
    x, y = m(cat_data.LONGITUDE, cat_data.LATITUDE)
  File "/usr/local/lib/python2.7/site-packages/mpl_toolkits/basemap/__init__.py", line 1148, in __call__
    xout,yout = self.projtran(x,y,inverse=inverse)
  File "/usr/local/lib/python2.7/site-packages/mpl_toolkits/basemap/proj.py", line 286, in __call__
    outx,outy = self._proj4(x, y, inverse=inverse)
  File "/usr/local/lib/python2.7/site-packages/mpl_toolkits/basemap/pyproj.py", line 388, in __call__
    _proj.Proj._fwd(self, inx, iny, radians=radians, errcheck=errcheck)
  File "_proj.pyx", line 122, in _proj.Proj._fwd (src/_proj.c:1571)
RuntimeError

我检查了我的机器上是否安装了 mpl_toolkits.basemapproj 模块。底图是从源代码as instructed 安装的,proj 是由 Homebrew 安装的,它们对我来说看起来不错。

如果你安装了底图和项目,这段代码运行成功了吗?如果不是,您认为是模块安装问题、代码本身问题还是其他问题?

Haiti.csv文件可以从https://github.com/pydata/pydata-book/raw/master/ch08/Haiti.csv下载

import pandas as pd
import numpy as np
from pandas import DataFrame

data = pd.read_csv('Haiti.csv')

data = data[(data.LATITUDE > 18) & (data.LATITUDE < 20) &
        (data.LONGITUDE > -75) & (data.LONGITUDE < -70)
        & data.CATEGORY.notnull()]

def to_cat_list(catstr):
    stripped = (x.strip() for x in catstr.split(','))
    return [x for x in stripped if x]

def get_all_categories(cat_series):
    cat_sets = (set(to_cat_list(x)) for x in cat_series) 
    return sorted(set.union(*cat_sets))

def get_english(cat):
    code, names = cat.split('.') 
    if '|' in names:
        names = names.split(' | ')[1] 
    return code, names.strip()

all_cats = get_all_categories(data.CATEGORY)
english_mapping = dict(get_english(x) for x in all_cats)

def get_code(seq):
    return [x.split('.')[0] for x in seq if x]

all_codes = get_code(all_cats)
code_index = pd.Index(np.unique(all_codes))
dummy_frame = DataFrame(np.zeros((len(data), len(code_index))),
                        index=data.index, columns=code_index)

for row, cat in zip(data.index, data.CATEGORY): 
    codes = get_code(to_cat_list(cat)) 
    dummy_frame.ix[row, codes] = 1

data = data.join(dummy_frame.add_prefix('category_'))

from mpl_toolkits.basemap import Basemap 
import matplotlib.pyplot as plt

def basic_haiti_map(ax=None, lllat=17.25, urlat=20.25, lllon=-75, urlon=-71):
    # create polar stereographic Basemap instance. 
    m = Basemap(ax=ax, projection='stere', 
                lon_0=(urlon + lllon) / 2, 
                lat_0=(urlat + lllat) / 2,
                llcrnrlat=lllat, urcrnrlat=urlat, 
                llcrnrlon=lllon, urcrnrlon=urlon, 
                resolution='f')
    # draw coastlines, state and country boundaries, edge of map. m.drawcoastlines()
    m.drawstates()
    m.drawcountries()
    return m

fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(12, 10)) 
fig.subplots_adjust(hspace=0.05, wspace=0.05)

to_plot = ['2a', '1', '3c', '7a']

lllat=17.25; urlat=20.25; lllon=-75; urlon=-71

for code, ax in zip(to_plot, axes.flat):
    m = basic_haiti_map(ax, lllat=lllat, urlat=urlat,
                        lllon=lllon, urlon=urlon) 

    cat_data = data[data['category_%s' % code] == 1]

    # compute map proj coordinates.
    print cat_data.LONGITUDE, cat_data.LATITUDE
    x, y = m(cat_data.LONGITUDE, cat_data.LATITUDE)

    m.plot(x, y, 'k.', alpha=0.5)
    ax.set_title('%s: %s' % (code, english_mapping[code]))

【问题讨论】:

    标签: python pandas data-analysis matplotlib-basemap proj


    【解决方案1】:

    感谢Alex Messina's finding,将 m(cat_data.LONGITUDE, cat_data.LATITUDE) 更改为 m(cat_data.LONGITUDE.values, cat_data.LATITUDE.values) 解决了这个问题。

    通过对我的进一步研究,自 2013 年 12 月 31 日发布的 v0.13.0 以来,pandas 更改了 DataFrame 的 Series 数据(源自 NDFrame)应使用 .values 传递给像 basemap/proj 这样的 Cython 函数,如下所示。

    引用熊猫github commit log

    +.. warning::
     +
     +   In 0.13.0 since ``Series`` has internaly been refactored to no longer sub-class ``ndarray``
     +   but instead subclass ``NDFrame``, you can **not pass** a ``Series`` directly as a ``ndarray`` typed parameter
     +   to a cython function. Instead pass the actual ``ndarray`` using the ``.values`` attribute of the Series.
     +
     +   Prior to 0.13.0
     +
     +   .. code-block:: python
     +
     +        apply_integrate_f(df['a'], df['b'], df['N'])
     +
     +   Use ``.values`` to get the underlying ``ndarray``
     +
     +   .. code-block:: python
     +
     +        apply_integrate_f(df['a'].values, df['b'].values, df['N'].values)
    

    您可以找到示例代码here的更正版本。

    【讨论】:

      猜你喜欢
      • 2023-03-16
      • 2013-01-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-26
      • 1970-01-01
      • 2021-01-04
      相关资源
      最近更新 更多