Get results with undirected graph but not with multidigraph - python

Dear people of stackoverflow,
I made a routeplanner based on length and elevation. With both costfactors I get only results with an undirected graph. So the code is good for an undirect graph but doesn't work with a MultiDiGraph as input, which I want because it is necessary with elevation.
The errors I get:
number 1:
~\anaconda3\envs\environmentwithhighestversion\lib\site-
packages\osmnx\plot.py in
plot_graph_route(G, route, route_color, route_linewidth, route_alpha,
orig_dest_size, ax,
**pg_kwargs)
292
293 # scatterplot origin and destination points (first/last nodes in
route)
--> 294 x = (G.nodes[route[0]]["x"], G.nodes[route[-1]]["x"])
295 y = (G.nodes[route[0]]["y"], G.nodes[route[-1]]["y"])
296 ax.scatter(x, y, s=orig_dest_size, c=route_color,
alpha=route_alpha, edgecolor="none")
TypeError: 'NoneType' object is not subscriptable
Number 2:
~\anaconda3\envs\environmentwithhighestversion\lib\site-
packages\osmnx\utils_graph.py in get_route_edge_attributes(G, route,
attribute, minimize_key, retrieve_default)
263 """
264 attribute_values = []
--> 265 for u, v in zip(route[:-1], route[1:]):
266 # if there are parallel edges between two nodes, select the
one with the
267 # lowest value of minimize_key
TypeError: 'NoneType' object is not subscriptable
The code is partly altered, the original code is of G. Boeing (2021):
https://github.com/gboeing/osmnx-examples/blob/main/notebooks/12-node-elevations-edge-grades.ipynb
Here is also a reproducible example possible.
The code for the first error:
TypeError Traceback (most recent call
last)
<ipython-input-3-86e03594e5bd> in <module>
7 route_by_impedance = ox.shortest_path(G7, source, target,
weight="impedance")
8 print('Route Impedance:')
----> 9 fig, ax = ox.plot_graph_route(G7, route_by_impedance,
node_size=3)
10 def print_route_stats(route):
11 route_grades = ox.utils_graph.get_route_edge_attributes(G7,
route, "grade_abs")
The code for the second error:
ipython-input-4-4eb87f73e021> in print_route_stats(route)
9 #fig, ax = ox.plot_graph_route(G7, route_by_impedance, node_size=3)
10 def print_route_stats(route):
---> 11 route_grades = ox.utils_graph.get_route_edge_attributes(G7,
route, "grade_abs")
12 msg = "The average grade is {:.1f}% and the max is {:.1f}%"
13 print(msg.format(np.mean(route_grades) * 100,
np.max(route_grades) * 100))
Does anybody know why I get this problem?
Kind regards,
Damiaan

Related

Error with osmnx while creating graph from xml file

I am trying to build a graph where nodes would be the cities of the Friuli-Venezia Giulia region and the edges the roads connecting them (edge's weight being the road length).
I therefore decided to use data from openstreetmaps, I found a way to download an extract containing all I need (https://download.openstreetmap.fr/extracts/europe/italy/). Then I filtered the data using osmfilter to retain only what I needed
osmfilter file.osm --keep-nodes="place=* and population>1000 " --keep-ways="highway=primary =secondary =tertiary" --drop-relations --keep= -o=new.osm
So far everything went well (I guess). It is when I am trying to use osmnx to create the graph that an error occurs
import osmnx as ox
G = ox.graph.graph_from_xml('new.osm', simplify=True)
The error is the following
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
AttributeError: 'float' object has no attribute 'deg2rad'
The above exception was the direct cause of the following exception:
TypeError Traceback (most recent call last)
<ipython-input-2-75f455d1bcf4> in <module>
----> 1 G = ox.graph.graph_from_xml('new.osm', simplify=True)
~/.local/lib/python3.8/site-packages/osmnx/graph.py in graph_from_xml(filepath, bidirectional, simplify, retain_all)
516
517 # create graph using this response JSON
--> 518 G = _create_graph(response_jsons, bidirectional=bidirectional, retain_all=retain_all)
519
520 # simplify the graph topology as the last step
~/.local/lib/python3.8/site-packages/osmnx/graph.py in _create_graph(response_jsons, retain_all, bidirectional)
585 # add length (great-circle distance between nodes) attribute to each edge
586 if len(G.edges) > 0:
--> 587 G = distance.add_edge_lengths(G)
588
589 return G
~/.local/lib/python3.8/site-packages/osmnx/distance.py in add_edge_lengths(G, precision, edges)
152
153 # calculate great circle distances, round, and fill nulls with zeros
--> 154 dists = great_circle_vec(c[:, 0], c[:, 1], c[:, 2], c[:, 3]).round(precision)
155 dists[np.isnan(dists)] = 0
156 nx.set_edge_attributes(G, values=dict(zip(uvk, dists)), name="length")
~/.local/lib/python3.8/site-packages/osmnx/distance.py in great_circle_vec(lat1, lng1, lat2, lng2, earth_radius)
58 earth_radius
59 """
---> 60 y1 = np.deg2rad(lat1)
61 y2 = np.deg2rad(lat2)
62 dy = y2 - y1
TypeError: loop of ufunc does not support argument 0 of type float which has no callable deg2rad method
Any idea of what is wrong? I would also be glad if anyone knows a better way to create such graph.
Thank you very much

