Update edge attributes of a graph with networkx - python

I have the following graph with the edge attributes:
import networkx as nx
import random
G=nx.DiGraph()
G.add_edge('x','a', dependency=0.4)
G.add_edge('x','b', dependency=0.6)
G.add_edge('a','c', dependency=1)
G.add_edge('b','c', dependency=0.3)
G.add_edge('b','d', dependency=0.7)
G.add_edge('d','e', dependency=1)
G.add_edge('c','y', dependency=1)
G.add_edge('e','y', dependency=1)
After setting the structure of my graph, I will sample three different edge attributes and multiply them with a random number as followed:
for i in range(3):
sampled_edge = random.sample(G.edges, 1)
print(sampled_edge)
sampled_edge_with_random_number = G.edges[sampled_edge[0]]['dependency'] * random.uniform(0,1)
print(sampled_edge_with_random_number)
Now I want to update the initial graph attribute with the new sampled graph attribute so it would look something like this. The algorithm should look for the same edge attribute in the structure and update the dependency value:
for i in G.edges:
if i == sampled_edge:
i['dependency'] = sampled_edge_with_random_number
Can someone help me with this?

You can just access the attribute to update and change it
>>> G=nx.DiGraph()
>>> G.add_edge('x','a', dependency=0.4)
>>> G['x']['a']
{'dependency': 0.4}
>>> G['x']['a']['dependency'] = 10
>>> G['x']['a']
{'dependency': 10}
Another approach is nx.set_edge_attributes
>>> sampled_edge = ('x', 'a')
>>> new_val = 42
>>> nx.set_edge_attributes(G, {sampled_edge:{'dependency':new_val}})
>>> G['x']['a']['dependency']
42
where ('x','a') is your sampled_edge.

Related

Generate a bipartite structure in gephi

I have constructed in python with networkx a bipartite network like this:
import networkx as nx
from random import choice
from string import ascii_lowercase, digits
# Define the characters to choose from
chars = ascii_lowercase + digits
# Create two separate lists of 100 random strings each
lst = [''.join(choice(chars) for _ in range(12)) for _ in range(100)]
lst1 = [''.join(choice(chars) for _ in range(12)) for _ in range(100)]
# Create node labels for each list
List1 = [city for city in lst]
List2 = [city for city in lst1]
# Create the graph object
G = nx.Graph()
# Add nodes to the graph with different bipartite indices
G.add_nodes_from(List1, bipartite=0)
G.add_nodes_from(List2, bipartite=1)
# Add edges connecting nodes from the two lists
for i in range(len(lst)):
G.add_edge(List1[i], List2[i])
# Save the graph to a file
nx.write_gexf(G, "bipartite_network.gexf")
and I want to export this in Gephi which results in the following database:
which does not give me a bipartite structure (i.e. two separate lists of node connected via edges, namely the list under id connected to the list under Label). What is the right input to give Gephi in order to obtain the desired outcome?
Thank you

construct a tree out of list of strings

I have 400 lists that look like that:
[A ,B, C,D,E]
[A, C, G, B, E]
[A,Z,B,D,E]
...
[A,B,R,D,E]
Each with length of 5 items that start with A.
I would like to construct a tree or directed acyclic graph (while with counts a weights ) where each level is the index of the item i.e A have edges with all possible items in the first index, they will have edge with child in the second index and so on.
is there an easy way to build in in networkx ? what i thought to do is to create all the tuples for each level i.e for level 0 : (A,B) ,(A,C) , (A,Z) etc .. but not sure how to move with it
If I understood you correctly, you can set each list as a path using nx.add_path of a directed graph.
l = [['A' ,'B', 'C','D','E'],
['A', 'C','G', 'B', 'E'],
['A','Z','B','D','E'],
['A','B','R','D','E']]
Though since you have nodes across multiple levels, you should probably rename them according to their level, since you cannot have multiple nodes with the same name. So one way could be:
l = [[f'{j}_level{lev}' for lev,j in enumerate(i, 1)] for i in l]
#[['A_level1', 'B_level2', 'C_level3', 'D_level4', 'E_level5'],
# ['A_level1', 'C_level2', 'G_level3', 'B_level4', 'E_level5'],
# ['A_level1', 'Z_level2', 'B_level3', 'D_level4', 'E_level5'],
# ['A_level1', 'B_level2', 'R_level3', 'D_level4', 'E_level5']]
And now construct the graph with: ​
G = nx.DiGraph()
for path in l:
nx.add_path(G, path)
Then you could create a tree-like structure using a graphviz's dot layout:
from networkx.drawing.nx_agraph import graphviz_layout
pos=graphviz_layout(G, prog='dot')
nx.draw(G, pos=pos,
node_color='lightgreen',
node_size=1500,
with_labels=True,
arrows=True)

