Esempio n. 1
0
	def layout(node):
		#print(node)
		if node.is_leaf():
			if node.name in x_file_names:
				#make reconstructed bubble
				size = x[x_file_names.index(node.name)]
				F = CircleFace(radius=500*math.sqrt(size), color="RoyalBlue", style="sphere")
				F.border.width = None
				F.opacity = 0.6
				faces.add_face_to_node(F,node, 0, position="branch-right")
				if taxonomic_names_on_leaves:
					nameFace = AttrFace("name", fsize=25, fgcolor='black',text_suffix="_"+taxonomy[x_file_names.index(node.name)])
					faces.add_face_to_node(nameFace, node, 0, position="branch-right")
				else:
					nameFace = AttrFace("name", fsize=25, fgcolor='black')
					faces.add_face_to_node(nameFace, node, 0, position="branch-right")
		elif node.name in hyp_node_names: #Otherwise it's a hypothetical node, just use recon x
			node_base_name = hyp_node_names[node.name][0]
			percent = hyp_node_names[node.name][1]
			if node_base_name in x_file_names:
				idx = hyp_node_names[node.name][2]
				size = x[x_file_names.index(node_base_name)+(idx+1)*len(x_file_names)]
				F = CircleFace(radius=500*math.sqrt(size), color="RoyalBlue", style="sphere")
				F.border.width = None
				F.opacity = 0.6
				faces.add_face_to_node(F,node, 0, position="branch-right")
				#print node
				#print size
			else:
				size=0
		else:
			size=0
Esempio n. 2
0
	def layout(node):
		node_style = NodeStyle()
		node_style["hz_line_width"] = 10
		node_style["vt_line_width"] = 10
		node.set_style(node_style)
		#print(node)
		if node.is_leaf():
			if node.name in org_names:
				#make reconstructed bubble
				size = x[org_names.index(node.name)]
				F = CircleFace(radius=size_factor*math.sqrt(size), color="RoyalBlue", style="sphere")
				F.border.width = None
				F.opacity = 0.6
				faces.add_face_to_node(F,node, 0, position="branch-right")
				#Denote that this was a training organism
				nameFace = AttrFace("name", fsize=font_size, fgcolor='black')
				faces.add_face_to_node(nameFace, node, 0, position="branch-right")
		elif node.name in hyp_node_names: #Otherwise it's a hypothetical node, just use recon x
			node_base_name = hyp_node_names[node.name][0]
			percent = hyp_node_names[node.name][1]
			if node_base_name in org_names:
				idx = hyp_node_names[node.name][2]
				size = x[org_names.index(node_base_name)+(idx+1)*len(org_names)]
				F = CircleFace(radius=size_factor*math.sqrt(size), color="RoyalBlue", style="sphere")
				F.border.width = None
				F.opacity = 0.6
				faces.add_face_to_node(F,node, 0, position="branch-right")
				#This is if I want the names of the hypothetical nodes to be printed as well
				#nameFace = AttrFace("name", fsize=font_size, fgcolor='black')
				#faces.add_face_to_node(nameFace, node, 0, position="branch-right")
			else:
				size=0
		else:
			size=0
Esempio n. 3
0
 def layout(node):
     #print(node)
     if node.is_leaf():
         if node.name in x_file_names:
             #make reconstructed bubble
             size = x[x_file_names.index(node.name)]
             F = CircleFace(radius=500 * math.sqrt(size),
                            color="RoyalBlue",
                            style="sphere")
             F.border.width = None
             F.opacity = 0.6
             faces.add_face_to_node(F, node, 0, position="branch-right")
             if taxonomic_names_on_leaves:
                 nameFace = AttrFace(
                     "name",
                     fsize=25,
                     fgcolor='black',
                     text_suffix="_" +
                     taxonomy[x_file_names.index(node.name)])
                 faces.add_face_to_node(nameFace,
                                        node,
                                        0,
                                        position="branch-right")
             else:
                 nameFace = AttrFace("name", fsize=25, fgcolor='black')
                 faces.add_face_to_node(nameFace,
                                        node,
                                        0,
                                        position="branch-right")
     elif node.name in hyp_node_names:  #Otherwise it's a hypothetical node, just use recon x
         node_base_name = hyp_node_names[node.name][0]
         percent = hyp_node_names[node.name][1]
         if node_base_name in x_file_names:
             idx = hyp_node_names[node.name][2]
             size = x[x_file_names.index(node_base_name) +
                      (idx + 1) * len(x_file_names)]
             F = CircleFace(radius=500 * math.sqrt(size),
                            color="RoyalBlue",
                            style="sphere")
             F.border.width = None
             F.opacity = 0.6
             faces.add_face_to_node(F, node, 0, position="branch-right")
             #print node
             #print size
         else:
             size = 0
     else:
         size = 0
