Networkx visualization - visualization

I am new to netwrokx and I have a big network as follows that I need to just visualize its blue nodes:
Is there any way to see just blue nodes while the distance between them is same as the real graph's?
My desired output would be something like following one:
Result of using pos layout is as follows:
Joel helped med to find out the result and I share codes and outcome here for those who have the similar question:
Answer Codes:
pos = nx.spring_layout(G)
nx.draw_networkx(G, pos, nodelist = blue_nodes, node_color =
'blue',with_labels=False)
outcome:

Given a network G, with a list of "blue" nodes bluenodes, we can define a set of positions, and then draw just the blue nodes.
pos = nx.spring_layout(G) #there are other layouts that you might want to try.
nx.draw_networkx_nodes(G, pos, nodelist = bluenodes, node_color = 'blue', with_labels=False)

Related

Node attributes in for loops, NetworkX

I'm trying to model voting dynamics on networks, and would like to be able to create a graph in NetworkX where I can iterate the voter process on nodes, having their colour change corresponding to their vote 'labels'.
I've managed to get this code to let me see the attributes for each node, but how do I go about using those in a for loop to designate colour?
H = nx.Graph()
H.add_node(1,vote='labour')
H.add_node(2,vote='labour')
H.add_node(3,vote='conservative')
h=nx.get_node_attributes(H,'vote')
h.items()
Gives me the result:
[(1, 'labour'), (2, 'labour'), (3, 'conservative')]
I've got a for loop to do this type of colour coding based on the node number as follows, but haven't managed to make it work for my 'vote' status.
S=nx.star_graph(10)
colour_map=[]
for node in S:
if node % 2 ==0:
colour_map.append('blue')
else: colour_map.append('yellow')
nx.draw(S, node_color = colour_map,with_labels = True)
plt.show()
You can iterate the node attributes with H.nodes(data=True) which returns the node name and the node attributes in a dictionary. Here's a full example using your graph.
import networkx as nx
import matplotlib.pyplot as plt
H = nx.Graph()
H.add_node(1, vote='labour')
H.add_node(2, vote='labour')
H.add_node(3, vote='conservative')
color_map = []
for node, data in H.nodes(data=True):
if data['vote'] == 'labour':
color_map.append(0.25) # blue color
elif data['vote'] == 'conservative':
color_map.append(0.7) # yellow color
nx.draw(H, vmin=0, vmax=1, cmap=plt.cm.jet, node_color=color_map, with_labels=True)
plt.show()
This code will draw a different layout of nodes each time you run it (some layouts, as e.g. draw_spring, are available here).
Regarding colors, I use 0.25 for blue and 0.7 for yellow. Note that I use the jet matplotlib colormap and that I set vmin=0 and vmax=1 so that the color values are absolute (and not relative to eachother).
Output of the code above:
UPDATE:
I wasn't aware that you could simply use color names in matplotlib. Here's the updated for loop:
for node, data in H.nodes(data=True):
if data['vote'] == 'labour':
color_map.append("blue")
elif data['vote'] == 'conservative':
color_map.append("yellow")
And the updated draw command:
nx.draw(H, node_color=color_map, with_labels=True)
Note that this way you get different shades of blue and yellow than in the image above.

How to accurately order the clusters based on color in matlab [duplicate]

