python networkX: Making graph from tuples and assigning different colour for nodes - tuples

new = (('AXIN', 37, REPORTED),
('LGR', 34, REPORTED),
('NKD', 29, REPORTED),
('TNFRSF', 23, REPORTED),
('APCDD', 18, REPORTED),
('TOX', 15, UNREPORTED),
('LEF', 14, REPORTED),
('PLCB', 13, REPORTED),
('MME', 13, UNREPORTED),
('NOTUM', 13,UN REPORTED),
('GNG', 11, , REPORTED),
('LOXL', 10, UNREPORTED))
import matplotlib.pyplot as plt
import networkx as nx
children = sorted(new, key=lambda x: x[1])
parent = children.pop()[0]
G = nx.Graph()
for child, weight in children: G.add_edge(parent, child, weight=weight)
width = list(nx.get_edge_attributes(G, 'weight').values())
plt.savefig("plt.gene-expression.pdf")
plt.figure(figsize = (20, 10))
nx.draw_networkx(G, font_size=10, node_size=2000, alpha=0.6) #width=width is very fat lines
plt.savefig("gene-expression-graph.pdf")
In this nx graph, how can I make the UNREPORTED - green color, REPORTED-yellow color?
Parent node is the node with the largest number i.e., AXIN, 37

colors = []
for i in new:
if i[2] == 'UNREPORTED':
colors.append('green')
elif i[2] == 'REPORTED':
colors.append('yellow')
nx.draw_networkx(G, font_size=10, node_size=2000, alpha=0.6, node_color=colors)

The mismatch in ordering comes from the dictionaries that underlie networkx's graph representation. If you ensure that the list of colors is ordered the same way you will have the right color for the right node.
I've written two different approaches here that achieve what I think you want.
Note: I declared values for reported and unreported, rather than turning the third piece of every tuple into a string. But this part isn't essential
# Delcare the graph:
REPORTED = 1
UNREPORTED = 2
new = (('AXIN', 37, REPORTED),
('LGR', 34, REPORTED),
<...>
('LOXL', 10, UNREPORTED))
# 2 axes to show different approaches
plt.figure(1); plt.clf()
fig, ax = plt.subplots(1, 2, num=1, sharex=True, sharey=True)
### option 1: draw components step-by-step
# positions for drawing of all components in right place
pos = nx.spring_layout(G)
# identify which nodes are reported/unreported
nl_r = [name for (name, w, state) in new if state == REPORTED]
nl_u = [name for (name, w, state) in new if state == UNREPORTED]
# draw each subset of nodes in relevant color
nx.draw_networkx_nodes(G, pos=pos, nodelist=nl_r, node_color='g', nodesize=2000, ax=ax[0])
nx.draw_networkx_nodes(G, pos=pos, nodelist=nl_u, node_color='y', nodesize=2000, ax=ax[0])
# also need to draw the egdes
nx.draw_networkx_edges(G, pos=pos, ax=ax[0])
nx.draw_networkx_labels(G, pos=pos, ax=ax[0], font_size=10)
### option 2: more complex color list construction (but simpler plot command)
nl, cl = zip(*[(name, 'g') if state == REPORTED else (name, 'y') for (name, w, state) in new])
nx.draw_networkx(G, pos=pos, nodelist=nl, node_color=cl, nodesize=2000, ax=ax[1], font_size=10)
plt.show()

Related

Create a dictionary in a loop

