custom function for scatterplot in bokeh not running - python

dataset i am working on:
https://www.kaggle.com/code/gauravsahani/housing-in-london-for-beginners/data
i am using bokeh and have produced the following scatter plot
source=ColumnDataSource(data=dict(df,av=df.average_price,cr=df.no_of_crimes,ar=df.area))
p=figure(sizing_mode='stretch_width',toolbar_location=None,height=500,
x_axis_label='Average Salary',y_axis_label='crime rate')
p.xaxis.formatter = BasicTickFormatter(use_scientific=False)
p.add_layout(Legend(), 'right')
p.scatter(x='av',y='cr',source=source,size=9,alpha=0.4,legend_field='area',fill_color=factor_cmap('area',palette=magma(34),factors=df.area.unique()))
p.xgrid.grid_line_color=None
p.legend.label_text_font_size='12px'
p.legend.padding=4
p.legend.orientation='vertical'
p.legend.spacing=-7
p.add_tools(HoverTool(tooltips=[('Area','#ar')]))
show(p)
I am trying to produce a custom function for reusability which is the following:
source=ColumnDataSource(data=dict(df,av=df.average_price,
cr=df.no_of_crimes,
ar=df.area))
tooltips=[('Area','#ar')]
def scatter(source,x,y,xlabel=None,ylabel=None,size=None,alpha=None,legend_field=None,fill_color=None):
p=figure(sizing_mode='stretch_width',
toolbar_location=None,
height=500,
x_axis_label=xlabel,
y_axis_label=ylabel)
p.xgrid.grid_line_color=None
p.xaxis.formatter = BasicTickFormatter(use_scientific=False)
p.legend.label_text_font_size='12px'
p.legend.padding=4
p.legend.orientation='vertical'
p.legend.spacing=-7
p.scatter(source=source,x=x,y=y,size=size,alpha=alpha,legend_field=legend_field,fill_color=fill_color)
return p
p=scatter(source,x='av',y='cr')
show(p)
however I keep getting an error and I cant seem to figure out why since both my x and y columns are numerical values and already run successfuly when not working with a function. the error:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Input In [234], in <cell line: 24>()
20 p.scatter(source=source,x=x,y=y,size=size,alpha=alpha,legend_field=legend_field,fill_color=fill_color)
22 return p
---> 24 p=scatter(source,x='av',y='cr')
26 show(p)
Input In [234], in scatter(source, x, y, xlabel, ylabel, size, alpha, legend_field, fill_color)
17 p.legend.orientation='vertical'
18 p.legend.spacing=-7
---> 20 p.scatter(source=source,x=x,y=y,size=size,alpha=alpha,legend_field=legend_field,fill_color=fill_color)
22 return p
File ~\Anaconda3\lib\site-packages\bokeh\plotting\glyph_api.py:962, in GlyphAPI.scatter(self, *args, **kwargs)
960 return self.circle(*args, **kwargs)
961 else:
--> 962 return self._scatter(*args, marker=marker_type, **kwargs)
File ~\Anaconda3\lib\site-packages\bokeh\plotting\_decorators.py:86, in glyph_method.<locals>.decorator.<locals>.wrapped(self, *args, **kwargs)
84 if self.coordinates is not None:
85 kwargs.setdefault("coordinates", self.coordinates)
---> 86 return create_renderer(glyphclass, self.plot, **kwargs)
File ~\Anaconda3\lib\site-packages\bokeh\plotting\_renderer.py:116, in create_renderer(glyphclass, plot, **kwargs)
113 # handle the mute glyph, we always set one
114 muted_visuals = pop_visuals(glyphclass, kwargs, prefix='muted_', defaults=glyph_visuals, override_defaults={'alpha':0.2})
--> 116 glyph = make_glyph(glyphclass, kwargs, glyph_visuals)
117 nonselection_glyph = make_glyph(glyphclass, kwargs, nonselection_visuals)
118 selection_glyph = make_glyph(glyphclass, kwargs, selection_visuals)
File ~\Anaconda3\lib\site-packages\bokeh\plotting\_renderer.py:145, in make_glyph(glyphclass, kws, extra)
143 kws = kws.copy()
144 kws.update(extra)
--> 145 return glyphclass(**kws)
File ~\Anaconda3\lib\site-packages\bokeh\model\model.py:128, in Model.__init__(self, **kwargs)
121 def __init__(self, **kwargs: Any) -> None:
122
123 # "id" is popped from **kw in __new__, so in an ideal world I don't
124 # think it should be here too. But Python has subtle behavior here, so
125 # it is necessary
126 kwargs.pop("id", None)
--> 128 super().__init__(**kwargs)
129 default_theme.apply_to_model(self)
File ~\Anaconda3\lib\site-packages\bokeh\core\has_props.py:206, in HasProps.__init__(self, **properties)
203 self._unstable_themed_values = {}
205 for name, value in properties.items():
--> 206 setattr(self, name, value)
208 self._initialized = True
File ~\Anaconda3\lib\site-packages\bokeh\core\has_props.py:230, in HasProps.__setattr__(self, name, value)
228 properties = self.properties(_with_props=True)
229 if name in properties:
--> 230 return super().__setattr__(name, value)
232 descriptor = getattr(self.__class__, name, None)
233 if isinstance(descriptor, property): # Python property
File ~\Anaconda3\lib\site-packages\bokeh\core\property\descriptors.py:283, in PropertyDescriptor.__set__(self, obj, value, setter)
280 class_name = obj.__class__.__name__
281 raise RuntimeError(f"{class_name}.{self.name} is a readonly property")
--> 283 value = self.property.prepare_value(obj, self.name, value)
284 old = self._get(obj)
285 self._set(obj, old, value, setter=setter)
File ~\Anaconda3\lib\site-packages\bokeh\core\property\dataspec.py:515, in SizeSpec.prepare_value(self, cls, name, value)
513 except TypeError:
514 pass
--> 515 return super().prepare_value(cls, name, value)
File ~\Anaconda3\lib\site-packages\bokeh\core\property\bases.py:365, in Property.prepare_value(self, owner, name, value, hint)
363 else:
364 obj_repr = owner if isinstance(owner, HasProps) else owner.__name__
--> 365 raise ValueError(f"failed to validate {obj_repr}.{name}: {error}")
367 if isinstance(owner, HasProps):
368 obj = owner
ValueError: failed to validate Scatter(id='40569', ...).size: expected an element of either String, Dict(Enum('expr', 'field', 'value', 'transform'), Either(String, Instance(Transform), Instance(Expression), Float)) or Float, got None
any help would be great

