【问题标题】:Issues with Folium Choropleth, pandas: GeoJSON raises AttributeError: 'NoneType'Folium Choropleth,pandas 的问题:GeoJSON 引发 AttributeError:'NoneType'
【发布时间】:2018-05-13 19:28:15
【问题描述】:

我正在使用 Folium 对数据框进行数据可视化,但我坚持在 Folium 中设置 Choropleth 地图的 key_on 参数。 可以查看example code snippet on gist here

我的geojson:

{
    "type":"Topology",
    "arcs":[...],
    "transform":{...},    
    "objects":
        "Com01012018_g_WGS84":{
            "type":"GeometryCollection",
            "geometries": [
                {
                    "arcs":[...],
                    "type":"Polygon",
                    "properties": {
                        "COMUNE": "Borgo Vercelli",
                        "PRO_COM": 2017,
                        ...
                    }
                },
                {...},
            ]
        }
}

我的熊猫 df:

id     comune                  a11y-score   
0   Aquila d'Arroscia           65.17
1   Castel del Rio                 68.75
2   Castellaneta                 71.95
3   Castelvetrano                 77.27
4   Montescudo-Monte Colombo    59.65

我想在“COMUNE”上设置键,我可以很容易地遍历geojson:

with open('italy-comuni.json', encoding='utf-8') as json_file:
    data = json.load(json_file)
    obj = data['objects']
    for righe in obj["Com01012018_g_WGS84"]['geometries']:
        print(righe['properties']['COMUNE']) #print the name of the City

按照 OP here 的建议,我检查了这个 json 和我导入的数据帧是否具有相同的“comune”值(以避免提高 KeyError )并且 a11y-score 中的值已填充(从 0 到 100 的浮点值)。

这是我的传单代码:

m = folium.Map(location=[42.833333, 12.833333],zoom_start=6,tiles="Mapbox Bright")
m.choropleth(
 geo_data=state_geo,
 name='choropleth',
 data=italia_df,
 columns=['comune', 'a11y-score'],
 key_on='object.geometry.properties.COMUNE',
 fill_color='YlOrRd',
 fill_opacity=0.7,
 line_opacity=0.2,
 legend_name='A11y Score'
)
folium.LayerControl().add_to(m)

无法弄清楚如何正确设置 key_on。 尝试了这些,但实际上没有任何效果:

object.geometries.properties.COMUNE
objects.geometries.properties.comune
objects.Com01012018_g_WGS84.geometry.Polygon.properties.COMUNE
objects.Com01012018_g_WGS84.geometries.Polygon.properties.COMUNE
objects.geometry.Polygon.properties.COMUNE
objects.geometries.Polygon.properties.COMUNE
object.geometries.Polygon.properties.COMUNE
Com01012018_g_WGS84.geometry.properties.COMUNE

错误:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-19-578cc4d527b5> in <module>()
      1 # Save to html
----> 2 m.save('italy-a11yscore.html')

~\Anaconda3\envs\py36\lib\site-packages\branca\element.py in save(self, outfile, close_file, **kwargs)
    159 
    160         root = self.get_root()
--> 161         html = root.render(**kwargs)
    162         fid.write(html.encode('utf8'))
    163         if close_file:

~\Anaconda3\envs\py36\lib\site-packages\branca\element.py in render(self, **kwargs)
    307         """Renders the HTML representation of the element."""
    308         for name, child in self._children.items():
--> 309             child.render(**kwargs)
    310         return self._template.render(this=self, kwargs=kwargs)
    311 

~\Anaconda3\envs\py36\lib\site-packages\folium\map.py in render(self, **kwargs)
    336             '</style>'), name='map_style')
    337 
--> 338         super(LegacyMap, self).render(**kwargs)
    339 
    340 

~\Anaconda3\envs\py36\lib\site-packages\branca\element.py in render(self, **kwargs)
    622 
    623         for name, element in self._children.items():
--> 624             element.render(**kwargs)

~\Anaconda3\envs\py36\lib\site-packages\branca\element.py in render(self, **kwargs)
    618         script = self._template.module.__dict__.get('script', None)
    619         if script is not None:
--> 620             figure.script.add_child(Element(script(self, kwargs)),
    621                                     name=self.get_name())
    622 

~\Anaconda3\envs\py36\lib\site-packages\jinja2\runtime.py in __call__(self, *args, **kwargs)
    573                             (self.name, len(self.arguments)))
    574 
--> 575         return self._invoke(arguments, autoescape)
    576 
    577     def _invoke(self, arguments, autoescape):

~\Anaconda3\envs\py36\lib\site-packages\jinja2\asyncsupport.py in _invoke(self, arguments, autoescape)
    108     def _invoke(self, arguments, autoescape):
    109         if not self._environment.is_async:
--> 110             return original_invoke(self, arguments, autoescape)
    111         return async_invoke(self, arguments, autoescape)
    112     return update_wrapper(_invoke, original_invoke)

~\Anaconda3\envs\py36\lib\site-packages\jinja2\runtime.py in _invoke(self, arguments, autoescape)
    577     def _invoke(self, arguments, autoescape):
    578         """This method is being swapped out by the async implementation."""
--> 579         rv = self._func(*arguments)
    580         if autoescape:
    581             rv = Markup(rv)

<template> in macro(l_1_this, l_1_kwargs)