linestrings: Input operand 0 does not have enough dimensions (has 1, gufunc core with signature (i, d)->() requires 2)

I am following the sample source code on this link: Simplified detection of urban types
. And after updating GeoPandas (0.11.0) and GDAL (3.5.0) packages, I started getting this error:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Input In [4], in <cell line: 1>()
----> 1 profile = momepy.StreetProfile(streets, buildings)
File ~/opt/anaconda3/envs/PythonEnv/lib/python3.9/site-packages/momepy/dimension.py:590, in StreetProfile.__init__(self, left, right, heights, distance, tick_length, verbose)
587 ticks.append([line_end_1, pt])
588 ticks.append([line_end_2, pt])
--> 590 ticks = pygeos.linestrings(ticks)
592 inp, res = right.sindex.query_bulk(ticks, predicate="intersects")
593 intersections = pygeos.intersection(ticks[inp], right.geometry.values.data[res])
File ~/opt/anaconda3/envs/PythonEnv/lib/python3.9/site-packages/pygeos/decorators.py:80, in multithreading_enabled.<locals>.wrapped(*args, **kwargs)
78 for arr in array_args:
79 arr.flags.writeable = False
---> 80 return func(*args, **kwargs)
81 finally:
82 for arr, old_flag in zip(array_args, old_flags):
File ~/opt/anaconda3/envs/PythonEnv/lib/python3.9/site-packages/pygeos/creation.py:119, in linestrings(coords, y, z, indices, out, **kwargs)
117 coords = _xyz_to_coords(coords, y, z)
118 if indices is None:
--> 119 return lib.linestrings(coords, out=out, **kwargs)
120 else:
121 return simple_geometries_1d(coords, indices, GeometryType.LINESTRING, out=out)
ValueError: linestrings: Input operand 0 does not have enough dimensions (has 1, gufunc core with signature (i, d)->() requires 2)
the minimum source code that can regenerate the error:
import geopandas
import libpysal
import momepy
import osmnx
import pandas
place = 'Znojmo, Czechia'
buildings = osmnx.geometries.geometries_from_place(place, tags={'building':True})
osm_graph = osmnx.graph_from_place(place, network_type='drive')
#osm_graph = osmnx.projection.project_graph(osm_graph, to_crs=local_crs)
streets = osmnx.graph_to_gdfs(
osm_graph,
nodes=False,
edges=True,
node_geometry=False,
fill_edge_geometry=True
)
profile = momepy.StreetProfile(streets, buildings)
Does anyone aware of changes in the new packages that would result in this error?

'Polygon' object is not iterable- iPython Cookbook