Iteratively declare variables based on string?

Not sure if this has been asked before or not. Its a bit of an odd question, so I'll go ahead and fire away.
I've got some variable (or rather constant) definitions:
# Constants
# Colors
RED="RED"
ORANGE="ORANGE"
YELLOW="YELLOW"
GREEN="GREEN"
CYAN="CYAN"
BLUE="BLUE"
MAGENTA="MAGENTA"
# Modes
PANIC="PANIC"
SOLID="SOLID"
BREATHING="BREATHING"
# Special sub-modes (for panic)
BLINKING="BLINKING"
# Declare them
SOLID_RED="{}_{}".format(SOLID,RED)
SOLID_BLUE="{}_{}".format(SOLID,BLUE)
SOLID_MAGENTA="{}_{}".format(SOLID,MAGENTA)
## ..
BREATHING_RED="{}_{}".format(BREATHING,RED)
BREATHING_BLUE="{}_{}".format(BREATHING,BLUE)
BREATHING_MAGENTA="{}_{}".format(BREATHING,MAGENTA)
## ..
PANIC_RED="{}_{}".format(PANIC,RED)
PANIC_BLUE="{}_{}".format(PANIC,BLUE)
PANIC_MAGENTA="{}_{}".format(PANIC,MAGENTA)
## ..
PANIC_BLINKING="{}_{}".format(PANIC,BLINKING)
I got a lot of definitions! Instead of having to type them all out like this, would there be a way for me to just construct all these constants into existence as strings only using the definitions BEFORE # declare them , or by using, say, a dictionary?
The format I'd need for such a iterative construction is: MODE_COLOR naming convention.
I require that this answer works using Python 2.7. As I have some dependent 2.7 APIs included.
Another way using itertools.combinations and locals():
from itertools import combinations
from pprint import pprint
# Colors
RED="RED"
ORANGE="ORANGE"
YELLOW="YELLOW"
GREEN="GREEN"
CYAN="CYAN"
BLUE="BLUE"
MAGENTA="MAGENTA"
# Modes
PANIC="PANIC"
SOLID="SOLID"
BREATHING="BREATHING"
# Special sub-modes (for panic)
BLINKING="BLINKING"
v_consts = {k:v for k, v in locals().items() if k.isupper()}
combs = combinations(v_consts.values(), 2)
d_consts = {'%s_%s' % k: '%s_%s' % k for k in combs}
pprint(d_consts)
# Edit:
# If you want to add the created variables in Python's scope
# You can do something like this
globals().update(d_consts)
print SOLID_BLINKING, type(SOLID_BLINKING)
Output:
{'BLINKING_CYAN': 'BLINKING_CYAN',
'BLINKING_MAGENTA': 'BLINKING_MAGENTA',
'BLINKING_ORANGE': 'BLINKING_ORANGE',
'BLINKING_PANIC': 'BLINKING_PANIC',
'BLINKING_RED': 'BLINKING_RED',
...
'YELLOW_MAGENTA': 'YELLOW_MAGENTA',
'YELLOW_ORANGE': 'YELLOW_ORANGE',
'YELLOW_PANIC': 'YELLOW_PANIC',
'YELLOW_RED': 'YELLOW_RED'}
SOLID_BLINKING <type 'str'>
I would use a dictionary as the container to store the variables. Just list all of the colors and modes in lists, and then use a dictionary comprehension:
colors_list = ['red', 'blue']
modes_list = ['panic', 'solid']
color_modes = {k1 + '_' + k2: k1.upper() + '_' + k2.upper()
for k1 in colors_list for k2 in modes_list}
>>> color_modes
{'blue_panic': 'BLUE_PANIC',
'blue_solid': 'BLUE_SOLID',
'red_panic': 'RED_PANIC',
'red_solid': 'RED_SOLID'}
I think what you're trying to do is emitting a bit of a code smell.
The way I might approach this is by using a dictionary and a cross product. Here's a minified example:
from itertools import product
A = ['a', 'b', 'c']
B = ['d', 'e', 'f']
AB = {"{0} {1}".format(a, b): "{0}_{1}".format(a, b) for a, b in product(A, B)}
print(AB)
You can apply this to your colors and modifiers and access the colors by name:
colors['Magenta Solid']

