Node sizes based on degree change when degree does not

437 views
Skip to first unread message

Emily Levine

unread,
Jul 12, 2011, 10:33:45 AM7/12/11
to networkx-discuss
Hello-
I wrote two posts in June asking for some help with my SIR model using
networkx. I am using the same model but instead of generating a random
graph each run-through, I have input specific node and edge
information. I wish to size the nodes based on degree. This works in a
small program I wrote to test it. However, some of the nodes change
size every few time steps when I implement this in my SIR code. I
printed to make sure the degrees themselves were not changing, but I
am wondering if anyone has any suggestions as to what could be
changing the node size when degree isn't changing. I'm thinking it has
to do with the fact that I am using the infected, susceptible, and
recovered lists as the node lists (in order for the color to be
accurate), but I didn't think this would be a problem since the number
of nodes = the number of individuals.

Here is the relevant code (the graphing is towards the bottom in the
run function):

import networkx as nx
import matplotlib.pyplot as plt
import pylab as pl
import random
from random import choice
import copy
import scipy
import heapq

class SimpleNetworkSIRModel:
def __init__(self, b=0.2, g=0.01, S = 30, I = 1):

#parameters
self.b = b
self.g = g
self.t = 0
self.nodeList = range(38)
#self.N = self.nodeList

#initialize graph
self.graph = nx.DiGraph()
edgeList1 = [(0,9),(0,24),(0,27),(2,27),(6,5),
(6,8),(6,10),(6,15),(6,21),(6,27),
(6,31),(6,34),(6,36),(9,27),(14,2),
(14,13),(14,17),(14,27),(20,7),(20,9),
(20,10),(20,12),(20,14),(20,19),(20,24),
(20,29),(20,31),(20,34),(20,36),(24,20),
(24,35),(25,5),(25,11),(25,14),(25,16),
(25,21),(25,31),(26,16),(26,28),(28,16),
(28,24),(28,36),(31,4),(31,6),(31,13),
(13,15),(31,16),(31,23),(31,35),(32,1),
(32,18),(32,31),(35,8),(35,24),(35,30),
(35,31),(35,32),(35,36),(35,37)]

edgeList2 = [(0,12),(2,10),(2,20),(7,8),(7,14),
(9,0),(9,10),(9,12),(9,17),(9,19),
(9,34),(9,35),(12,3),(12,6),(12,17),
(12,19),(12,21),(12,24),(12,31),(12,32),
(12,35),(14,20),(18,0),(18,5),(18,9),
(18,12),(18,33),(19,0),(19,5),(19,7),
(19,9),(19,20),(19,31),(19,35),(22,1),
(22,9),(22,21),(23,21),(23,24),(23,28),
(23,32),(24,7),(24,21),(24,22),(24,23),
(24,25),(24,26),(24,31),(24,32),(24,33),
(32,11),(32,21),(35,21)]

edgeList3 = [(0,2),(0,3),(0,13),(0,17),(0,19),
(0,20),(0,34),(0,35),(2,0),(2,9),
(2,12),(2,13),(2,17),(2,19),(2,21),
(2,30),(2,34),(2,35),(6,18),(6,33),
(7,4),(7,11),(7,15),(7,25),(9,2),
(9,13),(11,4),(11,7),(11,14),(11,15),
(11,23),(12,0),(12,2),(12,9),(12,10),
(12,13),(12,20),(12,34),(14,4),(14,7),
(14,9),(14,11),(14,15),(14,18),(14,21),
(14,23),(14,24),(14,25),(14,30),(14,31),
(14,32),(18,2),(18,6),(18,10),(18,14),
(18,15),(18,23),(18,24),(18,30),(18,34),
(19,2),(19,3),(19,12),(19,13),(19,17),
(19,34),(20,2),(20,13),(20,21),(20,25),
(22,15),(22,23),(22,26),(22,28),(22,32),
(23,28),(23,22),(23,26),(23,31),(24,0),
(24,6),(24,9),(24,10),(24,12),(24,14),
(24,15),(24,18),(24,29),(24,30),(24,34),
(25,4),(25,7),(25,8),(25,15),(26,22),
(26,32),(28,22),(28,23),(28,26),(28,32),
(31,3),(31,14),(31,21),(32,22),(32,26),
(35,0),(35,2),(35,13),(35,16),(35,17),
(35,19),(35,20),(35,34)]
self.graph.add_edges_from(edgeList1, weight=1)
self.graph.add_edges_from(edgeList2, weight=2)
self.graph.add_edges_from(edgeList3, weight=3)