Esempio n. 4
0
def makeSupportSymbols(node, secondary_support):
    #function to make circle with size scaled to base support value and color of circle scaled to the level of the second support value
    opacity = 0.01
    # Let's make the sphere transparent 
    if secondary_support == None:
        circle_color = "Grey"
        opacity = 1.0
        factor = 6
    elif secondary_support >=95.0:
        circle_color = "Black"
        opacity = 1.0
        factor = 10
    elif secondary_support >=70.0:
        circle_color = "Black"
        opacity = 1.0
        factor = 8
    elif secondary_support <70.0:
        circle_color = "Black"
        opacity = 1.0
        factor = 6
    else:
        print "secondary value unexpected: {}".format(secondary_support())
        circle_color = "Red"
        opacity = 1.0
    #circle_color = "#33343E" #a black from the pomacanthus drawing
    #print "color is {}, bootstrap is {}, opacity is {}".format(color, secondary_support, opacity)
    support_face = CircleFace(radius=node.support * factor, color=circle_color, style="circle")    
    support_face.opacity = opacity
    faces.add_face_to_node(support_face, node, 0, position="float-behind")
Esempio n. 5
0
def layout(node):
    if node.is_leaf():

        #######################################################
        #~ Taxon Label Size and Margin Adjustment
        N = AttrFace("name", fsize=1200, fgcolor="#000000")
        N.margin_top = 250
        N.margin_right = 100  #outside
        N.margin_left = 1000  #inside
        N.margin_bottom = 250
        #######################################################

        #######################################################
        #~ Taxon Label Background Color Setting
        tmp = "<myTaxaonLabel>"
        #~ if not(node.name.find(tmp)) : N.background.color="#FF9999"
        #######################################################

        faces.add_face_to_node(N, node, 0, position="aligned")

    if (not node.is_leaf()):
        S = faces.AttrFace("support", fsize=200, fgcolor="#000000")
        S.margin_top = 20
        S.margin_right = 10
        S.margin_left = 20
        S.margin_bottom = 20
        faces.add_face_to_node(S, node, column=0, position="float")
        if "support" in node.features:
            # Creates a sphere face whose size is proportional to node's
            # feature "weight"
            C = CircleFace(radius=node.support * 20,
                           color="RoyalBlue",
                           style="sphere")
            # Let's make the sphere transparent
            C.opacity = 0.3
            # And place as a float face over the tree
            faces.add_face_to_node(C, node, position="float", column=1)
    style = NodeStyle()
    style["size"] = 0
    style["vt_line_width"] = 150
    style["hz_line_width"] = 150
    style["vt_line_type"] = 0  # 0 solid, 1 dashed, 2 dotted
    style["hz_line_type"] = 0
    node.set_style(style)

    bgcol1 = "#FFCCCC"
    bgcol2 = "#FFE5CC"
    bgcol3 = "#FFFFCC"
    bgcol4 = "#E5FFCC"
    bgcol5 = "#CCFFCC"
    bgcol6 = "#CCFFE5"
    bgcol7 = "#FFCCE5"
    bgcol8 = "#CCFFFF"
    bgcol9 = "#CCE5FF"
    bgcol10 = "#CCCCFF"
    bgcol11 = "#E5CCFF"
