如何使用路线距离创建颜色图
How to create a colormap with the distance of routes
目前我有一个图表显示我网络中所有节点和我的目标之间的所有最短路径:
现在我想制作一个 cmap,我将根据最短路径的距离为原点和边着色。谁能帮帮我?
这是我的资料:
import networkx as nx
import matplotlib.pyplot as plt
import osmnx as ox
import pandas as pd
import geopandas as gpd
from shapely.wkt import loads as load_wkt
ox.config(log_console=True, use_cache=True)
place = {'city': 'Lisbon', 'country': 'Portugal'}
G = ox.graph_from_place(place, network_type='drive')
G = ox.project_graph(G)
hospitals = ox.pois_from_place(place, amenities=['hospital'])
hosp_1 = hospitals.iloc[21]['geometry'] # Hospital Santa Maria (Polygon)
def poly_centroide(polygon):
# Gives me the coordinates of the center point of the Polygon
p1 = load_wkt(polygon)
centroide = p1.centroid.wkt
return centroide
polygon_1 = str(hosp_1)
coord_1_str = poly_centroide(polygon_1)
coord_1 = (38.74817825481225, -9.160815118526642) # Coordinates Hospital Santa Maria
target_1 = ox.get_nearest_node(G, coord_1)
routes = []
for node in G.nodes:
try:
route = nx.shortest_path(G, node, target_1)
routes.append(route)
except nx.exception.NetworkXNoPath:
continue
fig, ax = ox.plot_graph_routes(G, routes, edge_linewidth=0.2, node_size=5, route_linewidth=1)
plt.show()
现在我想知道如何创建节点和边的颜色基于最短路径距离的 cmap。
我怀疑可以用 nx.dra() 来完成,但我不知道如何...
提前致谢。
我已经稍微添加到你的代码中。这将有助于根据节点的拓扑距离为节点着色(因为在计算最短路径时没有传递任何特定权重,所以最短路径是根据到达目的地所需遍历的边数计算的,因为每条边都是分配权重 1).
我在target_1 = ox.get_nearest_node(G, coord_1)
之后开始
从图中获取节点和边地理数据框。为此,我们需要节点地理数据框。
nodes, edges = ox.graph_to_gdfs(G, nodes=True, edges=True)
然后我们计算最短路径、最短路径长度,并将后者分配给 nodes
地理数据框中的新列。
nodes['shortest_route_length_to_target'] = 0
routes = []
route_lengths = []
i = 0
for node in G.nodes:
try:
route = nx.shortest_path(G, node, target_1)
route_length = nx.shortest_path_length(G, node, target_1)
routes.append(route)
route_lengths.append(route_length)
nodes['shortest_route_length_to_target'][node] = route_length
except nx.exception.NetworkXNoPath:
continue
现在我们定义以下函数。您会注意到这些函数是文件 plot.py 中已经存在的函数,但为此目的稍作修改。
import numpy as np
import matplotlib.cm as cm
def get_colors(n, cmap='viridis', start=0., stop=1., alpha=1.,):
colors = [cm.get_cmap(cmap)(x) for x in np.linspace(start, stop, n)]
colors = [(r, g, b, alpha) for r, g, b, _ in colors]
return colors
def get_node_colors_by_attr(G, attr, num_bins=None, cmap='viridis', start=0, stop=1, na_color='none'):
if num_bins is None:
num_bins=len(G.nodes())
bin_labels = range(num_bins)
# attr_values = pd.Series([data[attr] for node, data in G.nodes(data=True)])
attr_values = pd.Series(nodes[attr].values)
cats = pd.qcut(x=attr_values, q=num_bins, labels=bin_labels)
colors = get_colors(num_bins, cmap, start, stop)
node_colors = [colors[int(cat)] if pd.notnull(cat) else na_color for cat in cats]
return node_colors
现在,以下代码行将为您提供所需的输出。
nc = get_node_colors_by_attr(G, attr = 'shortest_route_length_to_target', num_bins=20,)
fig, ax = ox.plot_graph(G, node_color = nc, fig_height=20,)
您可以改变颜色图 (cmap
) 或要将 route_lengths
值离散化成的 bin 数 (num_bins
)。
目前我有一个图表显示我网络中所有节点和我的目标之间的所有最短路径:
这是我的资料:
import networkx as nx
import matplotlib.pyplot as plt
import osmnx as ox
import pandas as pd
import geopandas as gpd
from shapely.wkt import loads as load_wkt
ox.config(log_console=True, use_cache=True)
place = {'city': 'Lisbon', 'country': 'Portugal'}
G = ox.graph_from_place(place, network_type='drive')
G = ox.project_graph(G)
hospitals = ox.pois_from_place(place, amenities=['hospital'])
hosp_1 = hospitals.iloc[21]['geometry'] # Hospital Santa Maria (Polygon)
def poly_centroide(polygon):
# Gives me the coordinates of the center point of the Polygon
p1 = load_wkt(polygon)
centroide = p1.centroid.wkt
return centroide
polygon_1 = str(hosp_1)
coord_1_str = poly_centroide(polygon_1)
coord_1 = (38.74817825481225, -9.160815118526642) # Coordinates Hospital Santa Maria
target_1 = ox.get_nearest_node(G, coord_1)
routes = []
for node in G.nodes:
try:
route = nx.shortest_path(G, node, target_1)
routes.append(route)
except nx.exception.NetworkXNoPath:
continue
fig, ax = ox.plot_graph_routes(G, routes, edge_linewidth=0.2, node_size=5, route_linewidth=1)
plt.show()
现在我想知道如何创建节点和边的颜色基于最短路径距离的 cmap。
我怀疑可以用 nx.dra() 来完成,但我不知道如何...
提前致谢。
我已经稍微添加到你的代码中。这将有助于根据节点的拓扑距离为节点着色(因为在计算最短路径时没有传递任何特定权重,所以最短路径是根据到达目的地所需遍历的边数计算的,因为每条边都是分配权重 1).
我在target_1 = ox.get_nearest_node(G, coord_1)
从图中获取节点和边地理数据框。为此,我们需要节点地理数据框。
nodes, edges = ox.graph_to_gdfs(G, nodes=True, edges=True)
然后我们计算最短路径、最短路径长度,并将后者分配给 nodes
地理数据框中的新列。
nodes['shortest_route_length_to_target'] = 0
routes = []
route_lengths = []
i = 0
for node in G.nodes:
try:
route = nx.shortest_path(G, node, target_1)
route_length = nx.shortest_path_length(G, node, target_1)
routes.append(route)
route_lengths.append(route_length)
nodes['shortest_route_length_to_target'][node] = route_length
except nx.exception.NetworkXNoPath:
continue
现在我们定义以下函数。您会注意到这些函数是文件 plot.py 中已经存在的函数,但为此目的稍作修改。
import numpy as np
import matplotlib.cm as cm
def get_colors(n, cmap='viridis', start=0., stop=1., alpha=1.,):
colors = [cm.get_cmap(cmap)(x) for x in np.linspace(start, stop, n)]
colors = [(r, g, b, alpha) for r, g, b, _ in colors]
return colors
def get_node_colors_by_attr(G, attr, num_bins=None, cmap='viridis', start=0, stop=1, na_color='none'):
if num_bins is None:
num_bins=len(G.nodes())
bin_labels = range(num_bins)
# attr_values = pd.Series([data[attr] for node, data in G.nodes(data=True)])
attr_values = pd.Series(nodes[attr].values)
cats = pd.qcut(x=attr_values, q=num_bins, labels=bin_labels)
colors = get_colors(num_bins, cmap, start, stop)
node_colors = [colors[int(cat)] if pd.notnull(cat) else na_color for cat in cats]
return node_colors
现在,以下代码行将为您提供所需的输出。
nc = get_node_colors_by_attr(G, attr = 'shortest_route_length_to_target', num_bins=20,)
fig, ax = ox.plot_graph(G, node_color = nc, fig_height=20,)
您可以改变颜色图 (cmap
) 或要将 route_lengths
值离散化成的 bin 数 (num_bins
)。