Good afternoon. I'm on an a* shortest path finder based on osmnx data in python. Actually, I'm plotting my shortest path at the end of my computation. But I would like to try to liveplotting this path (even if this means to go back and erase a piece of the path during the running). For that, I would like to use only matplotlib I don't have any idea of how I can do that.
import networkx as nx
import matplotlib.pyplot as mp
import csv
from haversine import haversine, Unit
import datetime
class Node():
"""A node class for A* Pathfinding"""
def __init__(self, parent=None, id=None):
self.parent = parent
self.id = id
#g distance between current and start_node
#h is the crow flies between current and goal
#f=g+h is the heuristic
self.g = 0
self.h = 0
self.f = 0
def __eq__(self, other):
return self.id == other.id
def get_neighbors(G, nodeid):
neig=[]
for i in G.neighbors(nodeid):
neig.append(i)
return neig
def crow_flies(nodeida,nodeidb, node_gps):
a=()
b=()
if nodeida==nodeidb:
return 0
else :
for i in range(len(node_gps)) :
if node_gps[i][1]==nodeida :
a=(node_gps[i][2],node_gps[i][3])
elif node_gps[i][1]==nodeidb :
b=(node_gps[i][2],node_gps[i][3])
dist=haversine(a,b, unit=Unit.METERS)
return dist
def get_cost(G,nodeida,nodeidb):
cost=G[nodeida][nodeidb][0]['weight']
return cost
def astar(G, nodeida,nodeidb, node_gps):
start_node = Node(None, 46381175)
start_node.g = start_node.h = start_node.f = 0
end_node = Node(None, 46378853)
end_node.g = end_node.h = end_node.f = 0
open_list = []
closed_list = []
children_list = []
open_list.append(start_node)
while len(open_list)>0:
current_node = open_list[0]
current_index = 0
for index, item in enumerate(open_list):
if item.f < current_node.f:
current_node = item
current_index = index
open_list.pop(current_index)
closed_list.append(current_node)
# Found the goal
if current_node.id == end_node.id:
path = []
current = current_node
while current is not None:
path.append(current.id)
current = current.parent
return path[::-1] # Return reversed path
children_list=get_neighbors(G, current_node.id)
children=[]
for child in children_list:
new_child = Node(current_node, child)
children.append(new_child)
#si un des enfants est déjà dans la liste fermée, ne rien faire
for closed in closed_list:
if new_child == closed:
continue
new_child.g = current_node.g + get_cost(G,current_node.id,new_child.id)
new_child.h = crow_flies(new_child.id,end_node.id, node_gps)
new_child.f = new_child.g + new_child.h
for open_node in open_list:
if new_child == open_node and new_child.g > open_node.g:
continue
# Add the child to the open list
open_list.append(new_child)
if __name__ == '__main__':
Data = open('edgelist_amsterdam.csv', "r")
Graphtype = nx.MultiDiGraph()
G = nx.parse_edgelist(Data, delimiter=',', create_using=Graphtype,
nodetype=int, data=(('weight', float),))
Data.close()
node_gps=[]
with open('nodelist_amsterdam.csv') as csvfile:
reader = csv.reader(csvfile, quoting=csv.QUOTE_NONNUMERIC) # change contents to floats
for row in reader: # each row is a list
node_gps.append(row)
start=datetime.datetime.now()
path=astar(G,46387698, 46381175, node_gps)
end=datetime.datetime.now()
elapsedtime=(end-start).total_seconds()
print("Path from 46387698 to 46381175 found in", elapsedtime, "seconds. The shortest path is : ",path )
pos = nx.spring_layout(G,10)
nx.draw(G,pos, with_labels=True)
#nx.draw_networkx_nodes(G, pos, node_size=500, label=G.nodes)
nx.draw_networkx_edge_labels(G, pos, font_size=5)
path_edges = zip(path,path[1:])
path_edges = set(path_edges)
nx.draw_networkx_nodes(G,pos,nodelist=path,node_color='r')
nx.draw_networkx_edges(G,pos,edgelist=path_edges,edge_color='r',width=10)
mp.show()
That's what I actually do. Do you have any idea about what I could do to liveplot ?
Thanks a lot !