I am running this code to generate a choropleth map of landprices in Germany. I have installed the pyviz, panel and geoviews packages. Even yesterday this was generating the plots with the hovering annotations. But today the code is generating an error:
AttributeError Traceback (most recent call last)
~\AppData\Local\Temp\ipykernel_7148\2718829362.py in <module>
3 years = pn.widgets.IntSlider(name="Jahre",value=2005,start=1995,end=2021,step=1)
4 #interact = pn.bind(map_landvalue,zeit=years,pval=value_type)
----> 5 de_map_plot = pn.Column(pn.Column(value_type,years),
6 pn.bind(map_landvalue,zeit=years,pval=value_type))
7 de_map_plot.show()
~\anaconda3\lib\site-packages\panel\layout\base.py in __init__(self, *objects, **params)
628 "as positional arguments or as a keyword, "
629 "not both." % type(self).__name__)
--> 630 params['objects'] = [panel(pane) for pane in objects]
631 elif 'objects' in params:
632 params['objects'] = [panel(pane) for pane in params['objects']]
~\anaconda3\lib\site-packages\panel\layout\base.py in <listcomp>(.0)
628 "as positional arguments or as a keyword, "
629 "not both." % type(self).__name__)
--> 630 params['objects'] = [panel(pane) for pane in objects]
631 elif 'objects' in params:
632 params['objects'] = [panel(pane) for pane in params['objects']]
~\anaconda3\lib\site-packages\panel\pane\base.py in panel(obj, **kwargs)
78 if kwargs.get('name', False) is None:
79 kwargs.pop('name')
---> 80 pane = PaneBase.get_pane_type(obj, **kwargs)(obj, **kwargs)
81 if len(pane.layout) == 1 and pane._unpack:
82 return pane.layout[0]
~\anaconda3\lib\site-packages\panel\param.py in __init__(self, object, **params)
743 if object is not None:
744 self._validate_object()
--> 745 self._replace_pane(not self.lazy)
746
747 @param.depends('object', watch=True)
~\anaconda3\lib\site-packages\panel\param.py in _replace_pane(self, force, *args)
792 new_object = Spacer()
793 else:
--> 794 new_object = self.eval(self.object)
795 if inspect.isawaitable(new_object):
796 param.parameterized.async_executor(partial(self._eval_async, new_object))
~\anaconda3\lib\site-packages\panel\param.py in eval(self, function)
775 args = (getattr(dep.owner, dep.name) for dep in arg_deps)
776 kwargs = {n: getattr(dep.owner, dep.name) for n, dep in kw_deps.items()}
--> 777 return function(*args, **kwargs)
778
779 async def _eval_async(self, awaitable):
~\anaconda3\lib\site-packages\param\parameterized.py in _depends(*args, **kw)
385 @wraps(func)
386 def _depends(*args, **kw):
--> 387 return func(*args, **kw)
388
389 deps = list(dependencies)+list(kw.values())
~\anaconda3\lib\site-packages\panel\depends.py in wrapped(*wargs, **wkwargs)
207 def wrapped(*wargs, **wkwargs):
208 combined_args, combined_kwargs = combine_arguments(wargs, wkwargs)
--> 209 return function(*combined_args, **combined_kwargs)
210 wrapped.__bound_function__ = function
211 return wrapped
~\AppData\Local\Temp\ipykernel_7148\3612203928.py in map_landvalue(zeit, pval)
7 test=df_kreise[df_kreise['Zeit']==zeit][['Kreise_Code',pval]]
8 test=pd.merge(kreise_map,test,on='Kreise_Code',how='outer')
----> 9 fig=test.dropna().hvplot(frame_height=550,frame_width=450,
10 hover_cols=['Kreise','Kreise_Code','pval_baureifsLand','pval_insgesamt'],
11 legend=False,c=pval,title=title_str,cmap='OrRd')
~\anaconda3\lib\site-packages\pandas\core\generic.py in __getattr__(self, name)
5573 ):
5574 return self[name]
-> 5575 return object.__getattribute__(self, name)
5576
5577 def __setattr__(self, name: str, value) -> None:
AttributeError: 'GeoDataFrame' object has no attribute 'hvplot'
Code:
import pandas as pd
import geopandas as gpd
import panel as pn
df_kreise=pd.read_csv('LandpriceFF_df.csv')
kreise_map=gpd.read_file('vg2500_geo84//vg2500_krs.dbf') #not in df_kreise [15001, 3152, 3156]
kreise_map['RS']=kreise_map['RS'].astype(int)
kreise_map=kreise_map.rename(columns={'RS':'Kreise_Code','GEN':'Kreise'})
de_map=gpd.read_file('vg2500_geo84//vg2500_sta.shp')
def map_landvalue(zeit,
pval):
title_str=' Germany '+pval+' Year '+str(zeit)
if pval == 'Baureifsland Purchase Value': pval='pval_baureifsLand'
elif pval=='Insgesamt Purchase Value': pval='pval_insgesamt'
test=df_kreise[df_kreise['Zeit']==zeit][['Kreise_Code',pval]]
test=pd.merge(kreise_map,test,on='Kreise_Code',how='outer')
fig=test.dropna().hvplot(frame_height=550,frame_width=450,
hover_cols=['Kreise','Kreise_Code','pval_baureifsLand','pval_insgesamt'],
legend=False,c=pval,title=title_str,cmap='OrRd')
return fig
pn.extension()
value_type=pn.widgets.Select(options=['Baureifsland Purchase Value','Insgesamt Purchase Value'])
years = pn.widgets.IntSlider(name="Jahre",value=2005,start=1995,end=2021,step=1)
de_map_plot = pn.Column(pn.Column(value_type,years),
pn.bind(map_landvalue,zeit=years,pval=value_type))
de_map_plot.show()
The datasets I am using are here: https://raw.githubusercontent.com/VolkaneicFox/IWH-Research/main/LandpriceFF_df.csv
https://raw.githubusercontent.com/VolkaneicFox/IWH-Research/main/vg2500_krs.shp
In order to use the holoviews pandas extension with df.hviews
methods, you must import hvplot.pandas
before the dataframe is created, even if you are never going to use the hvplot.pandas
module directly.
hvplot.pandas
is a critical import as it loads a holoviews pandas extension and registers holoviews with the pandas library so that dataframes created using pandas will have access to the DataFrame.hviews
attribute. Without this import, your regular pandas dataframes will not have the extension loaded and attempting to use the extension will simply raise an AttributeError
.
Note that geopandas.GeoDataFrame
is a subclass of pandas.DataFrame
and the above applies directly to geopandas as well. As with pandas, when reading a GeoDataFrame in from disk, the extension must be loaded before the read is called (before the geopandas object is created - but not necessarily before the file was written).
See the hvplot extension user guide for more info.