I have 2 lists that I want to convert them into a dict with key and values. I managed to do so but there are too many steps so I would like to know if there's a simpler way of achieving this. Basically I would like to create the dict directly in the loop without having the extra steps bellow. I just started working with python and I don't quite understand all the datatypes that it provides.
The jName form can be modified if needed.
jName=["Nose", "Neck", "RShoulder", "RElbow", "RWrist", "LShoulder", "LElbow", "LWrist", "RHip",
"RKnee","RAnkle","LHip", "LKnee", "LAnkle", "REye", "LEye", "REar", "LEar"]
def get_joints(subset, candidate):
joints_per_skeleton = [[] for i in range(len(subset))]
# for each detected skeleton
for n in range(len(subset)):
# for each joint
for i in range(18):
cidx = subset[n][i]
if cidx != -1:
y = candidate[cidx.astype(int), 0]
x = candidate[cidx.astype(int), 1]
joints_per_skeleton[n].append((y, x))
else:
joints_per_skeleton[n].append(None)
return joints_per_skeleton
joints = get_joints(subset,candidate)
print joints
Here is the output of the joints list of list
[[None, (48.0, 52.0), (72.0, 50.0), None, None, (24.0, 55.0), (5.0, 105.0), None, (63.0, 159.0), (57.0, 221.0), (55.0, 281.0), (28.0, 154.0), (23.0, 219.0), (23.0, 285.0), None, (25.0, 17.0), (55.0, 18.0), (30.0, 21.0)]]
Here I defined a function to create the dictionary from the 2 lists
def create_dict(keys, values):
return dict(zip(keys, values))
my_dict = create_dict(jointsName, joints[0])
Here is the result:
{'LAnkle': (23.0, 285.0),
'LEar': (30.0, 21.0),
'LElbow': (5.0, 105.0),
'LEye': (25.0, 17.0),
'LHip': (28.0, 154.0),
'LKnee': (23.0, 219.0),
'LShoulder': (24.0, 55.0),
'LWrist': None,
'Neck': (48.0, 52.0),
'Nose': None,
'RAnkle': (55.0, 281.0),
'REar': (55.0, 18.0),
'RElbow': None,
'REye': None,
'RHip': (63.0, 159.0),
'RKnee': (57.0, 221.0),
'RShoulder': (72.0, 50.0),
'RWrist': None}
I think defaultdict could help you. I made my own example to show that you could predefine the keys and then go through a double for loop and have the values of the dict be lists of potentially different sizes. Please let me know if this answers your question:
from collections import defaultdict
import random
joint_names = ['hip','knee','wrist']
num_skeletons = 10
d = defaultdict(list)
for skeleton in range(num_skeletons):
for joint_name in joint_names:
r1 = random.randint(0,10)
r2 = random.randint(0,10)
if r1 > 4:
d[joint_name].append(r1*r2)
print d
Output:
defaultdict(<type 'list'>, {'hip': [0, 5, 30, 36, 56], 'knee': [35, 50, 10], 'wrist': [27, 5, 15, 64, 30]})
As a note I found it very difficult to read through your code since there were some variables that were defined before the snippet you posted.

Adding outputs of two layers in keras