This question already exists:
How to accurately classify leafs into its disease category using Matlab
Closed 6 years ago.
I have an image of leaf that has mostly three colors black background, green leaf and brown diseased spots.
Here is the image
When I cluster it first time, I get brown spots in cluster 1, green portion in cluster 2, black region in cluster 3(for example).
When I cluster it second time, I get green portion in cluster 1,brown spots in cluster 2, black region in cluster 3(for example). b
When I cluster it third time the order of clusters are different again.
I want to change the code such that the brown spots appear in cluster 1, green portion in cluster 2 and black in cluster 3. The order of clusters should be same even if I cluster many times.Could someone please help me with the code? I am using Matlab2009a. This question is about ordering clusters
Here is what is being done so far
function segmented_img = leaf_segmentation( original_img, nclusters )
original_img = im2double(original_img);
G=fspecial('gaussian',[200 250],1);
smoothed_img =imfilter(original_img,G,'same');
conversionform = makecform('srgb2lab');
lab_img = applycform(smoothed_img,conversionform);
ab_img = double(lab_img(:,:,2:3));
nrows = size(ab_img,1);
ncols = size(ab_img,2);
ab_img = reshape(ab_img,nrows*ncols,2);
cluster_idx =
kmeans(ab_img,nclusters,'distance','sqEuclidean','Replicates',3);
cluster_img = reshape(cluster_idx,nrows,ncols);
segmented_img = cell(1,nclusters);
for k = 1:nclusters
segmented_img{k} = bsxfun( #times, original_img, cluster_img == k );
end
end
segmented = leaf_segmentation( imread('input image'), 3 );
figure,imshow(segmented{1}), title('Cluster 1');
figure, imshow(segmented{2}), title('Cluster 2');
figure, imshow(segmented{3}), title('Cluster 3');
Matlab kmeans has a 'Start' parameter, which can be set to a matrix of centroid initial locations. You can initialize to black, brown and green and you will probably even get the results a bit faster, if the image is really mostly composed of these colours.
Documentation
Just check the colors after the clustering!
One way of doing this is transforming the centroids color space to HSV and checking the values oh H and V. H will give you the color (for example, around 120.0 degrees its green) and V will give you the "ligth", so if V is 0 then whatever H is, it is the black cluster.
This should be trivial to program, but dont hesitate to ask any questions about it.

Image Processing - Dress Segmentation using opencv

I am working on dress feature identification using opencv.
As a first step, I need to segment t-shirt by removing face and hands from the image.
Any suggestion is appreciated.
I suggest the following approach:
Use Adrian Rosebrock's skin detection algorithm for detecting the skin (thank you for Rosa Gronchi for his comment).
Use region growing algorithm on the variance map. The initial seed can be calculated by using stage 1(see the attached code for more information).
code:
%stage 1: skin detection - Adrian Rosebrock solution
im = imread(<path to input image>);
hsb = rgb2hsv(im)*255;
skinMask = hsb(:,:,1) > 0 & hsb(:,:,1) < 20;
skinMask = skinMask & (hsb(:,:,2) > 48 & hsb(:,:,2) < 255);
skinMask = skinMask & (hsb(:,:,3) > 80 & hsb(:,:,3) < 255);
skinMask = imclose(skinMask,strel('disk',6));
%stage 2: calculate top, left and right centroid from the different connected
%components of the skin
stats = regionprops(skinMask,'centroid');
topCentroid = stats(1).Centroid;
rightCentroid = stats(1).Centroid;
leftCentroid = stats(1).Centroid;
for x = 1 : length(stats)
centroid = stats(x).Centroid;
if topCentroid(2)>centroid(2)
topCentroid = centroid;
elseif centroid(1)<leftCentroid(1)
leftCentroid = centroid;
elseif centroid(1)>rightCentroid(1)
rightCentroid = centroid;
end
end
%first seed - the average of the most left and right centroids.
centralSeed = int16((rightCentroid+leftCentroid)/2);
%second seed - a pixel which is right below the face centroid.
faceSeed = int16(topCentroid);
faceSeed(2) = faceSeed(2)+40;
%stage 3: std filter
varIm = stdfilt(rgb2gray(im));
%stage 4 - region growing on varIm using faceSeed and centralSeed
res1=regiongrowing(varIm,centralSeed(2),centralSeed(1),8);
res2=regiongrowing(varIm,faceSeed(2),faceSeed(1),8);
res = res1|res2;
%noise reduction
res = imclose(res,strel('disk',3));
res = imopen(res,strel('disk',2));
result after stage 1(skin detection):
final result:
Comments:
Stage 1 is calculated using the following algorithm.
The region growing function can be downloaded here.
The solution is not perfect. For example, it may fail if the texture of the shirt is similar to the texture of the background. But I think that it can be a good start.
Another improvement which can be done is to use a better region growing algorithm, which doesn't grows into the skinMask location. Also, instead of using the region growing algorithm twice independently, the result of the second call of region growing can can be based on the result from the first one.

Grouping nodes with the same color near each other in graphviz

I have created a graph with networkx and have wrote the graph representation to a dot file to be displayed with graphviz. Now, the nodes have color attributes and I would like graphviz to place nodes with the same color closer to each other.
For example, if node "soccer" and node "football" both have color 'blue' then they should be close together, whereas node "baseball" with color 'green' would not be near nodes "soccer" and "football"
How can I get nodes with the same color to be drawn closer together in Graphviz; hence forming clusters of colors?
Thanks for all the help and let me know if you need more information :)
You could use PyGraphviz to do the layout using dot with "clusters".
e.g.
import networkx as nx
G = nx.Graph()
G.add_node(1, color='blue', style='filled')
G.add_node(2, color='red', style='filled')
G.add_edge(1,2)
G.add_node(3, color='blue',style='filled')
G.add_node(4, color='red',style='filled')
G.add_edge(3,4)
G.add_edge(4,10)
G.add_path([10,20,30,40,50])
A = nx.to_agraph(G) # uses pygraphviz
red_nodes = [n for n,d in G.node.items() if d.get('color')=='red']
blue_nodes = [n for n,d in G.node.items() if d.get('color')=='blue']
A.add_subgraph(red_nodes, name = 'cluster1', color='red')
A.add_subgraph(blue_nodes, name = 'cluster2', color='blue')
A.write('colors.dot')
A.layout('dot')
A.draw('colors.png')

