Networkx to break the path if there is an intersection and print all the possible path - networkx

Is there a built-in function from networkx to print all of the path in the networkx?
I need to get list path without intersection in it. If there is an intersection, we break that path and list each of the possible path starting from that intersection until it reaches the end of the node. If the next node is an intersection, then that node is considered as end of node.
Example:
In the second graph, intersections are C and E. So, connected components should be:
-[C,F,G],[C,B,A],[E,H].[E,J,I],[E,D], [C,E] (It would be better if I can get their attributes as well
First graph, intersections are L, M ,N . Thus, connected components should be:
-[L,V],[N,P][N,O],[L,M,N],[L,N]
import networkx as nx
import matplotlib.pyplot as plt
G = nx.MultiGraph()
relations = [('A', 'B', 'neighbour'), ('A', 'B', 'friend'), ('B', 'C', 'coworker'),
('C', 'F', 'coworker'), ('C', 'F', 'friend'), ('F', 'G', 'coworker'),
('F', 'G', 'family'), ('C', 'E', 'friend'), ('E', 'D', 'family'),
('E', 'I', 'coworker'), ('E', 'I', 'neighbour'), ('I', 'J', 'coworker'),
('E', 'J', 'friend'), ('E', 'H', 'coworker'),('V', 'L', 'friend'),('M', 'L', 'friend'),('M', 'N', 'friend'), ('N', 'O', 'coworker'),('N', 'P', 'friend'), ('L', 'N', 'coworker')]
plt.figure(figsize =(9, 9))
nx.draw_networkx(G)
I actually also built the graph using momepy and geopandas as the data source. So, if there a function I can use in momepy, I am very keen to know too.
df = gpd.GeoDataFrame(df)
graph = momepy.gdf_to_nx(df, approach='primal')
nodes, edges, sw = momepy.nx_to_gdf(graph, points=True, lines

Related

How to distinguish multiple overlapping lines on MATLAB graphs?

How can I distinguish multiple overlapping lines on MATLAB graphs like this?
I would suggest different combinations of line widths, marker sizes and colors, plot the thickest lines and largest markers first since the ones plotted later will be on top, this code demonstrates this:
x=1:5;
plot(x, x, 'color', 'b', 'marker', 'o', 'markersize', 10, 'linewidth', 1)
line(x, x, 'color', 'g', 'linewidth', 1, 'marker', 's', 'markersize', 5, 'markerfacecolor', 'g', 'linestyle', '--')

How can I adjust line width for individual lines in a combined plot?

When I adjust line width for this type of plot it works.
plot(x1,y1, 'm','Linewidth',1)
hold on
plot(x2,y2, 'b','Linewidth',2)
hold on
plot(x3,y3, 'r','Linewidth',3)
hold on
plot(x4,y4, 'c','Linewidth',4)
hold on
plot(x5,y5, 'o','Linewidth',5)
But not when I do this.
plot(x1, y1, 'm','Linewidth',1,x2, y2, 'b','Linewidth',2,x3, y3, 'r','Linewidth',3,x4, y4, 'c','Linewidth',4,x5, y5, 'o','Linewidth',5);
I get an error.
Is it possible to adjust line width for a combined plot?
Is it possible to adjust line width for a combined plot?
No (well yes but not in a cleaner way).
You can adjust the parameters for all of them together if you want a single line. If you want control over the appearance of each of them, you will need to do separate plots.
You can do it accessing the properties, but I suspect that is just longer and less clear, so not sure if it is really the right solution.
h=plot(x1, y1, x2, y2, ...);
h(1).LineWidth=1;
h(2).LineWidth=2;
...
An alternate approach that is more scalable for greater numbers of plots and/or extra properties uses arrayfun. Basically, if you set up the data for all your plots in arrays, you can then plot all data with only one line of code
% set up the data and all plot attributes
x = {x1, x2, x3, x4, x5};
y = {y1, y2, y3, y4, y5};
styles = ['m', 'b', 'r', 'c', 'o'];
widths = [1, 2, 3, 4, 5];
% setup figure
figure
ax = axes('NextPlot','add'); % like calling hold on
% plot all elements
% equivalent to a for loop: for i = 1:length(x)
arrayfun(#(i) plot(ax, x{i}, y{i}, styles(i), 'linewidth', widths(i)), 1:length(x));
I don't like using hold since it is hard to know if it is on or off when you do the next plot. I like to use plot for the first line and line for subsequent lines like this:
plot(x1, y1, 'm', 'linewidth', 1)
line(x2, y2, 'color', 'b', 'linewidth', 2)
line(x3, y3, 'color', 'r', 'linewidth', 3)
line(x4, y4, 'color', 'c', 'linewidth', 4)
line(x5, y5, 'color', 'o', 'linewidth', 5)

Single legend for plots in primary and secondary axes

I created a plot with two data sets, in a primary and secondary Y axes, respectively, using
[ ha, hl1, hl2 ] = plotyy( xr, yr, xq, yq );
Then I formatted the lines with
set( hl1, 'Linestyle', '-' ); set( hl1, 'Color', 'b' ); % solid, blue
set( hl2, 'Linestyle', '--' ); set( hl2, 'Color', 'r' ); % dash, red
and I finally created a common legend for both with
hl = legend( [ hl1, hl2 ], 'r', '\theta/\pi' );
I guess it is not important the contents of ( xr, yr, xq, yq ). The two lines are correctly plotted, and each one on the correct axis.
The first line in the legend should have a (solid, blue) line, and
the second line should have a (dash, red) line.
The result is the opposite (see figure).
This is the same if I use
hl = legend( [ hl2, hl1 ], 'r', '\theta/\pi' );
and if I change the comma by a semicolon [ hl2; hl1 ].
What is the right way of doing it?
with octave-4.0.1-rc4, default graphics_toolkit ("qt"), the result seems fine.
x = linspace(0, 2*pi, 101);
[ha, hl1, hl2] = plotyy(x, sin(x), x, -sin(x));
set( hl1, 'Linestyle', '-' ); set( hl1, 'Color', 'b' ); % solid, blue
set( hl2, 'Linestyle', '--' ); set( hl2, 'Color', 'r' ); % dash, red
hl = legend( [ hl1, hl2 ], 'r', '\theta/\pi' );
Except the \theta/\pi is not correctly interpreted.
No need to file a bug report, since it has been solved in the development version.
But with 4.0.1 and graphics_toolkit("gnuplot") the plot is fine:
So it might be time to upgrade. Here are the ftp site and windows installers.
Using code like ederag's
x = linspace(0, 2*pi, 101);
[ha, hl1, hl2] = plotyy(x, sin(x), x, -sin(x));
set( hl1, 'Linestyle', '-' ); set( hl1, 'Color', 'b' ); % solid, blue
set( hl2, 'Linestyle', '--' ); set( hl2, 'Color', 'r' ); % dash, red
hl = legend( [ hl1, hl2 ], 'r', '\theta/\pi' );
I found out that adding the line
set( hl, 'fontsize', 20 );
after it inverts the lines in the legend. As far as I understand, this is unexpecetd (possibly a bug?).

Is that possible to assemble several options and pass to the plot function in matlab

I am using MATLAB to plot several figures and hope these figure use the same plot options, it looks something like this:
N = 20;
Fs = 200;
t = (0:N-1)/Fs;
x = sin(2*pi*10*t);
y = cos(2*pi*20*t);
z = x + y;
figure(1),clf;
subplot(311);
plot(t, x, 'bs-', 'MarkerFaceColor', 'b', 'LineWidth', 3);
grid on;
subplot(312);
plot(t, y, 'bs-', 'MarkerFaceColor', 'b', 'LineWidth', 3);
grid on;
subplot(313);
plot(t, z, 'bs-', 'MarkerFaceColor', 'b', 'LineWidth', 3);
grid on;
You can see the plot options are exactly the same. If I want to change the style, I have to change each of them. Is that possible assemble/group them together and pass them to the plot function?
I have tried to put them in a cell like this
plotOptions = {'bs-', 'MarkerFaceColor', 'b', 'LineWidth', 3};
It doesn't work. The reason might be the plot functions would take the plotOptions as one paramter and thus failed to parse it.
Using a cell with the options was already a good approach. Just use {:}, as below:
opt = {'bs-', 'MarkerFaceColor', 'b', 'LineWidth', 3};
figure(1),clf;
subplot(311);
plot(t, x, opt{:});
Then, each element of the cell is evaluated as single argument.
Solution with unique plotting function:
subplot(312);
myplot(t,y)
Save myplot function as a separate m-file.
function myplot(t,x)
plot(t, x, 'bs-', 'MarkerFaceColor', 'b', 'LineWidth', 3);
end
The cell answer is good, another option is to set the arg value to be a variable:
faceColor = 'b';
lineWidth = 3;
figure(1),clf;
subplot(311);
plot(t, x, 'bs-', 'MarkerFaceColor', faceColor, 'LineWidth', lineWidth);
subplot(312);
plot(t, y, 'bs-', 'MarkerFaceColor', faceColor, 'LineWidth', lineWidth);
subplot(313);
plot(t, z, 'bs-', 'MarkerFaceColor', faceColor, 'LineWidth', lineWidth);
A very clean alternative approach would be to keep the plot command as simple as possible and manipulate the handles afterwards.
opts = {'Color','red','MarkerFaceColor', 'b', 'LineWidth',3};
h(1) = plot(t, x);
grid on;
subplot(312);
h(2) = plot(t, y);
grid on;
subplot(313);
h(3) = plot(t, z);
grid on;
arrayfun(#(x) set(x,opts{:}),h)
The advantage over the indeed neat approach by Nemesis is, that in case you have multiple sets of properties, like:
opts.slimRed = {'Color','red','MarkerFaceColor', 'b', 'LineWidth',1};
opts.fatBlue = {'Color','blue','MarkerFaceColor', 'b', 'LineWidth',5};
and you want to exchange them, you just need to modify one variable
arrayfun(#(x) set(x,opts.fatBlue{:}),h)
to change the appearance of a whole set of handles h.

Intersection of two cell arrays of strings in MATLAB

I have two cell arrays, X and Y. Each cell array is made up of strings : i.e, X{i} is a string for all i, and so is Y{i}. I would like to find the intersection of the two cell arrays, (presumably a third cell array} that has the strings common to both X and Y.
There is a single function that does this: intersect
For example:
>> X = {'a', 'b'; 'c', 'd'};
>> Y = {'c', 'd', 'e', 'f'};
>> Z = intersect(X, Y)
Z =
'c' 'd'
There might a single function that does this - I don't remember. But you can do it pretty easily with ismember:
a = {'a', 'b', 'c'};
b = {'b', 'd', 'a'};
intersection = a(ismember(a, b));