How to load edges and nodes into a matlab network
Mostrar comentarios más antiguos
Is it possible to load edges and nodes into matlab for network/graph analysis (I want to model node centrality on a real network)?
I have a point file (file 1) With XYZ coordinates and unique name for nodes.
I have an edge file with two columns that describe the start and end nodes in file 1. (this was a polyline export from ArcGIS).
Any resources you could point me to would be greatly appreciated! I'm trying to model river network centrality...
This may not be possible... just was curious as I'm a beginner.
Respuesta aceptada
Más respuestas (1)
William Wadsworth
el 7 de Oct. de 2020
0 votos
18 comentarios
Steven Lord
el 7 de Oct. de 2020
You would need to create a graph or digraph using the functions listed in the Construction section on this documentation page. Since you have coordinate data you're probably going to want to store those as "Other Attributes" in the Nodes table of the graph or digraph as per the fourth item in the Topics section on that page. To use that coordinate data when plotting, see the "Custom Graph Node Coordinates" example on the documentation page for the plot function for network objects. The plot function is listed in the Visualization section on that documentation page to which I linked in the first sentence.
William Wadsworth
el 7 de Oct. de 2020
Ameer Hamza
el 8 de Oct. de 2020
Can you show how the data for nodes and edges is available? Is it a text file? Can you share a sample?
William Wadsworth
el 8 de Oct. de 2020
Ameer Hamza
el 8 de Oct. de 2020
See this example
nodes_info = readtable('ShareNodes.txt');
edges_info = readtable('ShareEdges.txt');
G = graph();
G = G.addnode(string(nodes_info.Nodename));
G = G.addedge(string(edges_info.NodenameFR), string(edges_info.NodenameTO));
plot(G);
William Wadsworth
el 8 de Oct. de 2020
Ameer Hamza
el 8 de Oct. de 2020
table elements are accessed using brace indexing
plot(G, 'XData', nodes_info{:,4}, 'YData', nodes_info{:,5}, 'ZData', nodes_info{:,6});
or using column name
plot(G, 'XData', nodes_info.Easting, 'YData', nodes_info.Northing, 'ZData', nodes_info.RASTERVALU);
William Wadsworth
el 8 de Oct. de 2020
Steven Lord
el 8 de Oct. de 2020
Distance as the crow flies between your points or as the ant crawls along the edges between your points? For the former compute the norm of the vector formed by subtracting coordinates of the points. For the latter, you probably want to use the distances function on your graph.
For the error about ZData not being finite, that means your data contains Inf or NaN values. You can see which ones aren't using isfinite then look back at the corresponding rows of your RiverNetworkNodesTrim.txt file.
>> x = [1 2 Inf 4 NaN 6 7];
>> F = isfinite(x)
F =
1×7 logical array
1 1 0 1 0 1 1
>> x(F)
ans =
1 2 4 6 7
>> x(~F)
ans =
Inf NaN
Ameer Hamza
el 8 de Oct. de 2020
As Steven mentioned, there is likely a NaN of Inf in the Z column.
Also, the weights are not automatically calculated by graphs when plotted. You need to specify the distances between nodes yourself. The following code shows a simple approach for calculating the distance values. I believe more efficient approaches should be possible.
nodes_info = readtable('ShareNodes.txt');
edges_info = readtable('ShareEdges.txt');
distances = zeros(size(edges_info,1),1);
for i = 1:numel(distances)
src = edges_info{i,1};
dst = edges_info{i,2};
idx_src = src == nodes_info{:,7};
idx_dst = dst == nodes_info{:,7};
src_pos = nodes_info{idx_src, 4:6};
dst_pos = nodes_info{idx_dst, 4:6};
distances(i) = norm(src_pos-dst_pos);
end
G = graph();
G = G.addnode(string(nodes_info.Nodename));
G = G.addedge(string(edges_info.NodenameFR), string(edges_info.NodenameTO), distances);
plot(G, ...
'XData', nodes_info{:,4}, ...
'YData', nodes_info{:,5}, ...
'ZData', nodes_info{:,6}, ...
'EdgeLabel', G.Edges.Weight);
Ameer Hamza
el 8 de Oct. de 2020
Here is another approach for calculating the distances. Not sure which one is more efficient for a large dataset. Maybe you can try and share the timing results.
nodes_info = readtable('ShareNodes.txt');
edges_info = readtable('ShareEdges.txt');
G = graph();
G = G.addnode(string(nodes_info.Nodename));
G = G.addedge(string(edges_info.NodenameFR), string(edges_info.NodenameTO), zeros(size(edges_info,1),1));
G.Nodes.X = nodes_info.Easting;
G.Nodes.Y = nodes_info.Northing;
G.Nodes.Z = nodes_info.RASTERVALU;
for i = 1:G.numedges
idx = G.findnode(G.Edges.EndNodes(i,:));
src_pos = G.Nodes{idx(1), 2:3};
dst_pos = G.Nodes{idx(2), 2:3};
G.Edges.Weight(i) = norm(src_pos-dst_pos);
end
plot(G, ...
'XData', nodes_info{:,4}, ...
'YData', nodes_info{:,5}, ...
'ZData', nodes_info{:,6}, ...
'EdgeLabel', G.Edges.Weight);
William Wadsworth
el 8 de Oct. de 2020
Ameer Hamza
el 8 de Oct. de 2020
Yes, this code also make sense. The distance calculations are correct.
William Wadsworth
el 9 de Oct. de 2020
Ameer Hamza
el 9 de Oct. de 2020
I guess there is some confusion here. Your current code calculates the distance as an ant crawls along the edges. The other case ("as the crow flies") does not require you to develop a graph. You just take two nodes and use their coordinates to calculate the distance. In that case, you don't care if there is an edge between these two nodes, just like a crow, which can fly in a straight line between any two points, whereas an ant can only move along edges to reach the destination. If there is no direct path, the ant needs to go through intermediate nodes.
William Wadsworth
el 9 de Oct. de 2020
Ameer Hamza
el 9 de Oct. de 2020
You can still use the z value in the calculation of distance by directly using vecnorm() [a general form of hypot()]
G.Edges.Weight = vecnorm(xyz(s,:)-xyz(t,:),2,2);
William Wadsworth
el 9 de Oct. de 2020
Categorías
Más información sobre Graph and Network Algorithms en Centro de ayuda y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!