I have an issue that seems to have no straight forward solution in Keras.
My server runs on ubuntu 14.04, keras with backend tensorflow.
Here's the issue:
I have two input tenors of the shape: Input(shape=(30,125,1)), each of them is fed to a cascade of three layers below:
CNN1 = Conv2D(filters = 8, kernel_size = (1,64) , padding = "same" , activation = "relu" )
CNN2 = Conv2D(filters = 8, kernel_size = (8,1) , padding = "same" , activation = "relu" )
pool = MaxPooling2D((2, 2))
Each of the obtained output tensors for respective inputs is of shape (None, 15, 62, 8). Now, I wish to add each of the (15,62) matrix for both inputs for each filter and get an output of dimension again (None, 15, 62, 8).
I tried with the following lines of code using Lambda layer but it throws an error.
from keras import backend as K
from keras.layers import Lambda
def myadd(x):
increment = x[1]
result = K.update_add(x[0], increment)
return result
in_1 = Input(shape=(30,125,1))
in_1CNN1 = CNN1(in_1)
in_1CNN2 = CNN2(in_1CNN1)
in_1pool = pool(in_1CNN2)
in_2 = Input(shape=(30,125,1))
in_2CNN1 = CNN1(in_2)
in_2CNN2 = CNN2(in_2CNN1)
in_2pool = pool(in_2CNN2)
y1 =y1.astype(np.float32) # an input regression label array of shape (numsamples,1) loaded from a mat file
out1 = Lambda(myadd, output_shape=(None, 15, 62, 8))([in_1pool,in_2pool])
a= keras.layers.Flatten()(out1)
pre1 = Dense(1000, activation='sigmoid')(a)
pre2 =Dropout(0.2)(pre1)
predictions = Dense(1, activation='sigmoid')(pre2)
model = Model(inputs=[in_1,in_2], outputs=predictions)
model.compile(optimizer='sgd',loss='mean_squared_error')
model.fit([inputdata1,inputdata2], y1, epochs=20, validation_split=0.5)
#inputdata1, inputdata2 are arrays loaded from a mat file and are each of shape (5169, 30, 125, 1)
The error is highlighted below:
Traceback (most recent call last):
File "keras_workshop/keras_multipleinputs_multiple CNN.py", line 225, in <module>
out1 = Lambda(myadd, output_shape=(None, 15, 62, 8))([in_1pool,in_2pool])
File "/home/tharun/anaconda2/lib/python2.7/site-packages/keras/engine/topology.py", line 603, in __call__
output = self.call(inputs, **kwargs)
File "/home/tharun/anaconda2/lib/python2.7/site-packages/keras/layers/core.py", line 651, in call
return self.function(inputs, **arguments)
File "keras_workshop/keras_multipleinputs_multiple CNN.py", line 75, in myadd
result = K.update_add(x[0], increment)
File "/home/tharun/anaconda2/lib/python2.7/site-packages/keras/backend/tensorflow_backend.py", line 958, in update_add
return tf.assign_add(x, increment)
File "/home/tharun/anaconda2/lib/python2.7/site-packages/tensorflow/python/ops/state_ops.py", line 245, in assign_add
return ref.assign_add(value)
AttributeError: 'Tensor' object has no attribute 'assign_add'
Try the Add() layer or the add() function that Keras provides.
Add
keras.layers.Add()
Layer that adds a list of inputs.
It takes as input a list of tensors, all of the same shape, and returns a single tensor (also of the same shape).
add
keras.layers.add(inputs)
Functional interface to the Add layer.
Arguments
inputs: A list of input tensors (at least 2).
**kwargs: Standard layer keyword arguments.
Returns
A tensor, the sum of the inputs.

Force ylim range in subgraph

When plotting a serie of subgraphs with matplotlib, I can't set the ylim range properly.
Here's part of the code:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
(...) # loading npy data
titles = ["basestr1", "basestr2", "basestr3", "basestr4", "basestr5"]
labels = ["baselab1", "baselab2", "baselab3", "baselab4", "baselab5"]
linew = 2.24
ms = 10
mw = 2
fc = (1,1,1)
bc = (1,1,1)
mpl.rcParams['axes.prop_cycle'] = mpl.cycler(color=[(1,0.4,0.4), (0.1,0.6,0.1), (0.04,0.2,0.04)])
mpl.rcParams.update({'font.size': 12})
fig2 = plt.subplots(2, 2, figsize=(12,9), facecolor=fc)
plt.rc('font', family='serif')
ax0 = plt.subplot(221)
ax1 = plt.subplot(222)
ax2 = plt.subplot(223)
ax3 = plt.subplot(224)
axl = [ax0, ax1, ax2, ax3]
em = []
fp = []
fn = []
gm = []
for c,element in enumerate(elements):
em.append([i[0] for i in element])
fp.append([i[1][1] if 1 in i[1] else 0 for i in element]) # red
fn.append([i[1][2] if 2 in i[1] else 0 for i in element]) # light green
gm.append([i[1][3] if 3 in i[1] else 0 for i in element]) # dark green
axl[c].semilogy(em[c], fp[c], "-x", lw=linew, markersize=ms, mew=mw) # red
axl[c].semilogy(em[c], fn[c], "-x", lw=linew, markersize=ms, mew=mw) # light green
axl[c].semilogy(em[c], gm[c], "-o", lw=linew, markersize=ms, mew=mw, mfc='None') # dark green
axl[c].set_ylim([-10, 200]) # <-- Here's the issue; it seems not to work properly.
axl[c].grid(True,which="both")
axl[c].set_title(titles[c])
axl[c].set_xlabel(labels[c])
axl[c].set_ylabel(r'Count')
plt.legend(['False', 'True', 'Others'], loc=3, bbox_to_anchor=(.62, 0.4), borderaxespad=0.)
plt.tight_layout(pad=0.4, w_pad=0.5, h_pad=1.0)
plt.savefig('/home/username/Desktop/figure.png',
facecolor=fig2.get_facecolor(),edgecolor='w',orientation='landscape',papertype=None,
format=None, transparent=False, bbox_inches=None, pad_inches=0.1,
frameon=None)
plt.show() # block=False
Where elements is a list containing 4 arrays.
Each of these array looks like:
elements[0]
Out[16]:
array([[1, {0.0: 1252, 1.0: 11, 2.0: 170, 3.0: 11}],
[2, {0.0: 1251, 1.0: 12, 2.0: 163, 3.0: 18}],
[3, {0.0: 1229, 1.0: 34, 2.0: 148, 3.0: 33}],
...,
[6, {0.0: 1164, 1.0: 99, 2.0: 125, 3.0: 56}],
[7, {0.0: 1111, 1.0: 152, 2.0: 105, 3.0: 76}],
[8, {0.0: 1056, 1.0: 207, 2.0: 81, 3.0: 100}]], dtype=object)
Where am I wrong?
I can set any values I want in axl[c].set_ylim([-10, 200]) it doesn't change anything on the output graph.
Update:
Ok, it seems not possible to set other value as 1 as starting y-axis value here.

