Skip to content

Commit

Permalink
Add functionality to draw multiple paths on graph with legend showing…
Browse files Browse the repository at this point in the history
… path lengths

- Implemented draw_paths_matplotlib function to visualize multiple paths on a graph.
- Automatically generates a legend with the path lengths.
- Added functionality to calculate and display the total length of each path.
  • Loading branch information
romanroff committed Feb 3, 2025
1 parent b39c94f commit 9b2e0b1
Show file tree
Hide file tree
Showing 4 changed files with 208 additions and 51 deletions.
165 changes: 118 additions & 47 deletions examples/examples.ipynb

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions ride_pfa/drawer/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
from ride_pfa.drawer.folium_drawer import *
from ride_pfa.drawer.matplotlib_drawer import *
8 changes: 4 additions & 4 deletions ride_pfa/drawer/folium_drawer.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@
from ride_pfa.clustering import Community

__all__ = [
'draw_graph',
'draw_path'
'draw_graph_folium',
'draw_path_folium'
]


def draw_graph(
def draw_graph_folium(
graph: nx.Graph,
cms: Optional[Community] = None,
m: Optional[folium.Map] = None) -> folium.Map:
Expand Down Expand Up @@ -52,7 +52,7 @@ def draw_graph(
return m


def draw_path(graph: nx.Graph, path: list[int],
def draw_path_folium(graph: nx.Graph, path: list[int],
m: Optional[folium.Map],
color: str = 'red',
weight: float = 5) -> folium.Map:
Expand Down
85 changes: 85 additions & 0 deletions ride_pfa/drawer/matplotlib_drawer.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import random
from typing import Optional

import networkx as nx
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches

from ride_pfa.clustering import Community

__all__ = [
'draw_graph_matplotlib',
'draw_paths_matplotlib'
]

def draw_graph_matplotlib(graph: nx.Graph, cms: Optional[Community] = None, ax: Optional[plt.Axes] = None):
if ax is None:
_, ax = plt.subplots(figsize=(20, 20))

pos = {node: (graph.nodes[node]['x'], graph.nodes[node]['y']) for node in graph.nodes()}

if cms is not None:
colors = generate_colors(len(cms))
for i, c in cms:
nx.draw_networkx_nodes(graph, pos, nodelist=c, node_color=colors[i], ax=ax, node_size=10)
else:
nx.draw_networkx_nodes(graph, pos, node_color='blue', ax=ax, node_size=10)

nx.draw_networkx_edges(graph, pos, edge_color='gray', width=1, ax=ax)

ax.set_title("Graph Visualization")
ax.set_xlabel("Longitude")
ax.set_ylabel("Latitude")

return ax


def draw_paths_matplotlib(graph: nx.Graph, paths: list[tuple[list[int], str]], ax: Optional[plt.Axes] = None):
"""
Рисует граф и список путей на одном изображении.
:param graph: Граф (networkx)
:param paths: Список кортежей (путь, цвет), где путь — это список узлов, цвет — цвет линии пути.
Если цвет не задан, он будет выбран автоматически.
:param ax: График matplotlib (если None, создается новый)
"""
if ax is None:
_, ax = plt.subplots(figsize=(20, 20))

pos = {node: (graph.nodes[node]['x'], graph.nodes[node]['y']) for node in graph.nodes()}

# Рисуем граф один раз
draw_graph_matplotlib(graph, ax=ax)

# Генерируем цвета, если они не заданы
colors = generate_colors(len(paths))

legend_patches = []
for i, (path, color) in enumerate(paths):
color = color if color else colors[i]

path_edges = list(zip(path[:-1], path[1:]))
nx.draw_networkx_edges(graph, pos, edgelist=path_edges, edge_color=color, width=3, ax=ax)

# Вычисляем длину пути
total_length = sum(graph.edges[u, v].get('length', 0) for u, v in path_edges)

# Добавляем элемент в легенду
legend_patches.append(mpatches.Patch(color=color, label=f"Path {i+1}: {total_length:.2f}"))

# Добавляем легенду
ax.legend(handles=legend_patches, loc="upper right")

ax.set_title("Graph with Paths")
ax.set_xlabel("Longitude")
ax.set_ylabel("Latitude")

return ax


def random_color_hex():
return "#{:06x}".format(random.randint(0, 0xFFFFFF))


def generate_colors(num_colors):
return [random_color_hex() for _ in range(num_colors)]

0 comments on commit 9b2e0b1

Please sign in to comment.