问题
I have two lists of coordinates: first for x-coordinates and second for y-coordinates. I trying to use them as nodes of a graph.
import networkx as nx
list_of_coordinates_x = list(4.5 , 4, 67, 578, 68) #random numbers
list_of_coordinates_y = list(6.7, 3, 12, 45.555, 692)
G=nx.MultiGraph()
for i in range(len(list_of_coordinates_x)):
G.add_node(i, x = list_of_coordinates_x[i], y = list_of_coordinates_y[i])
if i > 0:
G.add_edge(i-1,i)
nx.draw(G,node_size=10,with_labels=False)
But the all graphs that I have by this way looks like sets of nodes put on the plane randomly. How can I fixate them by my coordinates on the image? And how can I use my own 1680x1050 .jpg file for that? After using the answer on the first part of the question, I have this graph:
But I want to put it on a picture like this:
回答1:
For that you need to set the node positions as attributes, and just use a placeholder as node name. So one approach could be to just enumerate
the nodes in the order they appear, and follow the same logic as yours, but adding the zipped coordinate elements as pos
attributes:
x = [4.5 , 420, 67, 620, 68]
y = [6.7, 68, 56, 231, 380]
G = nx.DiGraph()
coords = list(zip(x,y))
for node, coo in enumerate(coords, start=1):
G.add_node(node, pos=coo)
if node<len(coords):
G.add_edge(node, node+1)
Then you could create a dictionary as node:(x,y)
which is the format that pos
in nx.draw
is expecting, and the nodes are in this way located on the specified coordinates:
nodes = G.nodes(data=True)
pos = {node:attr['pos'] for node, attr in nodes}
plt.figure(figsize=(12,5))
nx.draw(G,
nodelist=nodelist,
pos=pos,
node_size=500,
node_color='orange')
In order to overlap the graph on an existing image you have to make sure that they both share the same extent
. This is nicely explained here:
When layering multiple images, the images need to have the same extent. This does not mean they need to have the same shape, but they both need to render to the same coordinate system determined by xmin, xmax, ymin, ymax
In order to do so, you can enforce a certain extent to both the graph coordinates and the image. This value will depend on the image size, so you'll have to adjust the extent of both the graph and image to the actual size of the image. I'll use a sample image from klearn.datasets.load_sample_image
as an example, but for your own image you can just load it with matplotlib.image.imread('my_image.jpg')
.
from sklearn.datasets import load_sample_image
img = load_sample_image('flower.jpg')
x = [4.5 , 420, 67, 620, 68]
y = [6.7, 68, 56, 231, 380]
y_lim, x_lim = img.shape[:-1]
extent = 0, x_lim, 0, y_lim
G = nx.DiGraph()
coords = list(zip(x,y))
for node, coo in enumerate(coords, start=1):
G.add_node(node, pos=coo)
if node<len(coords):
G.add_edge(node, node+1)
fig = plt.figure(frameon=False, figsize=(10,19))
plt.imshow(img, extent=extent, interpolation='nearest')
nodes = G.nodes(data=True)
pos = {node:attr['pos'] for node, attr in nodes}
nx.draw(G,
nodelist=nodelist,
pos=pos,
node_size=200,
edge_color='w',
width=4,
extent=extent,
node_color='orange',
interpolation='nearest')
plt.show()
来源:https://stackoverflow.com/questions/61674222/overlap-graph-on-image-using-coordinates