Esempio n. 6
0
 def layout(node):
     node_style = NodeStyle()
     node_style["hz_line_width"] = 10
     node_style["vt_line_width"] = 10
     node.set_style(node_style)
     #print(node)
     if node.is_leaf():
         if node.name in org_names:
             #make reconstructed bubble
             size = x[org_names.index(node.name)]
             F = CircleFace(radius=size_factor * math.sqrt(size),
                            color="RoyalBlue",
                            style="sphere")
             F.border.width = None
             F.opacity = 0.6
             faces.add_face_to_node(F, node, 0, position="branch-right")
             #Denote that this was a training organism
             nameFace = AttrFace("name", fsize=font_size, fgcolor='black')
             faces.add_face_to_node(nameFace,
                                    node,
                                    0,
                                    position="branch-right")
     elif node.name in hyp_node_names:  #Otherwise it's a hypothetical node, just use recon x
         node_base_name = hyp_node_names[node.name][0]
         percent = hyp_node_names[node.name][1]
         if node_base_name in org_names:
             idx = hyp_node_names[node.name][2]
             size = x[org_names.index(node_base_name) +
                      (idx + 1) * len(org_names)]
             F = CircleFace(radius=size_factor * math.sqrt(size),
                            color="RoyalBlue",
                            style="sphere")
             F.border.width = None
             F.opacity = 0.6
             faces.add_face_to_node(F, node, 0, position="branch-right")
             #This is if I want the names of the hypothetical nodes to be printed as well
             #nameFace = AttrFace("name", fsize=font_size, fgcolor='black')
             #faces.add_face_to_node(nameFace, node, 0, position="branch-right")
         else:
             size = 0
     else:
         size = 0
Esempio n. 7
0
	def layout(node):
		if node.name in ckm_name_to_perc:
			ckm_perc = float(ckm_name_to_perc[node.name])
		else:
			ckm_perc = 0
		F = CircleFace(radius=3.14*math.sqrt(ckm_perc), color="RoyalBlue", style="sphere")
		F.border.width = None
		F.opacity = 0.6
		faces.add_face_to_node(F,node, 0, position="branch-right")
		if label_internal_nodes:
			faces.add_face_to_node(TextFace(node.name, fsize=7),node, 0, position="branch-top")
Esempio n. 8
0
def layout(node):
    if node.is_leaf():
        
        #######################################################
        #~ Taxon Label Size and Margin Adjustment
        N = AttrFace("name", fsize=1200,fgcolor="#000000")
        N.margin_top = 250
        N.margin_right = 100 #outside
        N.margin_left = 1000 #inside
        N.margin_bottom = 250
        #######################################################
        
        #######################################################
        #~ Taxon Label Background Color Setting
        tmp = "<myTaxaonLabel>" 
        #~ if not(node.name.find(tmp)) : N.background.color="#FF9999"
        #######################################################
        
        faces.add_face_to_node(N, node, 0, position="aligned")

    if (not node.is_leaf()) :
        S=faces.AttrFace("support", fsize=200, fgcolor="#000000")
        S.margin_top = 20
        S.margin_right = 10
        S.margin_left = 20
        S.margin_bottom = 20
        faces.add_face_to_node( S, node, column=0 , position = "float")
        if "support" in node.features:
        # Creates a sphere face whose size is proportional to node's
        # feature "weight"
            C = CircleFace(radius=node.support*20, color="RoyalBlue", style="sphere")
        # Let's make the sphere transparent 
            C.opacity = 0.3
        # And place as a float face over the tree
            faces.add_face_to_node(C, node, position="float",column=1)
    style = NodeStyle()
    style["size"] = 0
    style["vt_line_width"] = 150
    style["hz_line_width"] = 150
    style["vt_line_type"] = 0 # 0 solid, 1 dashed, 2 dotted
    style["hz_line_type"] = 0
    node.set_style(style)

    bgcol1="#FFCCCC"
    bgcol2="#FFE5CC"
    bgcol3="#FFFFCC"
    bgcol4="#E5FFCC"
    bgcol5="#CCFFCC"
    bgcol6="#CCFFE5"
    bgcol7="#FFCCE5"
    bgcol8="#CCFFFF"
    bgcol9="#CCE5FF"
    bgcol10="#CCCCFF"
    bgcol11="#E5CCFF"
Esempio n. 9
0
def layout(node):
    if node.is_leaf():
        # Add node name to laef nodes
        N = AttrFace("name", fsize=14, fgcolor="black")
        faces.add_face_to_node(N, node, 0)
    if "weight" in node.features:
        # Creates a sphere face whose size is proportional to node's
        # feature "weight"
        C = CircleFace(radius=node.weight, color="RoyalBlue", style="sphere")
        # Let's make the sphere transparent 
        C.opacity = 0.3
        # And place as a float face over the tree
        faces.add_face_to_node(C, node, 0, position="float")