distribute same size circles evenly inside a square using Matlab

I have a figure of size 14 x 14 square drawn inside an axis of 20 x 20, in matlab.
I am trying to draw circles of radius 0.7 inside the square and need to arrange them evenly. I need to draw 233 circles. Please let me know how can I do it?
Currently I can draw them randomly but couldn't get 233 circle. Please see my below code.
Your reply is appreciated.
% Urban, sub urban, Rural areas
x_area =[3, 12, 6];
y_area = [6, 8, 16];
r_area = [1, 7, 2];
f = figure;
hAxs = axes('Parent',f);
hold on, box on, axis equal
xlabel('x')
ylabel('y','Rotation',0)
title('Compute the area of circles a vectorized way for several cicles')
axis([0 20 0 20])
rectangle('Position',[5,1,14,14])
rectangle('Position',[3,1,2,2])
rectangle('Position',[1,3,4,4])
hold on, box on, axis equal
a = 233;
x_base_urban = randi([6 18], 1, a);
b = rand([10 8], 1);
y_base_urban = randi([2 14],1, a);
r_base_urban = 0.9;
size_x = size(x_base_urban);
size_x = size_x(2);
size_y = size(y_base_urban);
size_y = size_y(2);
colour = rand(size_x,3);
for t = 1: size_x
plot(x_base_urban(t)+ r_base_urban.*cos(0:2*pi/100:2*pi),...
y_base_urban(t)+ r_base_urban.*sin(0:2*pi/100:2*pi),'parent',hAxs)
plot(x_base_urban(t),y_base_urban(t),'+','parent',hAxs)
end
Thanks
Randomly plotting everything won't work. Actually, if your circles can't overlap, nothing will work. To show that, just compare the results of following calculations:
lSquare = 14;
rCircle = 0.7;
nCircles = 233;
areaCircles = nCircles * pi * rCircle^2
areaSquare = lSquare^2
You will see that areaCircles > areaSquare, so it is impossible to fit them all in. On the other hand, if areaSquare >= areaCircles does not guarantee you that a solution exists!
Try your setup with a smaller example to come up with a solution. E.g. take a square box and a bunch of spherical objects (balls, marbles, oranges, apples, ... if need be) and try to fit as much of those in your box. If that works, you might even want to draw their positions on a sheet of paper before trying to implement it.
If you do this correctly, you will get an idea of how to stack round objects in a square container. That is also exactly what you need to do in your exercise. Then try to make a model/algorithm of what you did manually and implement that in MATLAB. It won't be hard, but you will need some small calculations: Pythagoras and intersection of circles.
I also suggest you use a function to draw a circle as #Andrey shows, so something of the form function drawCircle(center, radius). That allows you to keep complexity down.
If your circles can overlap, then the solution is quite easy: look at a circle as an object with a center point and distribute these center points evenly over the square. Don't use rand to do this, but calculate their positions yourself.
If you can't find a solution, I might expand my answer in a few days.
Without diving too deep into your code, I think that you need to add a hold function, after the first plot
for t = 1: size_x
plot(x_base_urban(t)+ r_base_urban.*cos(0:2*pi/100:2*pi),...
y_base_urban(t)+ r_base_urban.*sin(0:2*pi/100:2*pi),'parent',hAxs)
plot(x_base_urban(t),y_base_urban(t),'+','parent',hAxs)
hold(hAxs,'on');
end
By the way, the best way to draw circle is by using rectangle command.
rectangle('Curvature',[1 1],'Position',[1 3 4 5])
So you can create a PlotCircle function (like #EgonGeerardyn suggests) like this:
function plotCircle(x,y,r)
rectangle('Position',[x-r y-r 2*r 2*r],'Curvature',[1 1]);
end