Osmnx-examples - Usage examples, demos, and tutorials for OSMnx.

Overview

Binder Build Status

OSMnx Examples

OSMnx is a Python package to work with street networks and other spatial data from OpenStreetMap: retrieve, model, analyze, and visualize street networks as well as other infrastructure types, points of interest, building footprints, speed/travel time, elevation, and more.

This repo contains usage examples and feature demonstrations. You can run these OSMnx example notebooks interactively online with Binder or locally with the official OSMnx docker image. All of the examples are in this repo's notebooks folder. Note that this repo's main branch generally tracks the functionality of the OSMnx repo's main branch. For examples corresponding to previous versions, use this repo's tags to browse by release.

More info:

Comments
  • Different lengths of basic and extended stats dictionary columns

    Different lengths of basic and extended stats dictionary columns

    Possibility of Error or Misunderstanding of how "Calculate basic street network measures (topological and metric)" works

    image

    This is from notebook "06-example-osmnx-networkx.ipynb

    "Use OSMnx to analyze a NetworkX street network, including routing""

    In the example, the length of the dataframe is 30 columns.

    1. Is that the standard?
    2. Should other places, if they exist as a polygon, be consistent in polygon length, if I am using the same arguments?

    I have ran multiple tests on different cities, and I either get 26 or 28 columns, respectively.

    The only two arguments that I called are G and area from these basic stats docs

    I am trying to see where the error is because if I have the same argument for every place and I know the shapes exist, why would they have different column lengths?

      `stats = ox.basic_stats(G, area=area)
        for k, count in stats['streets_per_node_counts'].items():
            stats['int_{}_count'.format(k)] = count
        for k, proportion in stats['streets_per_node_proportion'].items():
            stats['int_{}_prop'.format(k)] = proportion`
    

    The only solution I can think of why I may have different columns is how I am writing it to a csv,

            que = pd.DataFrame(pd.Series(stats)).T
            with open(file_name +'.csv', 'w') as f:
                que.to_csv(f, header=False,index=False,encoding='utf-8')
    

    Full code for clarity

    for value in df.Name:
            place = value
            gdf = ox.gdf_from_place(place)
            area = ox.project_gdf(gdf).unary_union.area
            G = ox.graph_from_place(place, network_type='drive_service')
            stats = ox.basic_stats(G, area=area)
            for k, count in stats['streets_per_node_counts'].items():
                stats['int_{}_count'.format(k)] = count
            for k, proportion in stats['streets_per_node_proportion'].items():
                stats['int_{}_prop'.format(k)] = proportion
            # delete the no longer needed dict elements
            del stats['streets_per_node_counts']
            del stats['streets_per_node_proportion']
            file_name = str(counter)
            que = pd.DataFrame(pd.Series(stats)).T
            with open(file_name + '.csv', 'w') as f:
                que.to_csv(f, header=False,index=False,encoding='utf-8')
            del stats
            del place
            del area
            del gdf
           time.sleep(1000)
    
    opened by RockyCD 8
  • NetworkXNotImplemented in 08-example-line-graph

    NetworkXNotImplemented in 08-example-line-graph

    opened by philippks 6
  • Optional method of better rendering ischrones for accessibility using nodes + edges

    Optional method of better rendering ischrones for accessibility using nodes + edges

    Regarding this example: https://github.com/gboeing/osmnx-examples/blob/master/notebooks/13-isolines-isochrones.ipynb

    I propose a new method, make_iso_polys, outlined below. This, rather than a convex hull, might best demonstrate coverage area while preserved nuances ("inlets" or areas of inaccessibility not captured when creating a convex hull around a point cloud).

    Example of what improved plot looks like: image

    Ful function defintion.

    def make_iso_polys(G, edge_buff=25, node_buff=50):
        isochrone_polys = []
        for trip_time in sorted(trip_times, reverse=True):
            subgraph = nx.ego_graph(G, center_node, radius=trip_time, distance='time')
    
            node_points = [Point((data['x'], data['y'])) for node, data in subgraph.nodes(data=True)]
            nodes_gdf = gpd.GeoDataFrame({'id': subgraph.nodes()}, geometry=node_points)
            nodes_gdf = nodes_gdf.set_index('id')
    
            edge_lines = []
            for n_fr, n_to in subgraph.edges():
                f = nodes_gdf.loc[n_fr].geometry
                t = nodes_gdf.loc[n_to].geometry
                edge_lines.append(LineString([f,t]))
    
            n = nodes_gdf.buffer(node_buff).geometry
            e = gpd.GeoSeries(edge_lines).buffer(edge_buff).geometry
            all_gs = list(n) + list(e)
            new_iso = gpd.GeoSeries(all_gs).unary_union
            isochrone_polys.append(new_iso)
        return isochrone_polys
    

    Further elaboration available here: http://kuanbutts.com/2017/12/16/osmnx-isochrones/

    opened by kuanb 6
  • TypeError: unhashable type: 'dict' on first example in 00-osmnx-features-demo.ipynb

    TypeError: unhashable type: 'dict' on first example in 00-osmnx-features-demo.ipynb

    get a graph for some city

    G = ox.graph_from_place('Piedmont, California, USA', network_type='drive') fig, ax = ox.plot_graph(G)

    Installed per instructions on Mac OS. Terminal output and error output follow.

    Any direction would be appreciated. Thanks, Jay

    Output from terminal looks good except the last line (notebook not trusted): Posting to http://overpass-api.de/api/interpreter with timeout=180, "{'data': '[out:json][timeout:180];(way["highway"]["area"!~"yes"]["highway"!~"cycleway|footway|path|pedestrian|steps|track|corridor|elevator|escalator|proposed|construction|bridleway|abandoned|platform|raceway|service"]["motor_vehicle"!~"no"]["motorcar"!~"no"]["access"!~"private"]["service"!~"parking|parking_aisle|driveway|private|emergency_access"](poly:"37.823113 -122.255010 37.823199 -122.255027 37.823651 -122.255055 37.824104 -122.255026 37.824552 -122.254940 37.824991 -122.254797 37.825417 -122.254600 37.825824 -122.254350 37.826210 -122.254049 37.826569 -122.253701 37.826799 -122.253455 37.826915 -122.253330 37.827176 -122.253244 37.827377 -122.253178 37.827800 -122.253010 37.828208 -122.252791 37.828597 -122.252523 37.828964 -122.252207 37.829303 -122.251848 37.829613 -122.251448 37.829891 -122.251012 37.830143 -122.250573 37.830803 -122.249429 37.830839 -122.249407 37.831197 -122.249128 37.831286 -122.249052 37.832123 -122.248407 37.832393 -122.248200 37.832408 -122.248188 37.832448 -122.248157 37.832806 -122.247849 37.833139 -122.247498 37.833444 -122.247109 37.833717 -122.246685 37.833957 -122.246229 37.834162 -122.245747 37.834328 -122.245241 37.834455 -122.244718 37.834542 -122.244183 37.834587 -122.243639 37.834589 -122.243372 37.834678 -122.243039 37.834731 -122.242827 37.834764 -122.242685 37.834890 -122.241972 37.834909 -122.241820 37.834955 -122.241306 37.834963 -122.241152 37.834972 -122.240864 37.834984 -122.239854 37.834988 -122.239743 37.835013 -122.239561 37.835040 -122.239289 37.835061 -122.239227 37.835189 -122.238722 37.835278 -122.238205 37.835314 -122.237839 37.835348 -122.237717 37.835448 -122.237227 37.835481 -122.237028 37.835520 -122.236796 37.835555 -122.236603 37.835691 -122.235869 37.835737 -122.235620 37.835738 -122.235611 37.835971 -122.234342 37.836041 -122.233967 37.836454 -122.232630 37.836562 -122.232282 37.836840 -122.231384 37.837223 -122.230148 37.837363 -122.229621 37.837462 -122.229079 37.837518 -122.228527 37.837531 -122.227970 37.837501 -122.227415 37.837429 -122.226866 37.837313 -122.226329 37.837157 -122.225809 37.836961 -122.225310 37.836727 -122.224838 37.836458 -122.224397 37.836321 -122.224194 37.835909 -122.223581 37.835902 -122.223571 37.835860 -122.223509 37.835655 -122.223085 37.835595 -122.222985 37.835586 -122.222968 37.835578 -122.222952 37.835434 -122.222684 37.835429 -122.222676 37.835381 -122.222587 37.835374 -122.222573 37.835322 -122.222478 37.835298 -122.222434 37.835063 -122.221995 37.835055 -122.221980 37.834974 -122.221830 37.834716 -122.221399 37.834427 -122.221000 37.834110 -122.220638 37.833766 -122.220315 37.833400 -122.220035 37.833015 -122.219801 37.832810 -122.219691 37.832272 -122.219402 37.831977 -122.219183 37.831614 -122.218915 37.830654 -122.218095 37.830647 -122.218088 37.830591 -122.218041 37.830515 -122.217976 37.830496 -122.217959 37.830412 -122.217887 37.830144 -122.217659 37.829807 -122.217396 37.829733 -122.217344 37.829631 -122.217281 37.829503 -122.217182 37.829430 -122.217131 37.828987 -122.216860 37.828701 -122.216709 37.828662 -122.216688 37.828379 -122.216543 37.827516 -122.215453 37.827432 -122.215347 37.827198 -122.215051 37.827190 -122.215041 37.827029 -122.214674 37.826870 -122.214305 37.826798 -122.214155 37.826740 -122.214040 37.826711 -122.213957 37.826644 -122.213786 37.826416 -122.213272 37.826146 -122.212791 37.825839 -122.212347 37.825749 -122.212230 37.825389 -122.211810 37.825007 -122.211454 37.825005 -122.211449 37.824892 -122.211240 37.824758 -122.211006 37.824502 -122.210581 37.823733 -122.209301 37.823648 -122.209175 37.823573 -122.209040 37.823492 -122.208894 37.823215 -122.208389 37.823146 -122.208264 37.823031 -122.208047 37.822619 -122.207266 37.822482 -122.207006 37.822225 -122.206566 37.821937 -122.206159 37.821618 -122.205789 37.821273 -122.205460 37.820904 -122.205174 37.820515 -122.204933 37.820110 -122.204741 37.819692 -122.204599 37.819265 -122.204508 37.818833 -122.204469 37.818400 -122.204482 37.817970 -122.204548 37.817547 -122.204666 37.817135 -122.204834 37.816738 -122.205051 37.816359 -122.205316 37.816002 -122.205625 37.815670 -122.205975 37.815367 -122.206365 37.814959 -122.206941 37.814930 -122.206982 37.814675 -122.207349 37.814481 -122.207381 37.814339 -122.207410 37.814177 -122.207447 37.814030 -122.207484 37.813634 -122.207607 37.813500 -122.207657 37.812918 -122.207931 37.812911 -122.207935 37.812827 -122.207984 37.812691 -122.208066 37.812132 -122.208467 37.811978 -122.208597 37.811966 -122.208603 37.811575 -122.208821 37.811483 -122.208879 37.811239 -122.209045 37.811213 -122.209064 37.811191 -122.209080 37.811159 -122.209104 37.811136 -122.209120 37.810777 -122.209410 37.810730 -122.209452 37.810345 -122.209837 37.810210 -122.209988 37.810035 -122.210195 37.809941 -122.210312 37.809922 -122.210337 37.809674 -122.210537 37.809327 -122.210879 37.809009 -122.211262 37.808722 -122.211682 37.808469 -122.212135 37.808252 -122.212618 37.808073 -122.213125 37.807935 -122.213651 37.807838 -122.214192 37.807783 -122.214742 37.807771 -122.215296 37.807802 -122.215849 37.807875 -122.216396 37.807991 -122.216931 37.808147 -122.217449 37.808240 -122.217718 37.808412 -122.218216 37.808499 -122.218428 37.808535 -122.218647 37.808536 -122.218646 37.808586 -122.218943 37.808619 -122.219109 37.808647 -122.219244 37.808740 -122.219662 37.808776 -122.219850 37.809087 -122.221225 37.809106 -122.221298 37.809181 -122.221649 37.809265 -122.221991 37.809318 -122.222187 37.809322 -122.222205 37.809389 -122.222450 37.809446 -122.222678 37.809566 -122.223440 37.809569 -122.223463 37.809617 -122.223762 37.809705 -122.224211 37.809768 -122.224486 37.809957 -122.225311 37.809961 -122.225329 37.810025 -122.225605 37.810110 -122.225936 37.810180 -122.226181 37.810184 -122.226195 37.810396 -122.226930 37.810412 -122.226982 37.810520 -122.227465 37.810522 -122.227472 37.810980 -122.229494 37.811104 -122.230040 37.811143 -122.230250 37.811185 -122.230460 37.811258 -122.230791 37.811688 -122.232912 37.811690 -122.232921 37.811838 -122.233645 37.812030 -122.234375 37.812098 -122.234585 37.812105 -122.234606 37.812310 -122.235233 37.812335 -122.235308 37.812365 -122.235416 37.812513 -122.235963 37.812569 -122.236157 37.812624 -122.236335 37.812672 -122.236504 37.812695 -122.236590 37.812699 -122.236606 37.812766 -122.236853 37.812871 -122.237407 37.812918 -122.237961 37.812919 -122.237980 37.812939 -122.238210 37.813006 -122.238743 37.813113 -122.239267 37.813198 -122.239611 37.813451 -122.240643 37.813454 -122.240655 37.813499 -122.240838 37.813517 -122.240934 37.813670 -122.241713 37.813721 -122.241973 37.813767 -122.242187 37.813858 -122.242584 37.814131 -122.243775 37.814134 -122.243787 37.814226 -122.244185 37.814278 -122.244395 37.814318 -122.244546 37.814438 -122.244999 37.814453 -122.245050 37.814580 -122.245495 37.814634 -122.245662 37.814641 -122.245685 37.814797 -122.246160 37.814803 -122.246192 37.814849 -122.246421 37.814970 -122.246925 37.815128 -122.247413 37.815321 -122.247881 37.815547 -122.248324 37.815805 -122.248739 37.816092 -122.249121 37.816171 -122.249217 37.816316 -122.249386 37.816481 -122.249570 37.816608 -122.249705 37.816727 -122.249828 37.816858 -122.249983 37.816976 -122.250117 37.817113 -122.250268 37.817343 -122.250506 37.817479 -122.250637 37.818026 -122.251088 37.818110 -122.251147 37.818393 -122.251471 37.818403 -122.251482 37.818668 -122.251851 37.819597 -122.253146 37.819902 -122.253532 37.820234 -122.253880 37.820592 -122.254186 37.820972 -122.254447 37.821369 -122.254661 37.821781 -122.254826 37.822203 -122.254941 37.822633 -122.255004 37.823065 -122.255015 37.823113 -122.255010");>;);out;'}" Downloaded 792.5KB from overpass-api.de in 8.82 seconds Saved response to cache file "cache/2e68726eb0121fe5f6f00f39771d3830.json" Got all network data within polygon from API in 1 request(s) and 9.30 seconds Creating networkx graph from downloaded OSM data... Created graph with 5,578 nodes and 10,929 edges in 0.15 seconds Added edge lengths to graph in 0.09 seconds Identifying all nodes that lie outside the polygon... Created r-tree spatial index for 5,578 points in 0.21 seconds [I 05:13:43.513 NotebookApp] Saving file at /osmnx-examples/notebooks/00-osmnx-features-demo.ipynb [W 05:13:43.514 NotebookApp] Notebook osmnx-examples/notebooks/00-osmnx-features-demo.ipynb is not trusted

    Error output:


    TypeError Traceback (most recent call last) in 1 # get a graph for some city ----> 2 G = ox.graph_from_place('Piedmont, California, USA', network_type='drive') 3 fig, ax = ox.plot_graph(G)

    ~/anaconda3/envs/ox/lib/python3.8/site-packages/osmnx/core.py in graph_from_place(query, network_type, simplify, retain_all, truncate_by_edge, name, which_result, buffer_dist, timeout, memory, max_query_area_size, clean_periphery, infrastructure, custom_filter) 1443 1444 # create graph using this polygon(s) geometry -> 1445 G = graph_from_polygon(polygon, network_type=network_type, simplify=simplify, 1446 retain_all=retain_all, truncate_by_edge=truncate_by_edge, 1447 name=name, timeout=timeout, memory=memory,

    ~/anaconda3/envs/ox/lib/python3.8/site-packages/osmnx/core.py in graph_from_polygon(polygon, network_type, simplify, retain_all, truncate_by_edge, name, timeout, memory, max_query_area_size, clean_periphery, infrastructure, custom_filter) 1324 G_buffered = create_graph(response_jsons, name=name, retain_all=True, 1325 bidirectional=network_type in settings.bidirectional_network_types) -> 1326 G_buffered = truncate_graph_polygon(G_buffered, polygon_buffered, retain_all=True, truncate_by_edge=truncate_by_edge) 1327 1328 # simplify the graph topology

    ~/anaconda3/envs/ox/lib/python3.8/site-packages/osmnx/core.py in truncate_graph_polygon(G, polygon, retain_all, truncate_by_edge, quadrat_width, min_num, buffer_amount) 731 732 # find all the nodes in the graph that lie outside the polygon --> 733 points_within_geometry = intersect_index_quadrats(gdf_nodes, polygon, quadrat_width=quadrat_width, min_num=min_num, buffer_amount=buffer_amount) 734 nodes_outside_polygon = gdf_nodes[~gdf_nodes.index.isin(points_within_geometry.index)] 735

    ~/anaconda3/envs/ox/lib/python3.8/site-packages/osmnx/core.py in intersect_index_quadrats(gdf, geometry, quadrat_width, min_num, buffer_amount) 678 # drop duplicate points, if buffered poly caused an overlap on point(s) 679 # that lay directly on a quadrat line --> 680 points_within_geometry = points_within_geometry.drop_duplicates(subset='node') 681 else: 682 # after simplifying the graph, and given the requested network type,

    ~/anaconda3/envs/ox/lib/python3.8/site-packages/pandas/core/frame.py in drop_duplicates(self, subset, keep, inplace, ignore_index) 4806 4807 inplace = validate_bool_kwarg(inplace, "inplace") -> 4808 duplicated = self.duplicated(subset, keep=keep) 4809 4810 if inplace:

    ~/anaconda3/envs/ox/lib/python3.8/site-packages/pandas/core/frame.py in duplicated(self, subset, keep) 4883 4884 vals = (col.values for name, col in self.items() if name in subset) -> 4885 labels, shape = map(list, zip(*map(f, vals))) 4886 4887 ids = get_group_index(labels, shape, sort=False, xnull=False)

    ~/anaconda3/envs/ox/lib/python3.8/site-packages/pandas/core/frame.py in f(vals) 4857 4858 def f(vals): -> 4859 labels, shape = algorithms.factorize( 4860 vals, size_hint=min(len(self), _SIZE_HINT_LIMIT) 4861 )

    ~/anaconda3/envs/ox/lib/python3.8/site-packages/pandas/core/algorithms.py in factorize(values, sort, na_sentinel, size_hint) 627 na_value = None 628 --> 629 codes, uniques = _factorize_array( 630 values, na_sentinel=na_sentinel, size_hint=size_hint, na_value=na_value 631 )

    ~/anaconda3/envs/ox/lib/python3.8/site-packages/pandas/core/algorithms.py in _factorize_array(values, na_sentinel, size_hint, na_value) 476 477 table = hash_klass(size_hint or len(values)) --> 478 uniques, codes = table.factorize(values, na_sentinel=na_sentinel, na_value=na_value) 479 480 codes = ensure_platform_int(codes)

    pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable.factorize()

    pandas/_libs/hashtable_class_helper.pxi in pandas._libs.hashtable.PyObjectHashTable._unique()

    TypeError: unhashable type: 'dict'

    opened by jayurbain 5
  • Issue running 00-osmnx-features-demo

    Issue running 00-osmnx-features-demo

    I am new to this package, and network analysis on python generally. As I was replicating the commands in the first example notebook, I ran in to the following issue:

    edge_centrality = nx.closeness_centrality(nx.line_graph(G))

    NetworkXNotImplemented                    Traceback (most recent call last)
    <ipython-input-14-9e05ced82762> in <module>()
          1 # edge closeness centrality: convert graph to line graph so edges become nodes and vice versa
    ----> 2 edge_centrality = nx.closeness_centrality(nx.line_graph(G))
    
    <decorator-gen-501> in line_graph(G, create_using)
    
    /usr/local/lib/python2.7/dist-packages/networkx/utils/decorators.pyc in _not_implemented_for(not_implement_for_func, *args, **kwargs)
         69         if match:
         70             msg = 'not implemented for %s type' % ' '.join(graph_types)
    ---> 71             raise nx.NetworkXNotImplemented(msg)
         72         else:
         73             return not_implement_for_func(*args, **kwargs)
    
    NetworkXNotImplemented: not implemented for multigraph type
    

    I imagine this is something to do with the networkx package, but I was wondering if anyone else has any suggestions to overcome this problem.

    Thanks!

    opened by amedury 5
  • new example: interpolate external measurements to estimate graph's new node/edge weights

    new example: interpolate external measurements to estimate graph's new node/edge weights

    Thanks for the super awesome OSMnx package you have put together. I truly enjoyed going through your demos and examples and learned a lot. However, I miss seeing an example relevant to the following use case I am working on.

    I want to find the shortest path between two points on the map with the least X attribute (temperature, pollution etc.)! And here by X attribute I mean data points that we gather from sensors on the street. The trick is that these data points not necessarily align on the edges or nodes on the graph or we may have multiple measurements around each node or edge.

    The question is what is the best way to estimate X attribute value for the graph nodes and edges from such data? I find the 12-node-elevations-edge-grades.ipynb example the most relevant to this use case, when calculating shortest paths, considering grade impedance. But here these lines using Google elevation API:

    # add elevation to each of the nodes, using the google elevation API, then calculate edge grades
    G = ox.add_node_elevations(G, api_key=google_elevation_api_key)
    G = ox.add_edge_grades(G)
    

    does the trick neatly and one easily access the elevations at node and edge as you showed!

    I was thinking of using the average of M nearest neighbors to estimate the node X attribute, maybe also a similar approach for the edge? Edge sounds a bit trickier though. I further come across the Voronoi diagrams as an alternative options to interpolate the X attribute impedance for node and edge on the graph using the measurements. At the same time I do not want to over-complicate the solutions, as it seems there are many features within OSMnx and NetworkX that may do the trick and I am not aware of (not to mention I am new to graphs as well).

    Happy to contribute if I get to learn how if you find this a useful demo to have in this repo.

    opened by mmortazavi 3
  • PolarAxesSubplot' object has no attribute 'flat

    PolarAxesSubplot' object has no attribute 'flat

    Hello, when I am trying to run your example, I receive the following error:

    AttributeError: 'PolarAxesSubplot' object has no attribute 'flat'

    I use python 3.6 version

    Thanks in advance

    opened by rs06085 3
  • Extracting boundaries with specified administrative level is not working correctly

    Extracting boundaries with specified administrative level is not working correctly

    Hi Geoff, I have read the documentation, and searched on the internet (https://stackoverflow.com/) for solutions, but until now I didn't find any hint about how administrative boundaries are handled in osmnx. To give an example, I am trying to run this code: ''' tags = {"boundary":"administrative","admin_level":"4" } gdf =ox.geometries.geometries_from_bbox(51.5, 51.0, 11.7, 11.2, tags) gdf.shape ''' The bounding box seems to be used as a polygon to create an intersection with all the boundaries in the OSM database, the first tag is working because only administrative boundaries are returned, but the filter on level is ignored (checking with gdf["admin_level"].head() shows level 6).

    I would like to understand what I am doing wrong, and how I can use this package better; it seems like a very useful library, and could submit a working example, if I have made a mistake in my code and have a map with the correct levels. Thanks, Gijs

    opened by GvdDool 2
  • osmnx street network polar plot 1 bin backward than histogramas

    osmnx street network polar plot 1 bin backward than histogramas

    I am using osmnx version 0.14.1 . While I am making edge bearing histogram and polar plots, I see some difference as they don't seem similar. As an example in the image: As there are 30 bins in the histogram, each bin having 12 degrees, 0-12 degree have the street of (approx) 800. But in the polar rose, it shows more than 1500 in that direction. Why is that? It looks like the full polar plot is shifted 1 bin backwards. Is there any way to fix that? I am attaching the code and image below.

    yz yz1 Capture

    opened by JewelR1401104 2
  • Existing alternate isochrones example doesn't respect geometry of curved links

    Existing alternate isochrones example doesn't respect geometry of curved links

    First of all, a quick thanks for creating such a useful and easy-to-use module! I've got a slight improvement to suggest to one of the existing examples.

    The improved isochrones method added in #4 by @kuanb provides, for me, a much better way of visualising the isochrones. However, when the input links are curved this is not respected in the output buffers.

    If we alter the call to make_iso_polys in cell 13 to have edge_buff=10 and up the output fig_height, we can observe the buffer not "following" the link along the curved edges for example in the two links indicated by the arrows:

    curved link issue

    This comes about as a result of the way the buffers are defined in the function:

    edge_lines = []
    for n_fr, n_to in subgraph.edges():
        f = nodes_gdf.loc[n_fr].geometry
        t = nodes_gdf.loc[n_to].geometry
        edge_lines.append(LineString([f,t]))
    

    As the line is defined just by the start and end nodes, curvature is lost. It should be possible to instead look up the geometry of the link in the original graph, and thus keep the curvature.

    I'm not sure of the best method to do this, but a slightly messy alternative method I've created is as follows:

    edge_lines = []
    for n_fr, n_to in subgraph.edges():
        f = nodes_gdf.loc[n_fr].geometry
        t = nodes_gdf.loc[n_to].geometry
        edge_lookup = G.get_edge_data(n_fr, n_to)[0].get('geometry',  LineString([f,t]))
        edge_lines.append(edge_lookup)
    

    It seems as though the straight edges don't have a geometry key, hence the slightly awkward call to .get(). The result of this modification is that the curved edges are indeed followed:

    fixed curved edges

    I'm happy to submit a PR including this fix, but I wasn't sure if this was the best method, and I don't want to tread on anyone's toes!

    opened by asongtoruin 2
  • Use of nx.shortest_path without weight attribute

    Use of nx.shortest_path without weight attribute

    All through the examples while calculating shortest_path it looks like the code is calculating the shortest path without taking into account the actual length. nx.shortest_path(G, origin, destination) calculates the shortest path in terms of number of jumps from one node to another node in the graph, to take into account the actual distance between them it should be nx.shortest_path(G, origin, destination, weight='length') to take into account the length of all the edges. Let me know if I am missing something.

    opened by MridulS 2
  • Add Clustering Example by Network Distance

    Add Clustering Example by Network Distance

    Thanks for this comprehensive library.

    I found and old example of yours, which interesting for our organization of field work.

    https://github.com/gboeing/network-clustering/blob/main/network-clustering-simple.ipynb

    I would love to see this as part of this repo. Adapted to the newer API.

    Thanks and best wishes,

    Miili

    opened by miili 0
Owner
Geoff Boeing
Urban planning professor at USC: urban analytics, street networks, rental markets, data science.
Geoff Boeing
Beyonic API Python official client library simplified examples using Flask, Django and Fast API.

Beyonic API Python official client library simplified examples using Flask, Django and Fast API.

Harun Mbaabu Mwenda 46 Sep 1, 2022
Some examples regarding how to use the Twitter APIs for academic research

Twitter Developer Platform: Using Twitter APIs for Academic Research All the scripts require a config.ini file in which the keys are put. There is a t

Federico Bianchi 6 Feb 13, 2022
This repository contains Python code examples using the MoneyMoov API

Python Examples This repository contains Python code examples using the MoneyMoov API. The examples are written to operate in the NoFrixion sandbox en

nofrixion 1 Feb 8, 2022
Tools for use in DeFi. Impermanent Loss calculations, staking and farming strategies, coingecko and pancakeswap API queries, liquidity pools and more

DeFi open source tools Get Started Instalation General Tools Impermanent Loss, simple calculation Compare Buy & Hold with Staking and Farming Complete

Juan Pablo Pisano 467 Jan 8, 2023
A Pancakeswap and Uniswap trading client (and bot) with limit orders, marker orders, stop-loss, custom gas strategies, a GUI and much more.

Pancakeswap and Uniswap trading client Adam A A Pancakeswap and Uniswap trading client (and bot) with market orders, limit orders, stop-loss, custom g

null 570 Mar 9, 2022
Andrei 1.4k Dec 24, 2022
A Twitter Bot that retweets and likes tweets with the hashtag #girlscriptwoc and #girlscript, and also follows the user.

GirlScript Winter of Contributing Twitter Bot A Twitter Bot that retweets and likes tweets with the hashtag #girlscriptwoc and #girlscript, and also f

Pranay Gupta 9 Dec 15, 2022
StudyLion is a Discord bot that tracks members' study and work time while offering members to view their statistics and use productivity tools such as: To-do lists, Pomodoro timers, reminders, and much more.

StudyLion - Discord Productivity Bot StudyLion is a Discord bot that tracks members' study and work time while offering members the ability to view th

null 45 Dec 26, 2022
OpenSea Bulk Uploader And Trader 100000 NFTs (MAC WINDOWS ANDROID LINUX) Automatically and massively upload and sell your non-fungible tokens on OpenSea using Python Selenium

OpenSea Bulk Uploader And Trader 100000 NFTs (MAC WINDOWS ANDROID LINUX) Automatically and massively upload and sell your non-fungible tokens on OpenS

ERC-7211 3 Mar 24, 2022
IMDbPY is a Python package useful to retrieve and manage the data of the IMDb movie database about movies, people, characters and companies

IMDbPY is a Python package for retrieving and managing the data of the IMDb movie database about movies, people and companies. Revamp notice Starting

Davide Alberani 1.1k Jan 2, 2023
Track live sentiment for stocks from Reddit and Twitter and identify growing stocks

Market Sentiment About This repository can mainly be used for two things. a. Tracking the live sentiment of stocks from Reddit and Twitter b. Tracking

Market Sentiment 345 Dec 17, 2022
Telegram Voice Chat UserBot made with Pyrogram and MarshalX/tgcalls with playlist and Heroku support

Telegram Voice Chat UserBot A Telegram UserBot to Play Audio in Voice Chats. This is also the source code of the userbot which is being used for playi

Calls Music 164 Nov 12, 2022
OSINT tool to get information from a Github and Gitlab profile and find user's email addresses leaked on commits.

gitrecon OSINT tool to get information from a Github or Gitlab profile and find user's email addresses leaked on commits. ?? How does this work? GitHu

GOΠZO 211 Dec 17, 2022
Policy and data administration, distribution, and real-time updates on top of Open Policy Agent

⚡ OPAL ⚡ Open Policy Administration Layer OPAL is an administration layer for Open Policy Agent (OPA), detecting changes to both policy and policy dat

null 8 Dec 7, 2022
This is a simple collection of instructions and scripts to accompany the computerphile video about mininet and openflow.

How to get going. This project should work on Linux or MacOS. I used Ubuntu 20.04 and provide some notes here. Note, this is certainly not intended as

Richard G. Clegg 70 Jan 2, 2023