Esempio n. 10
0
def layout(node):

	if not node.is_root():
		# give node name to all but the root
		faces.add_face_to_node(TextFace(node.name), node, 0)
		# and increase them with the wight
		if "weight" in node.features:
			# Creates a sphere face whose size is proportional to node's
			# feature "weight"
			C = CircleFace(radius=node.weight, color="RoyalBlue", style="sphere")
			# Let's make the sphere transparent 
			C.opacity = 0.34
			# And place as a float face over the tree
			faces.add_face_to_node(C, node, 0, position="float")
Esempio n. 11
0
def layout(node):

	if not node.is_root():
		# give node name to all but the root
		faces.add_face_to_node(TextFace(node.name), node, 0)
		# and increase them with the wight
		if "weight" in node.features:
			# Creates a sphere face whose size is proportional to node's
			# feature "weight"
			C = CircleFace(radius=node.weight, color="RoyalBlue", style="sphere")
			# Let's make the sphere transparent 
			C.opacity = 0.34
			# And place as a float face over the tree
			faces.add_face_to_node(C, node, 0, position="float")
 def layout(node):
     def color(node):
         if type(node.item) is Value:
             return "Red"
         elif type(node.item) is Parameter:
             return "Yellow"
         elif node.item.leaf:
             return "Green"
         else:
             return "RoyalBlue"
     N = AttrFace("name", fsize=14, fgcolor="black")
     faces.add_face_to_node(N, node, 0)
     C = CircleFace(radius=node.weight, color=color(node), style="sphere")
     C.opacity = 0.3
     faces.add_face_to_node(C, node, 0, position="float")
Esempio n. 13
0
def layout(node):
	if not node.is_root():
		# Add node name to laef nodes
		#N = AttrFace("name", fsize=14, fgcolor="black")
		#faces.add_face_to_node(N, node, 0)
		#pass
		faces.add_face_to_node(TextFace(node.name), node, 0)
		if "weight" in node.features:
			# Creates a sphere face whose size is proportional to node's
			# feature "weight"
			C = CircleFace(radius=node.weight, color="RoyalBlue", style="sphere")
			# Let's make the sphere transparent 
			C.opacity = 0.3
			# And place as a float face over the tree
			faces.add_face_to_node(C, node, 0, position="float")
Esempio n. 14
0
    def __layout__(self, node):
        if node.is_leaf():
            # Add node name to laef nodes
            N = AttrFace("name", fsize=14, fgcolor="black")
            faces.add_face_to_node(N, node, 0)
            nstyle = NodeStyle()

            nstyle["size"] = 0
            node.set_style(nstyle)
        if "internalCount" in node.features:
            print node.name
            # Creates a sphere face whose size is proportional to node's     
            # feature "weight"
            C = CircleFace(radius=int(node.internalCount)/10, color="RoyalBlue", style="sphere")
            T = TextFace("10")
            # Let's make the sphere transparent
            C.opacity = 0.3
            # And place as a float face over the tree
            faces.add_face_to_node(C, node, 0, position="float")
            faces.add_face_to_node(T, node, 1)
Esempio n. 15
0
    def __layout__(self, node):
        if node.is_leaf():
            # Add node name to laef nodes
            N = AttrFace("name", fsize=14, fgcolor="black")
            faces.add_face_to_node(N, node, 0)
            nstyle = NodeStyle()

            nstyle["size"] = 0
            node.set_style(nstyle)
        if "internalCount" in node.features:
            print node.name
            # Creates a sphere face whose size is proportional to node's
            # feature "weight"
            C = CircleFace(radius=int(node.internalCount) / 10,
                           color="RoyalBlue",
                           style="sphere")
            T = TextFace("10")
            # Let's make the sphere transparent
            C.opacity = 0.3
            # And place as a float face over the tree
            faces.add_face_to_node(C, node, 0, position="float")
            faces.add_face_to_node(T, node, 1)