I am learning visualization of data in python using Cartopy
I have this code for plotting Africa's population and GDP.
def choropleth(ax, attr, cmap_name):
# We need to normalize the values before we can
# use the colormap.
values = [c.attributes[attr] for c in africa]
norm = Normalize(
vmin=min(values), vmax=max(values))
cmap = plt.cm.get_cmap(cmap_name)
for c in africa:
v = c.attributes[attr]
sp = ShapelyFeature(c.geometry, crs,
edgecolor='k',
facecolor=cmap(norm(v)))
ax.add_feature(sp)
fig, (ax1, ax2) = plt.subplots(
1, 2, figsize=(10, 16),
subplot_kw=dict(projection=crs))
draw_africa(ax1)
choropleth(ax1, 'POP_EST', 'Reds')
ax1.set_title('Population')
draw_africa(ax2)
choropleth(ax2, 'GDP_MD_EST', 'Blues')
ax2.set_title('GDP')
And the expected output should be-
But I am getting an error as such -
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-41-b443c58ecbd5> in <module>
3 subplot_kw=dict(projection=crs))
4 draw_africa(ax1)
----> 5 choropleth(ax1, 'POP_EST', 'Reds')
6 ax1.set_title('Population')
7
<ipython-input-40-161126226479> in choropleth(ax, attr, cmap_name)
8 for c in africa:
9 v = c.attributes[attr]
---> 10 sp = ShapelyFeature(c.geometry, crs,
11 edgecolor='k',
12 facecolor=cmap(norm(v)))
~/anaconda3/lib/python3.8/site-packages/cartopy/feature/__init__.py in __init__(self, geometries, crs, **kwargs)
219 """
220 super(ShapelyFeature, self).__init__(crs, **kwargs)
--> 221 self._geoms = tuple(geometries)
222
223 def geometries(self):
TypeError: 'Polygon' object is not iterable
I tried searching for this issue on github but no to avail. Can anyone please help me out how can I correct this ?
Here is the site for reference .
The issue is that the code tries to pass a shapely Polygon to a function that expects MultiPolygon. The elegant solution by swatchai here https://stackoverflow.com/a/63812490/13208790 is to catch Polygons and put them in a list so they can be treated as MultiPolygons.
Here's the code adapted to your case:
for i, c in enumerate(africa):
v = c.attributes[attr]
print(i)
# swatchai's Polygon catch logic
if c.geometry.geom_type=='MultiPolygon':
# this is a list of geometries
sp = ShapelyFeature(c.geometry, crs,
edgecolor='k',
facecolor=cmap(norm(v)))
elif c.geometry.geom_type=='Polygon':
# this is a single geometry
sp = ShapelyFeature([c.geometry], crs,
edgecolor='k',
facecolor=cmap(norm(v)))
else:
pass #do not plot the geometry

Can not draw more than 8 nodes by networkx raising `NetworkXError: Node 8 has no position` error

I'm trying to draw graph by networkx. However, the below code suffers the error that is
NetworkXError: Node 8 has no position
I believe only less than seven nodes are allowed, but I can not understand why.
Please suggest why the error happens and how to fix to draw more than 8 nodes.
import networkx as nx
# new_words = ["1","2","3","4","5","6","7"] => It does not occur the error
new_words = ["1","2","3","4","5","6","7","8"]
target_word = ["0"]
G=nx.cubical_graph()
pos=nx.spring_layout(G)
nx.draw_networkx_nodes(G,pos,
nodelist=[0],
node_color='r',
node_size=50, alpha=0.8)
nx.draw_networkx_nodes(G,pos,
nodelist=range(1, len(new_words)+1),
node_color='w',
node_size=50, alpha=0.8)
nx.draw_networkx_edges(G,pos,
edgelist=[(0,i) for i in range(1,len(new_words)+1)])
# some math labels
labels={}
labels[0]=target_word
for idx in range(0,len(new_words)):
labels[idx+1] = new_words[idx]
nx.draw_networkx_labels(G,pos,labels)
The error message is:
---------------------------------------------------------------------------
NetworkXError Traceback (most recent call last)
<ipython-input-16-5ddab3dbe0d6> in <module>()
15 nodelist=range(1, len(new_words)+1),
16 node_color='w',
---> 17 node_size=50, alpha=0.8)
18
19 nx.draw_networkx_edges(G,pos,
/Users/sudou/.pyenv/versions/anaconda-2.0.1/lib/python2.7/site-packages/networkx/drawing/nx_pylab.pyc in draw_networkx_nodes(G, pos, nodelist, node_size, node_color, node_shape, alpha, cmap, vmin, vmax, ax, linewidths, label, **kwds)
384 xy = numpy.asarray([pos[v] for v in nodelist])
385 except KeyError as e:
--> 386 raise nx.NetworkXError('Node %s has no position.'%e)
387 except ValueError:
388 raise nx.NetworkXError('Bad value in node positions.')
NetworkXError: Node 8 has no position.
nx.cubical_graph() has 8 nodes. Namely [0,1,2,3,4,5,6,7]. You have sent a nodelist that includes node 8 which is not part of your graph. The graph you are drawing is the graph of a cube - 8 nodes (the vertices) and 12 edges (the edges of the cube).
You're asking it to plot 9 nodes of an 8 node graph. Thus it cannot find where that node goes.
Responding to your question on how to plot more than 8 nodes in a graph, you have to start with a graph with more than 8 nodes.

plotting rolling_mean (pandas) not working

I know there's a bunch of questions on here regarding the use of the rolling_mean function in pandas - but I can't get it to work.
I'm new to Python, and the packages numpy,pandas etc.
I have a list of DateTime objects and I have a list of simple integers. Plotting them works without a problem. But I can't plot a moving average line to the graph!
I'm trying to use the Pandas docs to understand it but I still can't get it to work. This is what I have tried:
# code before this simply reads a file and converts dates into datetime objects and values into a list
x1 = date_object #list of datetime objects
y1 = values1 #list of integer values
plot(x1,y1) # works fine
t = pd.date_range(date_object[0].strftime('%m/%d/%Y'), date_object[len(date_object)-1].strftime('%m/%d/%Y'), freq='W')
ts = pd.Series(y1, t)
ts_movavg = pd.rolling_mean(ts,10)
plot(ts_movavg)
..I get the following error:
ValueError: setting an array element with a sequence.
As you can probably quickly tell, I'm very confused. I think I'm missing the point of the Series object.
EDIT: (full traceback)
ValueError Traceback (most recent call last)
<ipython-input-228-2247062d3126> in <module>()
33 ts = pd.Series(y1, x1)
34
---> 35 ts_movavg = PD.rolling_mean(ts,10)
36
37 ts_movavg.head()
C:\Users\****\Anaconda\lib\site-packages\pandas\stats\moments.py in f(arg, window, min_periods, freq, center, time_rule, **kwargs)
507 return _rolling_moment(arg, window, call_cython, min_periods,
508 freq=freq, center=center,
--> 509 time_rule=time_rule, **kwargs)
510
511 return f
C:\Users\****\Anaconda\lib\site-packages\pandas\stats\moments.py in _rolling_moment(arg, window, func, minp, axis, freq, center, time_rule, **kwargs)
278 arg = _conv_timerule(arg, freq, time_rule)
279 calc = lambda x: func(x, window, minp=minp, **kwargs)
--> 280 return_hook, values = _process_data_structure(arg)
281 # actually calculate the moment. Faster way to do this?
282 if values.ndim > 1:
C:\Users\****\Anaconda\lib\site-packages\pandas\stats\moments.py in _process_data_structure(arg, kill_inf)
326
327 if not issubclass(values.dtype.type, float):
--> 328 values = values.astype(float)
329
330 if kill_inf:
ValueError: setting an array element with a sequence.
Could someone show me how to plot a moving average line using the rolling_mean function?

Categories