def scatter(source,x,y,xlabel=None,ylabel=None,size=5,alpha=1,legend_field=str(None),fill_color=None):
p=figure(sizing_mode='stretch_width',
toolbar_location=None,
height=500,
x_axis_label=xlabel,
y_axis_label=ylabel)
p.xgrid.grid_line_color=None
p.xaxis.formatter = BasicTickFormatter(use_scientific=False)
p.legend.label_text_font_size='12px'
p.legend.padding=4
p.legend.orientation='vertical'
p.legend.spacing=-7
if legend_field == str(None):
p.scatter(source=source,x=x,y=y,size=size,alpha=alpha,fill_color=fill_color)
else:
p.scatter(source=source,x=x,y=y,size=size,alpha=alpha,legend_field=legend_field,fill_color=fill_color)
return p

Related

Cannot plot datetime64[ns] on hvplot axis ('pandas_datetime_types' is not defined' error)

I am simply trying to plot some values against datetime64[ns] timestamps with holoviews.
That is,
x-axis = nx1 datetime64[ns] values
y-axis = nx1 data.
Here is a screen shot of what I have:
Screenshot of my dataframe
<class 'pandas._libs.tslibs.timestamps.Timestamp'>
and my overall code:
import hvplot.pandas
import pandas as pd
##
Code ommitted at the start to extract data and create dictionary to convert to data frame
##
#create dictionary
temp_dict = dict(sampling_time=time_y_value_is_taken, y_axis_values = y_values)
df = pd.Dataframe.from_dict(temp_dict)
df.sampling_time=df.sampling_time.astype('datetime64[ns]')
df=df.set_index('sampling_time')
##The following code cannot run this line- it throws error
df.hvplot.line()
I keep getting the error code : 'pandas_datetime_types' is not defined. I have also tried importing datetime as datetime - but it does not work.
EDIT: Here is the traceback:
---------------------------------------------------------------------------
NameError Traceback (most recent call last)
~\miniconda3\envs\mpess_visual\lib\site-packages\IPython\core\formatters.py in __call__(self, obj, include, exclude)
968
969 if method is not None:
--> 970 return method(include=include, exclude=exclude)
971 return None
972 else:
~\miniconda3\envs\mpess_visual\lib\site-packages\holoviews\core\dimension.py in _repr_mimebundle_(self, include, exclude)
1315 combined and returned.
1316 """
-> 1317 return Store.render(self)
1318
1319
~\miniconda3\envs\mpess_visual\lib\site-packages\holoviews\core\options.py in render(cls, obj)
1403 data, metadata = {}, {}
1404 for hook in hooks:
-> 1405 ret = hook(obj)
1406 if ret is None:
1407 continue
~\miniconda3\envs\mpess_visual\lib\site-packages\holoviews\ipython\display_hooks.py in pprint_display(obj)
280 if not ip.display_formatter.formatters['text/plain'].pprint:
281 return None
--> 282 return display(obj, raw_output=True)
283
284
~\miniconda3\envs\mpess_visual\lib\site-packages\holoviews\ipython\display_hooks.py in display(obj, raw_output, **kwargs)
250 elif isinstance(obj, (CompositeOverlay, ViewableElement)):
251 with option_state(obj):
--> 252 output = element_display(obj)
253 elif isinstance(obj, (Layout, NdLayout, AdjointLayout)):
254 with option_state(obj):
~\miniconda3\envs\mpess_visual\lib\site-packages\holoviews\ipython\display_hooks.py in wrapped(element)
144 try:
145 max_frames = OutputSettings.options['max_frames']
--> 146 mimebundle = fn(element, max_frames=max_frames)
147 if mimebundle is None:
148 return {}, {}
~\miniconda3\envs\mpess_visual\lib\site-packages\holoviews\ipython\display_hooks.py in element_display(element, max_frames)
190 return None
191
--> 192 return render(element)
193
194
~\miniconda3\envs\mpess_visual\lib\site-packages\holoviews\ipython\display_hooks.py in render(obj, **kwargs)
66 renderer = renderer.instance(fig='png')
67
---> 68 return renderer.components(obj, **kwargs)
69
70
~\miniconda3\envs\mpess_visual\lib\site-packages\holoviews\plotting\renderer.py in components(self, obj, fmt, comm, **kwargs)
408 doc = Document()
409 with config.set(embed=embed):
--> 410 model = plot.layout._render_model(doc, comm)
411 if embed:
412 return render_model(model, comm)
~\miniconda3\envs\mpess_visual\lib\site-packages\panel\viewable.py in _render_model(self, doc, comm)
453 if comm is None:
454 comm = state._comm_manager.get_server_comm()
--> 455 model = self.get_root(doc, comm)
456
457 if config.embed:
~\miniconda3\envs\mpess_visual\lib\site-packages\panel\viewable.py in get_root(self, doc, comm, preprocess)
510 """
511 doc = init_doc(doc)
--> 512 root = self._get_model(doc, comm=comm)
513 if preprocess:
514 self._preprocess(root)
~\miniconda3\envs\mpess_visual\lib\site-packages\panel\layout\base.py in _get_model(self, doc, root, parent, comm)
120 if root is None:
121 root = model
--> 122 objects = self._get_objects(model, [], doc, root, comm)
123 props = dict(self._init_params(), objects=objects)
124 model.update(**self._process_param_change(props))
~\miniconda3\envs\mpess_visual\lib\site-packages\panel\layout\base.py in _get_objects(self, model, old_objects, doc, root, comm)
110 else:
111 try:
--> 112 child = pane._get_model(doc, root, model, comm)
113 except RerenderError:
114 return self._get_objects(model, current_objects[:i], doc, root, comm)
~\miniconda3\envs\mpess_visual\lib\site-packages\panel\pane\holoviews.py in _get_model(self, doc, root, parent, comm)
237 plot = self.object
238 else:
--> 239 plot = self._render(doc, comm, root)
240
241 plot.pane = self
~\miniconda3\envs\mpess_visual\lib\site-packages\panel\pane\holoviews.py in _render(self, doc, comm, root)
304 kwargs['comm'] = comm
305
--> 306 return renderer.get_plot(self.object, **kwargs)
307
308 def _cleanup(self, root):
~\miniconda3\envs\mpess_visual\lib\site-packages\holoviews\plotting\bokeh\renderer.py in get_plot(self_or_cls, obj, doc, renderer, **kwargs)
71 combining the bokeh model with another plot.
72 """
---> 73 plot = super(BokehRenderer, self_or_cls).get_plot(obj, doc, renderer, **kwargs)
74 if plot.document is None:
75 plot.document = Document() if self_or_cls.notebook_context else curdoc()
~\miniconda3\envs\mpess_visual\lib\site-packages\holoviews\plotting\renderer.py in get_plot(self_or_cls, obj, doc, renderer, comm, **kwargs)
241 init_key = tuple(v if d is None else d for v, d in
242 zip(plot.keys[0], defaults))
--> 243 plot.update(init_key)
244 else:
245 plot = obj
~\miniconda3\envs\mpess_visual\lib\site-packages\holoviews\plotting\plot.py in update(self, key)
980 def update(self, key):
981 if len(self) == 1 and ((key == 0) or (key == self.keys[0])) and not self.drawn:
--> 982 return self.initialize_plot()
983 item = self.__getitem__(key)
984 self.traverse(lambda x: setattr(x, '_updated', True))
~\miniconda3\envs\mpess_visual\lib\site-packages\holoviews\plotting\bokeh\element.py in initialize_plot(self, ranges, plot, plots, source)
1388 element = self.hmap.last
1389 key = util.wrap_tuple(self.hmap.last_key)
-> 1390 ranges = self.compute_ranges(self.hmap, key, ranges)
1391 self.current_ranges = ranges
1392 self.current_frame = element
~\miniconda3\envs\mpess_visual\lib\site-packages\holoviews\plotting\plot.py in compute_ranges(self, obj, key, ranges)
636 if (not (axiswise and not isinstance(obj, HoloMap)) or
637 (not framewise and isinstance(obj, HoloMap))):
--> 638 self._compute_group_range(group, elements, ranges, framewise,
639 axiswise, robust, self.top_level,
640 prev_frame)
~\miniconda3\envs\mpess_visual\lib\site-packages\holoviews\plotting\plot.py in _compute_group_range(cls, group, elements, ranges, framewise, axiswise, robust, top_level, prev_frame)
853 continue
854 matching &= (
--> 855 len({'date' if isinstance(v, util.datetime_types) else 'number'
856 for rng in rs for v in rng if util.isfinite(v)}) < 2
857 )
~\miniconda3\envs\mpess_visual\lib\site-packages\holoviews\plotting\plot.py in <setcomp>(.0)
854 matching &= (
855 len({'date' if isinstance(v, util.datetime_types) else 'number'
--> 856 for rng in rs for v in rng if util.isfinite(v)}) < 2
857 )
858 if matching:
~\miniconda3\envs\mpess_visual\lib\site-packages\holoviews\core\util.py in isfinite(val)
902 return finite
903 elif isinstance(val, datetime_types+timedelta_types):
--> 904 return not isnat(val)
905 elif isinstance(val, (basestring, bytes)):
906 return True
~\miniconda3\envs\mpess_visual\lib\site-packages\holoviews\core\util.py in isnat(val)
866 elif pd and val is pd.NaT:
867 return True
--> 868 elif pd and isinstance(val, pandas_datetime_types+pandas_timedelta_types):
869 return pd.isna(val)
870 else:
NameError: name 'pandas_datetime_types' is not defined
Any suggestions? Thank you
Although I couldn't find any official doc to support my statement, it's a compatibility issue (HoloViews 1.14.4 was released before Pandas 1.3.0).
Looking at [gitHub]: holoviz/holoviews - (v1.14.4) holoviews/holoviews/core/util.py (starting with line #83), there are some conditional imports. One of them is ABCIndexClass.
[GitHub]: pandas-dev/pandas - (v1.3.0) pandas/pandas/core/dtypes/dtypes.py on the other hand, does not provide it (as opposed from let's say its v1.2.5 counterpart) yielding (silent) exception, and the behavior you're experiencing.
Ways to go:
Upgrade HoloViews to v1.14.5 which no longer has this problem, (or at least, there's a Pandas 1.3.0 conditional as well - fixed by [GitHub]: holoviz/holoviews - Add support for pandas>=1.3)
You could also downgrade Pandas to (e.g.) v1.2.5, although this is not the way to go

Networkx graph exporting to Pyvis - TypeError: Object of type int64 is not JSON serializable

I have a dataframe as below
Quote ID Quote Date Email Phone VIN
0 1410095416 6/6/2021 DAMIONADAE#GMAIL.COM 4049366688 1C4RJFBG9EC2267
1 1410143058 6/6/2021 BEEZZZHAPPY#YAHOO.COM 3122340791 NaN
2 1408893417 6/3/2021 MONEYKAY38#YAHOO.COM 2149004015 1J8HG48NX6C2470
3 1408764243 6/2/2021 TIFFANYLESTER419#GMAIL.COM 5024647900 JN8AZ08W57W6527
4 1408639003 6/2/2021 MONEYTEAM799#YAHOO.COM 2149001015 1ZVBP8AM3E52605
I'm using a function to generate network graph. The below function takes the dataframe, node and edges to generate the Graph.
def create_network(df, node, column_edge, column_edge1=None, column_edge2=None):
# select columns, remove NaN
df_edge1 = df[[node, column_edge]].dropna(subset=[column_edge]).drop_duplicates()
# To create connections between "node" who have the same "edge",
# join data with itself on the "node" column.
df_edge1 = df_edge1.merge(
df_edge1[[node, column_edge]].rename(columns={node:node+"_2"}),
on=column_edge
)
# By joining the data with itself, node will have a connection with themselves.
# Remove self connections, to keep only connected nodes which are different.
edge1 = df_edge1[~(df_edge1[node]==df_edge1[node+"_2"])].dropna()[[node, node +"_2", column_edge]]
# To avoid counting twice the connections (person 1 connected to person 2 and person 2 connected to person 1)
# we force the first ID to be "lower" then ID_2
edge1.drop(edge1.loc[edge1[node+"_2"]<edge1[node]].index.tolist(), inplace=True)
G = nx.from_pandas_edgelist(df=edge1, source=node, target=node + '_2', edge_attr=column_edge)
G.add_nodes_from(nodes_for_adding=df[node].tolist())
if column_edge1:
df_edge2 = df[[node, column_edge1]].dropna(subset=[column_edge1]).drop_duplicates()
df_edge2 = df_edge2.merge(
df_edge2[[node, column_edge1]].rename(columns={node:node+"_2"}),
on=column_edge1
)
edge2 = df_edge2[~(df_edge2[node]==df_edge2[node+"_2"])].dropna()[[node, node+"_2", column_edge1]]
edge2.drop(edge2.loc[edge2[node+"_2"]<edge2[node]].index.tolist(), inplace=True)
# Create the connections in the graph
links_attributes = {tuple(row[[node, node+"_2"]]): {column_edge1: row[column_edge1]} for i,row in edge2.iterrows()}
# create the connection, without attribute.
G.add_edges_from(links_attributes)
# adds the attribute.
nx.set_edge_attributes(G=G, values=links_attributes)
if column_edge2:
df_edge3 = df[[node, column_edge2]].dropna(subset=[column_edge2]).drop_duplicates()
df_edge3 = df_edge3.merge(
df_edge3[[node, column_edge2]].rename(columns={node:node+"_2"}),
on=column_edge2
)
edge3 = df_edge3[~(df_edge3[node]==df_edge3[node+"_2"])].dropna()[[node, node+"_2", column_edge2]]
edge3.drop(edge3.loc[edge3[node+"_2"]<edge3[node]].index.tolist(), inplace=True)
# Create the connections in the graph
links_attributes2 = {tuple(row[[node, node+"_2"]]): {column_edge2: row[column_edge2]} for i,row in edge3.iterrows()}
# create the connection, without attribute.
G.add_edges_from(links_attributes2)
# adds the attribute.
nx.set_edge_attributes(G=G, values=links_attributes2)
return G
Calling the above function
GE3 = create_network(data, 'Quote ID', "Email", column_edge1="Phone", column_edge2="VIN")
Graph info
Name:
Type: Graph
Number of nodes: 2441
Number of edges: 8374
Average degree: 6.8611
# import pyvis
from pyvis.network import Network
# # create vis network
net = Network(notebook=True, width=1000, height=600)
# load the networkx graph
net.from_nx(GE3)
# show
net.show("pyvis_example.html")
When I'm trying to export the graph using pyvis. I'm getting a
TypeError: Object of type int64 is not JSON serializable
Below is the complete error
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-35-b34699ea995d> in <module>()
17 net.from_nx(GE3)
18 # show
---> 19 net.show("pyvis_example.html")
10 frames
/usr/local/lib/python3.7/dist-packages/pyvis/network.py in show(self, name)
474 check_html(name)
475 if self.template is not None:
--> 476 return self.write_html(name, notebook=True)
477 else:
478 self.write_html(name)
/usr/local/lib/python3.7/dist-packages/pyvis/network.py in write_html(self, name, notebook)
457 bgcolor=self.bgcolor,
458 conf=self.conf,
--> 459 tooltip_link=use_link_template)
460
461 with open(name, "w+") as out:
/usr/local/lib/python3.7/dist-packages/jinja2/environment.py in render(self, *args, **kwargs)
1088 return concat(self.root_render_func(self.new_context(vars)))
1089 except Exception:
-> 1090 self.environment.handle_exception()
1091
1092 def render_async(self, *args, **kwargs):
/usr/local/lib/python3.7/dist-packages/jinja2/environment.py in handle_exception(self, source)
830 from .debug import rewrite_traceback_stack
831
--> 832 reraise(*rewrite_traceback_stack(source=source))
833
834 def join_path(self, template, parent):
/usr/local/lib/python3.7/dist-packages/jinja2/_compat.py in reraise(tp, value, tb)
26 def reraise(tp, value, tb=None):
27 if value.__traceback__ is not tb:
---> 28 raise value.with_traceback(tb)
29 raise value
30
<template> in top-level template code()
/usr/local/lib/python3.7/dist-packages/jinja2/filters.py in do_tojson(eval_ctx, value, indent)
1258 options = dict(options)
1259 options["indent"] = indent
-> 1260 return htmlsafe_json_dumps(value, dumper=dumper, **options)
1261
1262
/usr/local/lib/python3.7/dist-packages/jinja2/utils.py in htmlsafe_json_dumps(obj, dumper, **kwargs)
617 dumper = json.dumps
618 rv = (
--> 619 dumper(obj, **kwargs)
620 .replace(u"<", u"\\u003c")
621 .replace(u">", u"\\u003e")
/usr/lib/python3.7/json/__init__.py in dumps(obj, skipkeys, ensure_ascii, check_circular, allow_nan, cls, indent, separators, default, sort_keys, **kw)
236 check_circular=check_circular, allow_nan=allow_nan, indent=indent,
237 separators=separators, default=default, sort_keys=sort_keys,
--> 238 **kw).encode(obj)
239
240
/usr/lib/python3.7/json/encoder.py in encode(self, o)
197 # exceptions aren't as detailed. The list call should be roughly
198 # equivalent to the PySequence_Fast that ''.join() would do.
--> 199 chunks = self.iterencode(o, _one_shot=True)
200 if not isinstance(chunks, (list, tuple)):
201 chunks = list(chunks)
/usr/lib/python3.7/json/encoder.py in iterencode(self, o, _one_shot)
255 self.key_separator, self.item_separator, self.sort_keys,
256 self.skipkeys, _one_shot)
--> 257 return _iterencode(o, 0)
258
259 def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,
/usr/lib/python3.7/json/encoder.py in default(self, o)
177
178 """
--> 179 raise TypeError(f'Object of type {o.__class__.__name__} '
180 f'is not JSON serializable')
181
TypeError: Object of type int64 is not JSON serializable
I think the error is from the Graph network but I'm not sure where exactly is this happening and how to fix this....
Can anyone shed some light to fix this issue?
Make sure that your node indices are int types and not int64 or int32. Same would go for your edge construction. I would recommend checking the type of your df[node] pandas series.
Try casting to int all variables you know are int. In python, you can cast in this way: int(int64var).
If you don't want to cast all variables, you can debug your code and see variable per variable, if the variable type is correct.

Hvplot AttributeError: 'list' object has no attribute 'xy'

I have trouble making a interactive map with PySAL. I want to visualize the dutch 'gemeente' (Municipalities). You can download shape files from the dutch bureau of statistics: https://www.cbs.nl/nl-nl/dossier/nederland-regionaal/geografische-data/wijk-en-buurtkaart-2019
import geopandas as gpd
import hvplot.pandas
coords = gpd.read_file('gemeente_2019_v2.shp')
coords.hvplot(geo = True)
This raises an error that 'list' object has no attribute 'xy'.
I used PySAL 2.1.0 and tried upgrading to 2.4.0, but this made no difference.
Output:
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
~\.conda\envs\jh-open\lib\site-packages\IPython\core\formatters.py in __call__(self, obj, include, exclude)
968
969 if method is not None:
--> 970 return method(include=include, exclude=exclude)
971 return None
972 else:
~\.conda\envs\jh-open\lib\site-packages\holoviews\core\dimension.py in _repr_mimebundle_(self, include, exclude)
1315 combined and returned.
1316 """
-> 1317 return Store.render(self)
1318
1319
~\.conda\envs\jh-open\lib\site-packages\holoviews\core\options.py in render(cls, obj)
1403 data, metadata = {}, {}
1404 for hook in hooks:
-> 1405 ret = hook(obj)
1406 if ret is None:
1407 continue
~\.conda\envs\jh-open\lib\site-packages\holoviews\ipython\display_hooks.py in pprint_display(obj)
280 if not ip.display_formatter.formatters['text/plain'].pprint:
281 return None
--> 282 return display(obj, raw_output=True)
283
284
~\.conda\envs\jh-open\lib\site-packages\holoviews\ipython\display_hooks.py in display(obj, raw_output, **kwargs)
250 elif isinstance(obj, (CompositeOverlay, ViewableElement)):
251 with option_state(obj):
--> 252 output = element_display(obj)
253 elif isinstance(obj, (Layout, NdLayout, AdjointLayout)):
254 with option_state(obj):
~\.conda\envs\jh-open\lib\site-packages\holoviews\ipython\display_hooks.py in wrapped(element)
144 try:
145 max_frames = OutputSettings.options['max_frames']
--> 146 mimebundle = fn(element, max_frames=max_frames)
147 if mimebundle is None:
148 return {}, {}
~\.conda\envs\jh-open\lib\site-packages\holoviews\ipython\display_hooks.py in element_display(element, max_frames)
190 return None
191
--> 192 return render(element)
193
194
~\.conda\envs\jh-open\lib\site-packages\holoviews\ipython\display_hooks.py in render(obj, **kwargs)
66 renderer = renderer.instance(fig='png')
67
---> 68 return renderer.components(obj, **kwargs)
69
70
~\.conda\envs\jh-open\lib\site-packages\holoviews\plotting\renderer.py in components(self, obj, fmt, comm, **kwargs)
408 doc = Document()
409 with config.set(embed=embed):
--> 410 model = plot.layout._render_model(doc, comm)
411 if embed:
412 return render_model(model, comm)
~\.conda\envs\jh-open\lib\site-packages\panel\viewable.py in _render_model(self, doc, comm)
425 if comm is None:
426 comm = state._comm_manager.get_server_comm()
--> 427 model = self.get_root(doc, comm)
428
429 if config.embed:
~\.conda\envs\jh-open\lib\site-packages\panel\viewable.py in get_root(self, doc, comm, preprocess)
482 """
483 doc = init_doc(doc)
--> 484 root = self._get_model(doc, comm=comm)
485 if preprocess:
486 self._preprocess(root)
~\.conda\envs\jh-open\lib\site-packages\panel\layout\base.py in _get_model(self, doc, root, parent, comm)
111 if root is None:
112 root = model
--> 113 objects = self._get_objects(model, [], doc, root, comm)
114 props = dict(self._init_params(), objects=objects)
115 model.update(**self._process_param_change(props))
~\.conda\envs\jh-open\lib\site-packages\panel\layout\base.py in _get_objects(self, model, old_objects, doc, root, comm)
101 else:
102 try:
--> 103 child = pane._get_model(doc, root, model, comm)
104 except RerenderError:
105 return self._get_objects(model, current_objects[:i], doc, root, comm)
~\.conda\envs\jh-open\lib\site-packages\panel\pane\holoviews.py in _get_model(self, doc, root, parent, comm)
237 plot = self.object
238 else:
--> 239 plot = self._render(doc, comm, root)
240
241 plot.pane = self
~\.conda\envs\jh-open\lib\site-packages\panel\pane\holoviews.py in _render(self, doc, comm, root)
302 kwargs['comm'] = comm
303
--> 304 return renderer.get_plot(self.object, **kwargs)
305
306 def _cleanup(self, root):
~\.conda\envs\jh-open\lib\site-packages\holoviews\plotting\bokeh\renderer.py in get_plot(self_or_cls, obj, doc, renderer, **kwargs)
71 combining the bokeh model with another plot.
72 """
---> 73 plot = super(BokehRenderer, self_or_cls).get_plot(obj, doc, renderer, **kwargs)
74 if plot.document is None:
75 plot.document = Document() if self_or_cls.notebook_context else curdoc()
~\.conda\envs\jh-open\lib\site-packages\holoviews\plotting\renderer.py in get_plot(self_or_cls, obj, doc, renderer, comm, **kwargs)
241 init_key = tuple(v if d is None else d for v, d in
242 zip(plot.keys[0], defaults))
--> 243 plot.update(init_key)
244 else:
245 plot = obj
~\.conda\envs\jh-open\lib\site-packages\holoviews\plotting\plot.py in update(self, key)
980 def update(self, key):
981 if len(self) == 1 and ((key == 0) or (key == self.keys[0])) and not self.drawn:
--> 982 return self.initialize_plot()
983 item = self.__getitem__(key)
984 self.traverse(lambda x: setattr(x, '_updated', True))
~\.conda\envs\jh-open\lib\site-packages\geoviews\plotting\bokeh\plot.py in initialize_plot(self, ranges, plot, plots, source)
111 def initialize_plot(self, ranges=None, plot=None, plots=None, source=None):
112 opts = {} if isinstance(self, HvOverlayPlot) else {'source': source}
--> 113 fig = super(GeoPlot, self).initialize_plot(ranges, plot, plots, **opts)
114 if self.geographic and self.show_bounds and not self.overlaid:
115 from . import GeoShapePlot
~\.conda\envs\jh-open\lib\site-packages\holoviews\plotting\bokeh\element.py in initialize_plot(self, ranges, plot, plots, source)
1394 # Initialize plot, source and glyph
1395 if plot is None:
-> 1396 plot = self._init_plot(key, style_element, ranges=ranges, plots=plots)
1397 self._init_axes(plot)
1398 else:
~\.conda\envs\jh-open\lib\site-packages\holoviews\plotting\bokeh\element.py in _init_plot(self, key, element, plots, ranges)
492 subplots = list(self.subplots.values()) if self.subplots else []
493
--> 494 axis_types, labels, plot_ranges = self._axes_props(plots, subplots, element, ranges)
495 xlabel, ylabel, _ = labels
496 x_axis_type, y_axis_type = axis_types
~\.conda\envs\jh-open\lib\site-packages\holoviews\plotting\bokeh\element.py in _axes_props(self, plots, subplots, element, ranges)
403 # Get the Element that determines the range and get_extents
404 range_el = el if self.batched and not isinstance(self, OverlayPlot) else element
--> 405 l, b, r, t = self.get_extents(range_el, ranges)
406 if self.invert_axes:
407 l, b, r, t = b, l, t, r
~\.conda\envs\jh-open\lib\site-packages\geoviews\plotting\plot.py in get_extents(self, element, ranges, range_type)
71 extents = None
72 else:
---> 73 extents = project_extents(extents, element.crs, proj)
74 return (np.NaN,)*4 if not extents else extents
~\.conda\envs\jh-open\lib\site-packages\geoviews\util.py in project_extents(extents, src_proj, dest_proj, tol)
95 geom_in_src_proj = geom_clipped_to_dest_proj
96 try:
---> 97 geom_in_crs = dest_proj.project_geometry(geom_in_src_proj, src_proj)
98 except ValueError:
99 src_name =type(src_proj).__name__
~\.conda\envs\jh-open\lib\site-packages\cartopy\crs.py in project_geometry(self, geometry, src_crs)
216 raise ValueError('Unsupported geometry '
217 'type {!r}'.format(geom_type))
--> 218 return getattr(self, method_name)(geometry, src_crs)
219
220 def _project_point(self, point, src_crs):
~\.conda\envs\jh-open\lib\site-packages\cartopy\crs.py in _project_polygon(self, polygon, src_crs)
352 is_ccw = True
353 else:
--> 354 is_ccw = polygon.exterior.is_ccw
355 # Project the polygon exterior/interior rings.
356 # Each source ring will result in either a ring, or one or more
~\.conda\envs\jh-open\lib\site-packages\shapely\geometry\polygon.py in is_ccw(self)
86 def is_ccw(self):
87 """True is the ring is oriented counter clock-wise"""
---> 88 return bool(self.impl['is_ccw'](self))
89
90 #property
~\.conda\envs\jh-open\lib\site-packages\shapely\algorithms\cga.py in is_ccw_op(ring)
12 """Predicate implementation"""
13 def is_ccw_op(ring):
---> 14 return signed_area(ring) >= 0.0
15 return is_ccw_op
16
~\.conda\envs\jh-open\lib\site-packages\shapely\algorithms\cga.py in signed_area(ring)
4 algorithm at: https://web.archive.org/web/20080209143651/http://cgafaq.info:80/wiki/Polygon_Area
5 """
----> 6 xs, ys = ring.coords.xy
7 xs.append(xs[1])
8 ys.append(ys[1])
AttributeError: 'list' object has no attribute 'xy'
:Polygons [Longitude,Latitude]
The issue is related to the Coordinate Reference System of the shapefile.
Looking at coords.crs shows EPSG:28992.
You can get hvplot to work with this:
from cartopy import crs
coords.hvplot(geo = True, crs=crs.epsg(28992))
I am not sure if this would be considered an issue or not. It may be worth reporting in the github repo.

Error when using pandas dataframe in R cell, in rpy2, Jupyter Notebook

I want to use ggplot2 within Jupyter Notebook. However, when I try to make an R magic cell and introduce a variable, I get an error.
Here is the code (one paragraph indicates one cell):
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import rpy2
%matplotlib inline
from rpy2.robjects import pandas2ri
pandas2ri.activate()
%load_ext rpy2.ipython
%%R
library(ggplot2)
data = pd.read_csv('train_titanic.csv')
%%R -i data -w 900 -h 480 -u px
With this last cell, I get the following error (incl traceback):
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
~/anaconda3/envs/catenv/lib/python3.7/site-packages/rpy2/robjects/pandas2ri.py in py2rpy_pandasdataframe(obj)
54 try:
---> 55 od[name] = conversion.py2rpy(values)
56 except Exception as e:
~/anaconda3/envs/catenv/lib/python3.7/functools.py in wrapper(*args, **kw)
839
--> 840 return dispatch(args[0].__class__)(*args, **kw)
841
~/anaconda3/envs/catenv/lib/python3.7/site-packages/rpy2/robjects/pandas2ri.py in py2rpy_pandasseries(obj)
125 if type(x) is not homogeneous_type:
--> 126 raise ValueError('Series can only be of one type, or None.')
127 # TODO: Could this be merged with obj.type.name == 'O' case above ?
ValueError: Series can only be of one type, or None.
During handling of the above exception, another exception occurred:
TypeError Traceback (most recent call last)
~/anaconda3/envs/catenv/lib/python3.7/site-packages/rpy2/rinterface_lib/sexp.py in from_object(cls, obj)
367 try:
--> 368 mv = memoryview(obj)
369 res = cls.from_memoryview(mv)
TypeError: memoryview: a bytes-like object is required, not 'Series'
During handling of the above exception, another exception occurred:
AttributeError Traceback (most recent call last)
<ipython-input-14-75e210679e4a> in <module>
----> 1 get_ipython().run_cell_magic('R', '-i data -w 900 -h 480 -u px', '\n\n')
~/anaconda3/envs/catenv/lib/python3.7/site-packages/IPython/core/interactiveshell.py in run_cell_magic(self, magic_name, line, cell)
2360 with self.builtin_trap:
2361 args = (magic_arg_s, cell)
-> 2362 result = fn(*args, **kwargs)
2363 return result
2364
</home/morgan/anaconda3/envs/catenv/lib/python3.7/site-packages/decorator.py:decorator-gen-130> in R(self, line, cell, local_ns)
~/anaconda3/envs/catenv/lib/python3.7/site-packages/IPython/core/magic.py in <lambda>(f, *a, **k)
185 # but it's overkill for just that one bit of state.
186 def magic_deco(arg):
--> 187 call = lambda f, *a, **k: f(*a, **k)
188
189 if callable(arg):
~/anaconda3/envs/catenv/lib/python3.7/site-packages/rpy2/ipython/rmagic.py in R(self, line, cell, local_ns)
721 raise NameError("name '%s' is not defined" % input)
722 with localconverter(converter) as cv:
--> 723 ro.r.assign(input, val)
724
725 tmpd = self.setup_graphics(args)
~/anaconda3/envs/catenv/lib/python3.7/site-packages/rpy2/robjects/functions.py in __call__(self, *args, **kwargs)
190 kwargs[r_k] = v
191 return (super(SignatureTranslatedFunction, self)
--> 192 .__call__(*args, **kwargs))
193
194
~/anaconda3/envs/catenv/lib/python3.7/site-packages/rpy2/robjects/functions.py in __call__(self, *args, **kwargs)
111
112 def __call__(self, *args, **kwargs):
--> 113 new_args = [conversion.py2rpy(a) for a in args]
114 new_kwargs = {}
115 for k, v in kwargs.items():
~/anaconda3/envs/catenv/lib/python3.7/site-packages/rpy2/robjects/functions.py in <listcomp>(.0)
111
112 def __call__(self, *args, **kwargs):
--> 113 new_args = [conversion.py2rpy(a) for a in args]
114 new_kwargs = {}
115 for k, v in kwargs.items():
~/anaconda3/envs/catenv/lib/python3.7/functools.py in wrapper(*args, **kw)
838 '1 positional argument')
839
--> 840 return dispatch(args[0].__class__)(*args, **kw)
841
842 funcname = getattr(func, '__name__', 'singledispatch function')
~/anaconda3/envs/catenv/lib/python3.7/site-packages/rpy2/robjects/pandas2ri.py in py2rpy_pandasdataframe(obj)
59 'The error is: %s'
60 % (name, str(e)))
---> 61 od[name] = StrVector(values)
62
63 return DataFrame(od)
~/anaconda3/envs/catenv/lib/python3.7/site-packages/rpy2/robjects/vectors.py in __init__(self, obj)
382
383 def __init__(self, obj):
--> 384 super().__init__(obj)
385 self._add_rops()
386
~/anaconda3/envs/catenv/lib/python3.7/site-packages/rpy2/rinterface_lib/sexp.py in __init__(self, obj)
286 super().__init__(obj)
287 elif isinstance(obj, collections.abc.Sized):
--> 288 super().__init__(type(self).from_object(obj).__sexp__)
289 else:
290 raise TypeError('The constructor must be called '
~/anaconda3/envs/catenv/lib/python3.7/site-packages/rpy2/rinterface_lib/sexp.py in from_object(cls, obj)
370 except (TypeError, ValueError):
371 try:
--> 372 res = cls.from_iterable(obj)
373 except ValueError:
374 msg = ('The class methods from_memoryview() and '
~/anaconda3/envs/catenv/lib/python3.7/site-packages/rpy2/rinterface_lib/conversion.py in _(*args, **kwargs)
26 def _cdata_res_to_rinterface(function):
27 def _(*args, **kwargs):
---> 28 cdata = function(*args, **kwargs)
29 # TODO: test cdata is of the expected CType
30 return _cdata_to_rinterface(cdata)
~/anaconda3/envs/catenv/lib/python3.7/site-packages/rpy2/rinterface_lib/sexp.py in from_iterable(cls, iterable, populate_func)
317 if populate_func is None:
318 cls._populate_r_vector(iterable,
--> 319 r_vector)
320 else:
321 populate_func(iterable, r_vector)
~/anaconda3/envs/catenv/lib/python3.7/site-packages/rpy2/rinterface_lib/sexp.py in _populate_r_vector(cls, iterable, r_vector)
300 r_vector,
301 cls._R_SET_VECTOR_ELT,
--> 302 cls._CAST_IN)
303
304 #classmethod
~/anaconda3/envs/catenv/lib/python3.7/site-packages/rpy2/rinterface_lib/sexp.py in _populate_r_vector(iterable, r_vector, set_elt, cast_value)
237 def _populate_r_vector(iterable, r_vector, set_elt, cast_value):
238 for i, v in enumerate(iterable):
--> 239 set_elt(r_vector, i, cast_value(v))
240
241
~/anaconda3/envs/catenv/lib/python3.7/site-packages/rpy2/rinterface_lib/sexp.py in _as_charsxp_cdata(x)
430 return x.__sexp__._cdata
431 else:
--> 432 return conversion._str_to_charsxp(x)
433
434
~/anaconda3/envs/catenv/lib/python3.7/site-packages/rpy2/rinterface_lib/conversion.py in _str_to_charsxp(val)
118 s = rlib.R_NaString
119 else:
--> 120 cchar = _str_to_cchar(val)
121 s = rlib.Rf_mkCharCE(cchar, _CE_UTF8)
122 return s
~/anaconda3/envs/catenv/lib/python3.7/site-packages/rpy2/rinterface_lib/conversion.py in _str_to_cchar(s, encoding)
97 def _str_to_cchar(s, encoding: str = 'utf-8'):
98 # TODO: use isStrinb and installTrChar
---> 99 b = s.encode(encoding)
100 return ffi.new('char[]', b)
101
AttributeError: 'float' object has no attribute 'encode'
So I find that it is not possible to even start an R magic cell while importing my pandas dataframe object. However, I have tried creating R vectors inside the cell, and find I can plot these using ggplot2 with no issues.
I am using Python 3.7.6, rpy2 3.1.0, jupyter-notebook 6.0.3and am using Ubuntu 18.04.2 LTS on Windows Subsystem for Linux.
The problem is most likely with one (or more) columns having more than one type - therefore it is impossible to transfer the data into an R vector (which can hold only one data type). The traceback may be overwhelming, but here is the relevant part:
ValueError: Series can only be of one type, or None.
Which column it is? Difficult to say without looking at the dataset that you load, but my general solution is to check the types in the columns:
types = data.applymap(type).apply(set)
types[types.apply(len) > 1]
Anything returned by the snippet above would be a candidate culprit. There are many different ways of dealing with the problem, depending on the exact nature of the data. Workarounds that I frequently use include:
calling data = data.infer_objects() - helps if the pandas did not catch up with a dtype change and still stores the data with (suboptimal) Python objects
filling NaN with an empty string or a string constant if you have missing values in a string column (e.g. str_columns = str_columns.fillna(''))
dates.apply(pd.to_datetime, axis=1) if you have datetime objects but the dtype is object
using df.applymap(lambda x: datetime.combine(x, datetime.min.time()) if not isinstance(x, datetime) else x) if you have a mixture of date and datetime objects
In some vary rare cases pandas stores the data differently than expected by rpy2 (following certain manipulations); then writing the dataframe down to a csv file and reading it from the disk again helps - but this is likely not what you are facing here, as you start from a newly read dataframe.
I just noticed there might be an even simpler reason for the problem. For some reason, pandas2ri requires you to call pandas2ri.activate()after importing it. This solved the problem for me.

How to fix "AttributeError: 'str' object has no attribute 'setdefault' " in python folium geoJSON code?

How do I get folium to accept geoJSON input which seems to be causing this error?
Trying to do a choropleth map and got the same error so tried to just do a geoJSON overlay on a basic folium map with JSON file I created by taking a subset of a larger geoJSON file. Working in Juypter Notebook. JSON file appears to have correct structure.
msp_map = folium.Map(location=[latitude, longitude], zoom_start=10)
folium.GeoJson(
msp_zipcode_geo,
name='geojson'
).add_to(msp_map)
msp_map
AttributeError Traceback (most recent call last)
~/conda/lib/python3.6/site-packages/IPython/core/formatters.py in call(self, obj)
343 method = get_real_method(obj, self.print_method)
344 if method is not None:
--> 345 return method()
346 return None
347 else:
~/conda/lib/python3.6/site-packages/folium/map.py in _repr_html_(self, **kwargs)
249 self._parent = None
250 else:
--> 251 out = self._parent._repr_html_(**kwargs)
252 return out
253
~/conda/lib/python3.6/site-packages/branca/element.py in _repr_html_(self, **kwargs)
326
327 """
--> 328 html = self.render(**kwargs)
329 html = "data:text/html;charset=utf-8;base64," + base64.b64encode(html.encode('utf8')).decode('utf8') # noqa
330
~/conda/lib/python3.6/site-packages/branca/element.py in render(self, **kwargs)
319 """Renders the HTML representation of the element."""
320 for name, child in self._children.items():
--> 321 child.render(**kwargs)
322 return self._template.render(this=self, kwargs=kwargs)
323
~/conda/lib/python3.6/site-packages/folium/map.py in render(self, **kwargs)
336 ''), name='map_style')
337
--> 338 super(LegacyMap, self).render(**kwargs)
339
340
~/conda/lib/python3.6/site-packages/branca/element.py in render(self, **kwargs)
631
632 for name, element in self._children.items():
--> 633 element.render(**kwargs)
~/conda/lib/python3.6/site-packages/branca/element.py in render(self, **kwargs)
627 script = self._template.module.dict.get('script', None)
628 if script is not None:
--> 629 figure.script.add_child(Element(script(self, kwargs)),
630 name=self.get_name())
631
~/conda/lib/python3.6/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):
~/conda/lib/python3.6/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)
~/conda/lib/python3.6/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)
in macro(l_1_this, l_1_kwargs)
~/conda/lib/python3.6/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 '
~/conda/lib/python3.6/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)
AttributeError: 'str' object has no attribute 'setdefault'
Expecting to get map with overlay of county borders as specified in geoJSON file.
Figured out there was a data type mismatch in the key_on column of data where in the geoJSON file it was string type and in the data set file it was int64. Converting data set file was easier and produced choropleth with the right color range for each polygon in the geoJSON set.
Also figured out that geoJSON file I'd created as a subset of larger geoJSON file was different in that I'd stored some data as dict when it should have been list.

Categories

Resources