Esempio n. 16
0
def MakePlot(x, org_names, ckm30, ckm50, outgroup, outfile, outfilexml, sum_x):
	
	#Make sure names are unique
	names = org_names
	for name in names:
		if names.count(name)>1:
			temp_name = name
			i=1
			for dummy in range(0,names.count(name)-1): #Don't change the last one, just to make sure we don't conflict with the outgroup
				names[names.index(temp_name)] = temp_name + "_" + str(i)
				i = i +1
		
	#Normalize the x vector
	x = map(lambda y: y/sum(x),x)
	ckm30_norm = np.multiply(ckm30,1/np.diag(ckm30))
	ckm50_norm = np.multiply(ckm50,1/np.diag(ckm50))
	num_rows = ckm30_norm.shape[0]
	num_cols = ckm30_norm.shape[1]
	matrix=list()
	for i in range(num_rows):
		matrix.append([.5*(1-.5*ckm30_norm[i,j]-.5*ckm30_norm[j,i])+.5*(1-.5*ckm50_norm[i,j]-.5*ckm50_norm[j,i]) for j in range(i+1)])

	#Make the list of distances (ave of the two ckm matrices)
	ckm_ave_train = .5*ckm30_norm+.5*ckm50_norm
	ckm_ave_train_dist = dict()
	for i in range(len(org_names)):
		ckm_ave_train_dist[org_names[i]] = [.5*ckm_ave_train[i,j]+.5*ckm_ave_train[j,i] for j in range(len(org_names))]

	#Construct the tree. Note I could use RapidNJ here, but a few tests have shown that the trees that RapidNJ creates are rubbish.
	dm = _DistanceMatrix(names, matrix)
	constructor = DistanceTreeConstructor()
	tree = constructor.nj(dm)
	t=Tree(tree.format('newick'),format=1)
	#tree.format('newick')
	#Phylo.draw_ascii(tree)

	#Now I will put internal nodes in a certain phylogenetic distance between the root and a given node.
	#Function to insert a node at a given distance
	def insert_node(t, name_to_insert, insert_above, dist_along):
		insert_at_node = t.search_nodes(name=insert_above)[0]
		parent = (t&insert_above).up
		orig_branch_length = t.get_distance(insert_at_node,parent)
		if orig_branch_length < dist_along:
			raise ValueError("error: dist_along larger than orig_branch_length in PlotPackage.py")
		removed_node = insert_at_node.detach()
		removed_node.dist = orig_branch_length - dist_along
		added_node = parent.add_child(name=name_to_insert, dist=dist_along)
		added_node.add_child(removed_node)

	#Function to insert a node some % along a branch, taking into account the ckm distances and nodes already created in the NJ tree (and what distance their descendants are from everyone else)
	def insert_hyp_node(t, leaf_name, percent, ckm_ave_train_dist, org_names):
		dists = map(lambda y: abs(y-percent), ckm_ave_train_dist[leaf_name])
		nearby_indicies = list()
		#Add all the organisms that are within 0.05 of the given percent
	#	for i in range(len(dists)):
	#		if dists[i]<=.05:
	#			nearby_indicies.append(i)
		nearby_names = list()
		#If there are no nearby indicies, add the closest organism to the given percent
		if nearby_indicies==[]:
			nearby_names.append(org_names[dists.index(min(dists))])
		else:
			for i in range(len(nearby_indicies)):
				nearby_names.append(org_names[i])
		mean_dist = np.mean(map(lambda y: ckm_ave_train_dist[leaf_name][org_names.index(y)],nearby_names))
		nearby_names.append(leaf_name)
		LCA = t.get_common_ancestor(nearby_names)
		LCA_to_leaf_dist = t.get_distance(LCA,leaf_name)
		#divide the dist to the right/left of the LCA node by the number of percentage points in there
		if LCA.name==t.name:
			percent_dist = percent*LCA_to_leaf_dist
			if mean_dist <= percent:
				child_node = (t&leaf_name)
			else:
				child_node = (t&nearby_names[0])#This means "go up from root" in the direction of the nearest guy
			ancestor_node = (t&child_node.name).up
		elif mean_dist <= percent:
			percent_dist = t.get_distance(LCA) + abs(percent-mean_dist)*(LCA_to_leaf_dist)/(1-mean_dist)
			child_node = (t&leaf_name)
			ancestor_node = (t&child_node.name).up
		else:
			percent_dist = t.get_distance(LCA) - abs(percent-mean_dist)*(t.get_distance(LCA))/(mean_dist)
			child_node = (t&leaf_name)
			ancestor_node = (t&child_node.name).up
		while t.get_distance(t.name, ancestor_node) > percent_dist:
			child_node = ancestor_node
			ancestor_node = (t&child_node.name).up
		insert_node(t, leaf_name+"_"+str(percent), child_node.name, percent_dist-t.get_distance(t.name, ancestor_node))

	#Set outgroup
	if outgroup in names:
		t.set_outgroup(t&outgroup) #I will need to check that this outgroup is actually one of the names...
	else:
		print("WARNING: the chosen outgroup " + outgroup + " is not in the given taxonomy: ")
		print(names)
		print("Proceeding without setting an outgroup. This may cause results to be uninterpretable.")

	#Insert hypothetical nodes
	hyp_node_names = dict()
	cutoffs = [.9,.8,.7,.6,.5,.4,.3,.2,.1]
	cutoffs = [-.5141*(val**3)+1.0932*(val**2)+0.3824*val for val in cutoffs]
	for i in range(len(org_names)):
		xi = x[i:len(x):len(org_names)]
		for j in range(1,len(cutoffs)+1):
			if xi[j]>0:
				insert_hyp_node(t, org_names[i], cutoffs[j-1],ckm_ave_train_dist, org_names)
				hyp_node_names[org_names[i]+"_"+str(cutoffs[j-1])] = [org_names[i], cutoffs[j-1], j-1] #in case there are "_" in the file names

	size_factor=250
	font_size=55

	#Now put the bubbles on the nodes
	def layout(node):
		node_style = NodeStyle()
		node_style["hz_line_width"] = 10
		node_style["vt_line_width"] = 10
		node.set_style(node_style)
		#print(node)
		if node.is_leaf():
			if node.name in org_names:
				#make reconstructed bubble
				size = x[org_names.index(node.name)]
				F = CircleFace(radius=size_factor*math.sqrt(size), color="RoyalBlue", style="sphere")
				F.border.width = None
				F.opacity = 0.6
				faces.add_face_to_node(F,node, 0, position="branch-right")
				#Denote that this was a training organism
				nameFace = AttrFace("name", fsize=font_size, fgcolor='black')
				faces.add_face_to_node(nameFace, node, 0, position="branch-right")
		elif node.name in hyp_node_names: #Otherwise it's a hypothetical node, just use recon x
			node_base_name = hyp_node_names[node.name][0]
			percent = hyp_node_names[node.name][1]
			if node_base_name in org_names:
				idx = hyp_node_names[node.name][2]
				size = x[org_names.index(node_base_name)+(idx+1)*len(org_names)]
				F = CircleFace(radius=size_factor*math.sqrt(size), color="RoyalBlue", style="sphere")
				F.border.width = None
				F.opacity = 0.6
				faces.add_face_to_node(F,node, 0, position="branch-right")
				#This is if I want the names of the hypothetical nodes to be printed as well
				#nameFace = AttrFace("name", fsize=font_size, fgcolor='black')
				#faces.add_face_to_node(nameFace, node, 0, position="branch-right")
			else:
				size=0
		else:
			size=0
	
	ts = TreeStyle()
	ts.layout_fn = layout
	ts.mode = "r"
	#ts.mode = "c"
	ts.scale = 2*1000
	ts.show_leaf_name = False
	ts.min_leaf_separation = 50
	F = CircleFace(radius=.87*size_factor, color="RoyalBlue", style="sphere")
	F.border.width = None
	F.opacity = 0.6
	ts.legend.add_face(F,0)
	ts.legend.add_face(TextFace("  Inferred relative abundance",fsize=1.5*font_size,fgcolor="Blue"),1)
	ts.legend.add_face(TextFace("  Total absolute abundance depicted " + str(sum_x)[0:8], fsize=1.5*font_size,fgcolor="Black"),1)
	ts.legend_position=4
	#t.show(tree_style=ts)
	t.render(outfile, w=550, units="mm", tree_style=ts)
	
	#Redner the XML file
	project = Phyloxml()
	phylo = phyloxml.PhyloxmlTree(newick=t.write(format=0, features=[]))
	project.add_phylogeny(phylo)
	project.export(open(outfilexml,'w'))