#store the indices of agents in each state
self.sAgentList = []
self.iAgentList = []
self.rAgentList = []

#store counts of how many agents in each state at each time
step
self.sList = []
self.iList = []
self.rList = []
self.newIList = []

#keep track of recovery times
self.recoveryTimesHeap = []

#make a list of agent indices (all labeled 0 - N)
#and shuffle so no accidental correlation in agent actions
allAgents = self.nodeList

random.shuffle(allAgents)
while allAgents[0] == 0:
random.shuffle(allAgents)
break

#everyone starts out susceptible:
self.sAgentList = copy.copy(allAgents)

#now, infect a few at t = 0
self.indexCases = []
for i in xrange(I):
indexCase = self.sAgentList[0]
self.indexCases.append(indexCase)
self.infectAgent(indexCase)
self.iAgentList.append(indexCase)

def infectAgent(self,agent):
self.sAgentList.remove(agent)
recoveryTime = self.t + scipy.random.exponential(1/self.g)
heapq.heappush(self.recoveryTimesHeap, (recoveryTime, agent))

return 1

def recoverAgents(self):
recoverList = []
if len(self.recoveryTimesHeap) > 0:
while self.recoveryTimesHeap[0][0] <= self.t:
recoveryTuple = heapq.heappop(self.recoveryTimesHeap)
recoverList.append(recoveryTuple[1])
if len(self.recoveryTimesHeap) == 0:
break
return recoverList

def run(self):
pos = nx.circular_layout(self.graph)
while len(self.iAgentList) > 0:
tempIAgentList = []
recoverList = []
newI = 0
for iAgent in self.iAgentList:
for agent in self.graph[iAgent]:
if agent in self.sAgentList:
if (random.random() < self.b):
newI += self.infectAgent(agent)
tempIAgentList.append(agent)
#get list of who is recovering
recoverList = self.recoverAgents()
#bookkeeping with agent indices:
#for recoveries
for recoverAgent in recoverList:
self.iAgentList.remove(recoverAgent)
self.rAgentList.append(recoverAgent)

#new infections
self.iAgentList.extend(tempIAgentList)

#track number of individs in each state
self.sList.append(len(self.sAgentList))
self.iList.append(len(self.iAgentList))
self.rList.append(len(self.rAgentList))
self.newIList.append(newI)

#print(nx.degree(self.graph).values())

plt.ion() #turn interactive mode on
nodes = set(self.graph)
self.graph.add_nodes_from(self.nodeList)
nodeSize=[(100*self.graph.degree(n)) for n in self.graph]
alphaValue = 0.75

i=0
plt.clf()
plt.axis('equal')
plt.axis('off')

#nx.draw(self.graph, pos = pos,
node_size=self.nodeSize,alpha=alphaValue)

nx.draw_networkx_nodes(self.graph,pos,nodelist=self.sAgentList,node_size
= nodeSize, node_color='b', alpha = alphaValue)

nx.draw_networkx_nodes(self.graph,pos,nodelist=self.iAgentList,node_size
= nodeSize, node_color='r', alpha = alphaValue)

nx.draw_networkx_nodes(self.graph,pos,nodelist=self.rAgentList,node_size
= nodeSize, node_color='c', alpha = alphaValue)

nx.draw_networkx_nodes(self.graph,pos,nodelist=self.indexCases,node_size
= nodeSize, node_color='g', alpha = alphaValue)
nx.draw_networkx_edges(self.graph,pos)
nx.draw_networkx_labels(self.graph,pos)
plt.show()


Thank you!
Emily Levine

Richard Careaga

unread,
Jul 12, 2011, 10:43:33 AM7/12/11
to networkx...@googlegroups.com
The example, toward the bottom needs to fix


            #nx.draw(self.graph, pos = pos,
node_size=self.nodeSize,alpha=alphaValue)

to run

by uncommenting and joining the line. Once I do that I'll see if I can help on the main question.



Emily Levine
July 12, 2011 10:33 AM

Emily Levine

unread,
Jul 12, 2011, 10:49:13 AM7/12/11
to networkx-discuss
That line draws the nodes with the correct size, but draws it
underneath a set of nodes changing in size and color based on which
list they are from. So, by drawing the graph on its own and then
drawing the nodes separately to use different colors, I'll get two
sets of nodes.

