0

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 !

0 Answers0