Esempio n. 17
0
def style_node2(node, colour, size):
    C = CircleFace(radius = size, color = colour, style="sphere")
    C.opacity = 0.8
    node.add_face(C, 0, position="float")
Esempio n. 18
0
def MakePlot(x, org_names, ckm30, ckm50, outgroup, outfile, outfilexml, sum_x):

    #Make sure names are unique
    names = org_names
    for name in names:
        if names.count(name) > 1:
            temp_name = name
            i = 1
            for dummy in range(
                    0,
                    names.count(name) - 1
            ):  #Don't change the last one, just to make sure we don't conflict with the outgroup
                names[names.index(temp_name)] = temp_name + "_" + str(i)
                i = i + 1

    #Normalize the x vector
    x = map(lambda y: y / sum(x), x)
    ckm30_norm = np.multiply(ckm30, 1 / np.diag(ckm30))
    ckm50_norm = np.multiply(ckm50, 1 / np.diag(ckm50))
    num_rows = ckm30_norm.shape[0]
    num_cols = ckm30_norm.shape[1]
    matrix = list()
    for i in range(num_rows):
        matrix.append([
            .5 * (1 - .5 * ckm30_norm[i, j] - .5 * ckm30_norm[j, i]) + .5 *
            (1 - .5 * ckm50_norm[i, j] - .5 * ckm50_norm[j, i])
            for j in range(i + 1)
        ])

    #Make the list of distances (ave of the two ckm matrices)
    ckm_ave_train = .5 * ckm30_norm + .5 * ckm50_norm
    ckm_ave_train_dist = dict()
    for i in range(len(org_names)):
        ckm_ave_train_dist[org_names[i]] = [
            .5 * ckm_ave_train[i, j] + .5 * ckm_ave_train[j, i]
            for j in range(len(org_names))
        ]

    #Construct the tree. Note I could use RapidNJ here, but a few tests have shown that the trees that RapidNJ creates are rubbish.
    dm = _DistanceMatrix(names, matrix)
    constructor = DistanceTreeConstructor()
    tree = constructor.nj(dm)
    t = Tree(tree.format('newick'), format=1)

    #tree.format('newick')
    #Phylo.draw_ascii(tree)

    #Now I will put internal nodes in a certain phylogenetic distance between the root and a given node.
    #Function to insert a node at a given distance
    def insert_node(t, name_to_insert, insert_above, dist_along):
        insert_at_node = t.search_nodes(name=insert_above)[0]
        parent = (t & insert_above).up
        orig_branch_length = t.get_distance(insert_at_node, parent)
        if orig_branch_length < dist_along:
            raise ValueError(
                "error: dist_along larger than orig_branch_length in PlotPackage.py"
            )
        removed_node = insert_at_node.detach()
        removed_node.dist = orig_branch_length - dist_along
        added_node = parent.add_child(name=name_to_insert, dist=dist_along)
        added_node.add_child(removed_node)

    #Function to insert a node some % along a branch, taking into account the ckm distances and nodes already created in the NJ tree (and what distance their descendants are from everyone else)
    def insert_hyp_node(t, leaf_name, percent, ckm_ave_train_dist, org_names):
        dists = map(lambda y: abs(y - percent), ckm_ave_train_dist[leaf_name])
        nearby_indicies = list()
        #Add all the organisms that are within 0.05 of the given percent
        #	for i in range(len(dists)):
        #		if dists[i]<=.05:
        #			nearby_indicies.append(i)
        nearby_names = list()
        #If there are no nearby indicies, add the closest organism to the given percent
        if nearby_indicies == []:
            nearby_names.append(org_names[dists.index(min(dists))])
        else:
            for i in range(len(nearby_indicies)):
                nearby_names.append(org_names[i])
        mean_dist = np.mean(
            map(lambda y: ckm_ave_train_dist[leaf_name][org_names.index(y)],
                nearby_names))
        nearby_names.append(leaf_name)
        LCA = t.get_common_ancestor(nearby_names)
        LCA_to_leaf_dist = t.get_distance(LCA, leaf_name)
        #divide the dist to the right/left of the LCA node by the number of percentage points in there
        if LCA.name == t.name:
            percent_dist = percent * LCA_to_leaf_dist
            if mean_dist <= percent:
                child_node = (t & leaf_name)
            else:
                child_node = (
                    t & nearby_names[0]
                )  #This means "go up from root" in the direction of the nearest guy
            ancestor_node = (t & child_node.name).up
        elif mean_dist <= percent:
            percent_dist = t.get_distance(LCA) + abs(percent - mean_dist) * (
                LCA_to_leaf_dist) / (1 - mean_dist)
            child_node = (t & leaf_name)
            ancestor_node = (t & child_node.name).up
        else:
            percent_dist = t.get_distance(LCA) - abs(percent - mean_dist) * (
                t.get_distance(LCA)) / (mean_dist)
            child_node = (t & leaf_name)
            ancestor_node = (t & child_node.name).up
        while t.get_distance(t.name, ancestor_node) > percent_dist:
            child_node = ancestor_node
            ancestor_node = (t & child_node.name).up
        insert_node(t, leaf_name + "_" + str(percent), child_node.name,
                    percent_dist - t.get_distance(t.name, ancestor_node))

    #Set outgroup
    if outgroup in names:
        t.set_outgroup(
            t & outgroup
        )  #I will need to check that this outgroup is actually one of the names...
    else:
        print("WARNING: the chosen outgroup " + outgroup +
              " is not in the given taxonomy: ")
        print(names)
        print(
            "Proceeding without setting an outgroup. This may cause results to be uninterpretable."
        )

    #Insert hypothetical nodes
    hyp_node_names = dict()
    cutoffs = [.9, .8, .7, .6, .5, .4, .3, .2, .1]
    cutoffs = [
        -.5141 * (val**3) + 1.0932 * (val**2) + 0.3824 * val for val in cutoffs
    ]
    for i in range(len(org_names)):
        xi = x[i:len(x):len(org_names)]
        for j in range(1, len(cutoffs) + 1):
            if xi[j] > 0:
                insert_hyp_node(t, org_names[i], cutoffs[j - 1],
                                ckm_ave_train_dist, org_names)
                hyp_node_names[org_names[i] + "_" + str(cutoffs[j - 1])] = [
                    org_names[i], cutoffs[j - 1], j - 1
                ]  #in case there are "_" in the file names

    size_factor = 250
    font_size = 55

    #Now put the bubbles on the nodes
    def layout(node):
        node_style = NodeStyle()
        node_style["hz_line_width"] = 10
        node_style["vt_line_width"] = 10
        node.set_style(node_style)
        #print(node)
        if node.is_leaf():
            if node.name in org_names:
                #make reconstructed bubble
                size = x[org_names.index(node.name)]
                F = CircleFace(radius=size_factor * math.sqrt(size),
                               color="RoyalBlue",
                               style="sphere")
                F.border.width = None
                F.opacity = 0.6
                faces.add_face_to_node(F, node, 0, position="branch-right")
                #Denote that this was a training organism
                nameFace = AttrFace("name", fsize=font_size, fgcolor='black')
                faces.add_face_to_node(nameFace,
                                       node,
                                       0,
                                       position="branch-right")
        elif node.name in hyp_node_names:  #Otherwise it's a hypothetical node, just use recon x
            node_base_name = hyp_node_names[node.name][0]
            percent = hyp_node_names[node.name][1]
            if node_base_name in org_names:
                idx = hyp_node_names[node.name][2]
                size = x[org_names.index(node_base_name) +
                         (idx + 1) * len(org_names)]
                F = CircleFace(radius=size_factor * math.sqrt(size),
                               color="RoyalBlue",
                               style="sphere")
                F.border.width = None
                F.opacity = 0.6
                faces.add_face_to_node(F, node, 0, position="branch-right")
                #This is if I want the names of the hypothetical nodes to be printed as well
                #nameFace = AttrFace("name", fsize=font_size, fgcolor='black')
                #faces.add_face_to_node(nameFace, node, 0, position="branch-right")
            else:
                size = 0
        else:
            size = 0

    ts = TreeStyle()
    ts.layout_fn = layout
    ts.mode = "r"
    #ts.mode = "c"
    ts.scale = 2 * 1000
    ts.show_leaf_name = False
    ts.min_leaf_separation = 50
    F = CircleFace(radius=.87 * size_factor, color="RoyalBlue", style="sphere")
    F.border.width = None
    F.opacity = 0.6
    ts.legend.add_face(F, 0)
    ts.legend.add_face(
        TextFace("  Inferred relative abundance",
                 fsize=1.5 * font_size,
                 fgcolor="Blue"), 1)
    ts.legend.add_face(
        TextFace("  Total absolute abundance depicted " + str(sum_x)[0:8],
                 fsize=1.5 * font_size,
                 fgcolor="Black"), 1)
    ts.legend_position = 4
    #t.show(tree_style=ts)
    t.render(outfile, w=550, units="mm", tree_style=ts)

    #Redner the XML file
    project = Phyloxml()
    phylo = phyloxml.PhyloxmlTree(newick=t.write(format=0, features=[]))
    project.add_phylogeny(phylo)
    project.export(open(outfilexml, 'w'))