Проблемы с Folium Choropleth, pandas: GeoJSON вызывает AttributeError: 'NoneType' - PullRequest
0 голосов
/ 13 мая 2018

Я работаю над визуализацией данных для фрейма данных с использованием Folium, но я застрял в установке параметра key_on карты Choropleth в Folium. Вы можете посмотреть пример кода кода на Gist здесь

Мой геойсон:

{
    "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 здесь Я проверил, имеет ли и этот json, и мой импортированный фрейм данных одинаковое значение "comune" (чтобы избежать повышения KeyError), и все значения в a11y-Score заполнены (значения с плавающей запятой) от 0 до 100).

Вот мой код Leaflet:

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'

Я также нашел еще один вопрос по этой проблеме , но найденное там решение не работает для меня. Я изо всех сил пытаюсь найти правильную комбинацию в параметре key_on.

Спасибо за помощь!

ОБНОВЛЕНИЕ Я изменил свой JSON, теперь он выглядит так:

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

Но я не могу пройти через него, используя feature.properties.comune. На карте я не вижу свой слой GeoJson.

Ответы [ 2 ]

0 голосов
/ 04 июля 2019

У меня был AttributeError, но он исчез, когда я добавил

tiles="OpenStreetMap"

в мой оператор folium.Map ().

0 голосов
/ 14 мая 2018

Строка документации для folium.Map.choropleth ( читайте ее на GitHub здесь ) говорит, что аргумент key_on - это строка, которая всегда должна начинаться с 'feature'.Итак, первое, что я попробую, это:

key_on='feature.properties.COMUNE'
...