~\Anaconda3\envs\py36\lib\site-packages\jinja2\runtime.py in call(_Context__self, _Context__obj, *args, **kwargs)
    260                 args = (__self.environment,) + args
    261         try:
--> 262             return __obj(*args, **kwargs)
    263         except StopIteration:
    264             return __self.environment.undefined('value was undefined because '

~\Anaconda3\envs\py36\lib\site-packages\folium\features.py in style_data(self)
    563 
    564         for feature in self.data['features']:
--> 565             feature.setdefault('properties', {}).setdefault('style', {}).update(self.style_function(feature))  # noqa
    566             feature.setdefault('properties', {}).setdefault('highlight', {}).update(self.highlight_function(feature))  # noqa
    567         return json.dumps(self.data, sort_keys=True)

~\Anaconda3\envs\py36\lib\site-packages\folium\folium.py in style_function(x)
    303                 'color': line_color,
    304                 'fillOpacity': fill_opacity,
--> 305                 'fillColor': color_scale_fun(x)
    306             }
    307 

~\Anaconda3\envs\py36\lib\site-packages\folium\folium.py in color_scale_fun(x)
    290             def color_scale_fun(x):
    291                 return color_range[len(
--> 292                     [u for u in color_domain if
    293                      get_by_key(x, key_on) in color_data and
    294                      u <= color_data[get_by_key(x, key_on)]])]

~\Anaconda3\envs\py36\lib\site-packages\folium\folium.py in <listcomp>(.0)
    291                 return color_range[len(
    292                     [u for u in color_domain if
--> 293                      get_by_key(x, key_on) in color_data and
    294                      u <= color_data[get_by_key(x, key_on)]])]
    295         else:

~\Anaconda3\envs\py36\lib\site-packages\folium\folium.py in get_by_key(obj, key)
    286                 return (obj.get(key, None) if len(key.split('.')) <= 1 else
    287                         get_by_key(obj.get(key.split('.')[0], None),
--> 288                                    '.'.join(key.split('.')[1:])))
    289 
    290             def color_scale_fun(x):

~\Anaconda3\envs\py36\lib\site-packages\folium\folium.py in get_by_key(obj, key)
    285             def get_by_key(obj, key):
    286                 return (obj.get(key, None) if len(key.split('.')) <= 1 else
--> 287                         get_by_key(obj.get(key.split('.')[0], None),
    288                                    '.'.join(key.split('.')[1:])))
    289 

AttributeError: 'NoneType' object has no attribute 'get'

我还找到了another question on this problem,但在那里找到的解决方案对我不起作用。我正在努力在key_on 参数中找到正确的组合。

感谢您的帮助!

更新我已经更改了我的 JSON,它现在看起来像这样:

{ "type":"FeatureCollection", 
"features":[ 
             "type":"Feature", 
             "geometry": {...}, 
             "properties": { 
                    "comune": "Borgo Vercelli", 
                    "PRO_COM": 2017, 
                     ...

但我无法使用 feature.properties.comune 遍历它。在地图中我看不到我的 GeoJson 图层。

【问题讨论】:

  • UPDATE 我已经更改了我的 JSON,它现在看起来像这样:感谢您的评论。我已经编辑了我的 GeoJson,现在它看起来:``` { "type":"FeatureCollection", "features":[ "type":"Feature", "geometry": {...}, "properties": { “comune”:“Borgo Vercelli”,“PRO_COM”:2017,...```

标签: python pandas maps folium


【解决方案1】:

folium.Map.choropleth (read it on GitHub here) 的文档字符串表明 key_on 参数是一个必须始终以 'feature' 开头的字符串。所以我要尝试的第一件事是:

key_on='feature.properties.COMUNE'

【讨论】:

  • 我没有收到任何错误,但 html 页面没有显示任何 GeoJSON。我正在使用 feature.properties.comune 遍历 GeoJSON。我不知道为什么会这样。
  • @Peter Leimbigler 谢谢!!!我使用了 features 而不是 feature,我得到了与 precipitevolissimevolmente 相同的错误。无论如何,我仍然不明白为什么第一个键没有“s”,而 geoJson 文件具有更高键的功能
  • @precipitevolissimevolmente 我认为 key_on 参数区分大小写,所以你应该使用“feature.properties.COMUNE”而不是“feature.properties.comune”
【解决方案2】:

我有“AttributeError”,但是当我添加时它消失了

tiles="OpenStreetMap"

我的 folium.Map() 声明。

【讨论】:

    【解决方案3】:

    对我有用的是设置“key_on=”的键名从“feature.xyz.abc”开始,而 json 文件中的实际键等于“features”

    实际:

    `m.choropleth(
     geo_data= gsonfile,
     name='choropleth',
     data=pd_total,
     columns=['Neighbourhood', 'Count'],
     key_on= 'feature.properties.DISTRICT',
     fill_color='YlOrRd',
     fill_opacity=0.7,
     line_opacity=0.2,
    )`
    

    JSON:

    `{
      "type": "FeatureCollection",
      "crs": {
        "type": "name",
        "properties": {
          "name": "urn:ogc:def:crs:OGC:1.3:CRS84"
        }
      },
      "features": [{
        "type": "Feature",
        "properties": {
          "OBJECTID": 1,
          "DISTRICT": "CENTRAL",
          "COMPANY": "A"
        },`
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-19
      • 2016-03-21
      • 2016-04-13
      • 1970-01-01
      • 2021-11-11
      • 1970-01-01
      相关资源
      最近更新 更多