On Jul 12, 10:43 am, Richard Careaga <leuc...@gmail.com> wrote:
> The example, toward the bottom needs to fix
>
>              #nx.draw(self.graph, pos = pos,
> node_size=self.nodeSize,alpha=alphaValue)
>
> to run
>
> by uncommenting and joining the line. Once I do that I'll see if I can
> help on the main question.
>
> > ------------------------------------------------------------------------
>
> >    Emily Levine <mailto:eslevine...@gmail.com>

Moritz Beber

unread,
Jul 12, 2011, 10:58:45 AM7/12/11
to networkx...@googlegroups.com

> random.shuffle(allAgents)
> while allAgents[0] == 0:
> random.shuffle(allAgents)
> break
>
This loop always breaks on the first pass, maybe not what you intended.
You should rely on the shuffling to randomly shuffle your list, even
though the first index may not have changed.
> nodes = set(self.graph)
> self.graph.add_nodes_from(self.nodeList)
I don't see the point of re-adding the nodes here but maybe I missed
something.

> nodeSize=[(100*self.graph.degree(n)) for n in self.graph]
> alphaValue = 0.75
>
>
> nx.draw_networkx_nodes(self.graph,pos,nodelist=self.sAgentList,node_size
> = nodeSize, node_color='b', alpha = alphaValue)
>
> nx.draw_networkx_nodes(self.graph,pos,nodelist=self.iAgentList,node_size
> = nodeSize, node_color='r', alpha = alphaValue)
>
> nx.draw_networkx_nodes(self.graph,pos,nodelist=self.rAgentList,node_size
> = nodeSize, node_color='c', alpha = alphaValue)
>
> nx.draw_networkx_nodes(self.graph,pos,nodelist=self.indexCases,node_size
> = nodeSize, node_color='g', alpha = alphaValue)
> nx.draw_networkx_edges(self.graph,pos)
> nx.draw_networkx_labels(self.graph,pos)
> plt.show()
>
Your problem is that you have one list over all nodes with their sizes,
i.e., nodeSize but separate shorter lists for the agents themselves. So
when you supply the parameters nodelist= and node_size= the function
draw_networkx_nodes will always use the first entries of nodeSize up to
the length of the corresponding agent list, and not as you probably want
it the size of the corresponding index. I guess you'll have to construct
separate size lists as well. Maybe you can also draw the network once
with the proper sizes for all nodes and then only update the colour
afterwards for the groups of agents.

Moritz

Richard Careaga

unread,
Jul 12, 2011, 11:01:23 AM7/12/11
to networkx...@googlegroups.com
Sorry to be dense. In the example, is it your intent to comment out the entire line then?



Emily Levine
July 12, 2011 10:49 AM

That line draws the nodes with the correct size, but draws it
underneath a set of nodes changing in size and color based on which
list they are from. So, by drawing the graph on its own and then
drawing the nodes separately to use different colors, I'll get two
sets of nodes.



Richard Careaga
July 12, 2011 10:43 AM

The example, toward the bottom needs to fix

            #nx.draw(self.graph, pos = pos,
node_size=self.nodeSize,alpha=alphaValue)

to run

by uncommenting and joining the line. Once I do that I'll see if I can help on the main question.

Emily Levine

unread,
Jul 12, 2011, 11:49:11 AM7/12/11
to networkx-discuss
Richard -No problem at all, any help is good help. Yes, I meant to
comment out that line...I wanted to keep it in case I used it again.
Mortiz- Thank you for your advice, I will try it out


On Jul 12, 11:01 am, Richard Careaga <leuc...@gmail.com> wrote:
> Sorry to be dense. In the example, is it your intent to comment out the
> entire line then?
>
> > ------------------------------------------------------------------------
>
> >    Emily Levine <mailto:eslevine...@gmail.com>
> > July 12, 2011 10:49 AM
>
> > That line draws the nodes with the correct size, but draws it
> > underneath a set of nodes changing in size and color based on which
> > list they are from. So, by drawing the graph on its own and then
> > drawing the nodes separately to use different colors, I'll get two
> > sets of nodes.
>
> > ------------------------------------------------------------------------
>
> >    Richard Careaga <mailto:leuc...@gmail.com>
> > July 12, 2011 10:43 AM
>
> > The example, toward the bottom needs to fix
>
> >             #nx.draw(self.graph, pos = pos,
> > node_size=self.nodeSize,alpha=alphaValue)
>
> > to run
>
> > by uncommenting and joining the line. Once I do that I'll see if I can
> > help on the main question.
>
> > ------------------------------------------------------------------------
>
> >    Emily Levine <mailto:eslevine...@gmail.com>