create multiple ppt slides with python

I want to print the slides based on array list. But somehow I don't grasp the logic. My code right now is like this
totalSheets = [0, 1, 2]
totalSlides = ['slide', 'slide2', 'slide3']
prs = Presentation()
blank_slide_layout = prs.slide_layouts[6]
for sheet, slide in zip(totalSheets, totalSlides):
sheetExcel = excelFile.sheet_by_index(sheet)
slide = prs.slides.add_slide(blank_slide_layout)
I wrong at the slide one. I just thinking is it can doing like slide(n) and just do n += 1? Thanks for any help in advance
if you want to actually use random in the list, you can use this..
>>> import random
>>> totalSlides = ['slide', 'slide2', 'slide3']
>>> random.choice(totalSlides)
'slide3'
>>> random.choice(totalSlides)
'slide'
>>>
For mutiple on list, you can try this..
>>> import random
>>> totalSlides = ['slide', 'slide2', 'slide3']
>>> random.sample(totalSlides, len(totalSlides))
['slide2', 'slide3', 'slide']
>>> random.sample(totalSlides, len(totalSlides))
['slide3', 'slide', 'slide2']
>>> random.sample(totalSlides, len(totalSlides))
['slide2', 'slide', 'slide3']
>>> random.sample(totalSlides, len(totalSlides))
['slide3', 'slide2', 'slide']
>>>

AttributeError when trying to do a block partition with graph-tool

I am getting this error:
AttributeError: 'list' object has no attribute 'clear'
when trying to execute the example at this page
The example is:
>>> g = gt.collection.data["power"]
>>> bstack, mdl = gt.minimize_nested_blockmodel_dl(g, deg_corr=True)
>>> t = gt.get_hierarchy_tree(bstack)[0]
>>> tpos = pos = gt.radial_tree_layout(t, t.vertex(t.num_vertices() - 1), weighted=True)
>>> cts = gt.get_hierarchy_control_points(g, t, tpos)
>>> pos = g.own_property(tpos)
>>> b = bstack[0].vp["b"]
>>> gt.graph_draw(g, pos=pos, vertex_fill_color=b, vertex_shape=b, edge_control_points=cts,
... edge_color=[0, 0, 0, 0.3], vertex_anchor=0, output="power_nested_mdl.pdf")
<...>
and it gives me the exception when running the line:
>>> bstack, mdl = gt.minimize_nested_blockmodel_dl(g, deg_corr=True)
Any clue?
Thanks
list.clear() is not in Python 2, only in Python 3. The example runs without problem in Python 3.
Anyway, graph-tool is supposed to work on Python 2.7 and above, so this might as well be reported as a bug.

Categories

Resources