AttributeError: draw_artist can only be used after an initial draw which caches the render

My requirement is to plot the data in polar graph. However I need to keep polar graph in particular angle to looks like "V" shape and data need to plotted in between the particular angle.
In python I don't find a solution to keep the polar graph in particular angle, Example : Graph should be display in between -60 to 60 degree radius. To achieve that I have looked into couple of existing examples and creating required polar graph with FloatingSubplot functions. However I am hitting the issue , when we try to use along with function animation function with blit=True. Error message is displayed is "AttributeError: draw_artist can only be used after an initial draw which caches the render"
Here is my code.
#
import matplotlib
matplotlib.use('Qt4Agg')
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import style
import matplotlib.animation as animation
import mpl_toolkits.axisartist.floating_axes as floating_axes
from matplotlib.transforms import Affine2D
from matplotlib.projections import PolarAxes
from mpl_toolkits.axisartist import angle_helper
from mpl_toolkits.axisartist.grid_finder import MaxNLocator, DictFormatter
from mpl_toolkits.axisartist.floating_axes import GridHelperCurveLinear, FloatingSubplot
plt.close('all')
fig = plt.figure('Practice', dpi=100) # To set the fig title as pratice
ax1 = fig.add_subplot(2, 2, 1) # subplot for 1st plot
plt.ion()
ax1.grid(True)
def fractional_polar_axes(f, thlim=(0, 120), rlim=(0, 20), step=(30, 0.25),
thlabel='theta', rlabel='r', ticklabels=True, theta_offset=0, rlabels=None):
'''Return polar axes that adhere to desired theta (in deg) and r limits. steps for theta
and r are really just hints for the locators.'''
th0, th1 = thlim # deg
r0, r1 = rlim
thstep, rstep = step
tr_rotate = Affine2D().translate(theta_offset, 0)
# scale degrees to radians:
tr_scale = Affine2D().scale(np.pi / 180., 1.)
# pa = axes(polar="true") # Create a polar axis
pa = PolarAxes
tr = tr_rotate + tr_scale + pa.PolarTransform()
theta_grid_locator = angle_helper.LocatorDMS((th1 - th0) // thstep)
r_grid_locator = MaxNLocator((r1 - r0) // rstep)
theta_tick_formatter = angle_helper.FormatterDMS()
if rlabels:
rlabels = DictFormatter(rlabels)
grid_helper = GridHelperCurveLinear(tr,
extremes=(th0, th1, r0, r1),
grid_locator1=theta_grid_locator,
grid_locator2=r_grid_locator,
tick_formatter1=theta_tick_formatter,
tick_formatter2=rlabels)
a = FloatingSubplot(f, 222, grid_helper=grid_helper)
# a = Subplot(f,753, grid_helper=grid_helper)
# f.add_subplot(7,5,(3,34))
f.add_subplot(a)
# adjust x axis (theta):
print(a)
a.axis["bottom"].set_visible(False)
a.axis["top"].set_axis_direction("bottom") # tick direction
a.axis["top"].toggle(ticklabels=ticklabels, label=bool(thlabel))
a.axis["top"].major_ticklabels.set_axis_direction("top")
a.axis["top"].label.set_axis_direction("top")
a.axis["top"].major_ticklabels.set_pad(10)
# adjust y axis (r):
a.axis["left"].set_axis_direction("bottom") # tick direction
a.axis["right"].set_axis_direction("top") # tick direction
a.axis["left"].toggle(ticklabels=True, label=bool(rlabel))
# add labels:
a.axis["top"].label.set_text(thlabel)
a.axis["left"].label.set_text(rlabel)
# create a parasite axes whose transData is theta, r:
auxa = a.get_aux_axes(tr)
print(auxa)
# make aux_ax to have a clip path as in a?:
auxa.patch = a.patch
# this has a side effect that the patch is drawn twice, and possibly over some other
# artists. So, we decrease the zorder a bit to prevent this:
a.patch.zorder = -2
# add sector lines for both dimensions:
thticks = grid_helper.grid_info['lon_info'][0]
rticks = grid_helper.grid_info['lat_info'][0]
print(grid_helper.grid_info['lat_info'])
for th in thticks[1:-1]: # all but the first and last
auxa.plot([th, th], [r0, r1], ':', c='grey', zorder=-1, lw=0.5)
for ri, r in enumerate(rticks):
# plot first r line as axes border in solid black only if it isn't at r=0
if ri == 0 and r != 0:
ls, lw, color = 'solid', 1, 'black'
else:
ls, lw, color = 'dashed', 0.5, 'grey'
# From http://stackoverflow.com/a/19828753/2020363
auxa.add_artist(plt.Circle([0, 0], radius=r, ls=ls, lw=lw, color=color, fill=False,
transform=auxa.transData._b, zorder=-1))
return auxa
def animate(i):
global loopcount, th, r
th = th+.1
r = r+.1
datapoints.set_offsets(np.vstack((th,r)).T)
#print("in animate")
return datapoints,
if __name__ == '__main__':
r_locs = [0,5,10, 15, 20]
r_labels = ['0', '5', '10', '15', '20']
r_ticks = {loc: label for loc, label in zip(r_locs, r_labels)}
a1 = fractional_polar_axes(fig, thlim=(-60, 60), step=(20, 5),
theta_offset=90, rlabels=r_ticks)
th= 20
r=10
a1.scatter(th,r , c = 'r', alpha = 0.5, linewidths = '.2', s = 20) # plotting the line at thetha 20 and radius 10
datapoints = a1.scatter([], [], c='b', alpha = 0.5, linewidths = '.2', s = 20) # creating scatter line with given instruction,
ani = animation.FuncAnimation(fig, animate, frames=30, interval=20, blit=True)
plt.show(block=True)
#
"""
Above code is working perfectly fine with blit=False and also same solution working fine with line and scatter plotting in normal graph.
Please someone help me to resolve the issue.
"""

Getting a specific value from a tuple within a list

I have a list like this
tails = {(1, 352, 368), (2, 336, 368), (3, 320, 368)}
where the first value is the tail number, the second is its x position and the third is its y position. Later on in my code, I have
for item in tail:
pygame.draw.rect(windowSurface, RED, (xposition, yposition, 16, 16))
How do I get the second and third value from that specific tuple?
Since you're looking to learn python basics, I'll show several different ways to do this (despite of python's "There should be one-- and preferably only one --obvious way to do it"):
for item in tails:
xposition = item[1] # get item by index
yposition = item[2]
pygame.draw.rect(windowSurface, RED, (xposition, yposition, 16, 16))
or
for item in tails:
( xposition, yposition ) = item[1:] # tuple assignment
pygame.draw.rect(windowSurface, RED, (xposition, yposition, 16, 16))
or
for tail_num, xposition, yposition in tails: # tuple assignment in for-loop
pygame.draw.rect(windowSurface, RED, (xposition, yposition, 16, 16))
or
# prepare args using list comprehension
rect_args_list = [ tuple(item[1:]) + ( 16, 16) for item in tails ]
for rect_args in rect_args_list:
pygame.draw.rect(windowSurface, RED, rect_args)