Richard Careaga

unread,
Jul 12, 2011, 1:10:33 PM7/12/11
to networkx...@googlegroups.com
From the docs for nx.draw_networkx_nodes: "If an array is specified it must be the same length as nodelist. "

The argument nodeSize is based on the number of nodes in the entire graph:


nodeSize=[(100*self.graph.degree(n)) for n in self.graph]

but the argument needs to be same as the number of nodes in each of the four cases:


nx.draw_networkx_nodes(self.graph,pos,nodelist=self.sAgentList,node_size = nodeSize, node_color='b', alpha = alphaValue)
nx.draw_networkx_nodes(self.graph,pos,nodelist=self.iAgentList,node_size = nodeSize, node_color='r', alpha = alphaValue)
nx.draw_networkx_nodes(self.graph,pos,nodelist=self.rAgentList,node_size = nodeSize, node_color='c', alpha = alphaValue)
nx.draw_networkx_nodes(self.graph,pos,nodelist=self.indexCases,node_size = nodeSize, node_color='g', alpha = alphaValue)





Emily Levine
July 12, 2011 11:49 AM

Richard -No problem at all, any help is good help. Yes, I meant to
comment out that line...I wanted to keep it in case I used it again.
Mortiz- Thank you for your advice, I will try it out



July 12, 2011 10:49 AM

That line draws the nodes with the correct size, but draws it
underneath a set of nodes changing in size and color based on which
list they are from. So, by drawing the graph on its own and then
drawing the nodes separately to use different colors, I'll get two
sets of nodes.


July 12, 2011 10:43 AM

The example, toward the bottom needs to fix

            #nx.draw(self.graph, pos = pos,
node_size=self.nodeSize,alpha=alphaValue)

to run

by uncommenting and joining the line. Once I do that I'll see if I can help on the main question.

Emily Levine

unread,
Jul 12, 2011, 1:37:34 PM7/12/11
to networkx-discuss
Thank you both for your helpful suggestions!

On Jul 12, 1:10 pm, Richard Careaga <leuc...@gmail.com> wrote:
>  From the docs for nx.draw_networkx_nodes: "If an array is specified it
> must be the same length as nodelist. "
>
> The argument nodeSize is based on the number of nodes in the entire graph:
>
> nodeSize=[(100*self.graph.degree(n)) for n in self.graph]
>
> but the argument needs to be same as the number of nodes in each of the
> four cases:
>
> nx.draw_networkx_nodes(self.graph,pos,nodelist=self.sAgentList,node_size
> = nodeSize, node_color='b', alpha = alphaValue)
> nx.draw_networkx_nodes(self.graph,pos,nodelist=self.iAgentList,node_size
> = nodeSize, node_color='r', alpha = alphaValue)
> nx.draw_networkx_nodes(self.graph,pos,nodelist=self.rAgentList,node_size
> = nodeSize, node_color='c', alpha = alphaValue)
> nx.draw_networkx_nodes(self.graph,pos,nodelist=self.indexCases,node_size
> = nodeSize, node_color='g', alpha = alphaValue)
>
> > ------------------------------------------------------------------------
>
> >    Emily Levine <mailto:eslevine...@gmail.com>
> > July 12, 2011 11:49 AM
>
> > Richard -No problem at all, any help is good help. Yes, I meant to
> > comment out that line...I wanted to keep it in case I used it again.
> > Mortiz- Thank you for your advice, I will try it out
>
> > ------------------------------------------------------------------------
>
> >    Emily Levine <mailto:eslevine...@gmail.com>
> > July 12, 2011 10:49 AM
>
> > That line draws the nodes with the correct size, but draws it
> > underneath a set of nodes changing in size and color based on which
> > list they are from. So, by drawing the graph on its own and then
> > drawing the nodes separately to use different colors, I'll get two
> > sets of nodes.
>
> > ------------------------------------------------------------------------
>
> >    Richard Careaga <mailto:leuc...@gmail.com>
> > July 12, 2011 10:43 AM
>
> > The example, toward the bottom needs to fix
>
> >             #nx.draw(self.graph, pos = pos,
> > node_size=self.nodeSize,alpha=alphaValue)
>
> > to run
>
> > by uncommenting and joining the line. Once I do that I'll see if I can
> > help on the main question.
>
> > ------------------------------------------------------------------------
>
> >    Emily Levine <mailto:eslevine...@gmail.com>
Reply all
Reply to author
Forward
0 new messages