I made this class : 50 points of a spiral change to a cirle.
But the animation is sequential and I would like to start it at the same time.
class SpiralToCircle(Scene):
def construct(self):
vertices1 = range(50)
vertices2 = range(50)
edges = [(48, 49),(3, 4)]
g1 = Graph(vertices1, edges, layout="spiral")
g2 = Graph(vertices2, edges, layout="circular")
# self.add(graph)
self.play(Create(g1))
self.wait(5)
for i in vertices1:
self.play(g1[i].animate.move_to(g2[i]))
self.wait()
I thought about this trick, but I returns an error :
self.play((g1[i].animate.move_to(g2[i])) for i in vertices1)
TypeError: Unexpected argument <generator object GraphCircular.construct.. at 0x00000229667509E0> passed to Scene.play().
This should work: self.play([g1[i].animate.move_to(g2[i]) for i in vertices1]) The play function can take a list of animations.
Try unpacking the animation list and pass them as parameters to the play method:
self.play(*[g1[i].animate.move_to(g2[i]) for i in vertices1])
So, the code would be:
class SpiralToCircle(Scene):
def construct(self):
vertices1 = range(50)
vertices2 = range(50)
edges = [(48, 49), (3, 4)]
g1 = Graph(vertices1, edges, layout="spiral")
g2 = Graph(vertices2, edges, layout="circular")
# self.add(graph)
self.play(Create(g1))
self.wait(5)
self.play(*[g1[i].animate.move_to(g2[i]) for i in vertices1])
self.wait()
Generating this output:
Output Animation
Related
I'm trying to add a second edge's attribute in a existing graph.
I created a graph G and save it as a pkl file.
edges1 = pd.DataFrame({'source':[0,1,2,3,4],
'target':[10,11,12,13,14],
'weight':[50,50,50,50,50]})
G = nx.from_pandas_edgelist(edges1, 'source', 'target', 'weight')
I loaded G and then tried to add the second edge's attribute(cost) and a node attribute.
But it keeps overwriting the first edges' attribute(weight).
edges2 = pd.DataFrame({'source':[0,1,2,6,7,8],
'target':[10,11,12,16,17,18],
'cost':[100,100,100,100,100,100]})
nodes = pd.DataFrame({'node':[0,1,2,3,10,18],
'name':['A','B','C','D','E','F']})
nx.from_pandas_edgelist(edges2, 'source', 'target', 'cost')
nx.set_node_attributes(G, pd.Series(nodes.name, index=nodes.node).to_dict(), 'name')
I must load the graph G, so combining edges1 and edges2 DataFrames and creating a graph isn't what I need.
How can I get this?
[(0, 10, {'weight':50, 'cost': 100}), (1, 11, {'weight':50, 'cost':
100}) ...]
instead of this
[(0, 10, {'cost': 100}), (1, 11, {'cost': 100}) ...]
I'm not clear if you want to add new edges from edges2 or not. If you are okay with adding new edges, you can use nx.compose:
H = nx.from_pandas_edgelist(edges2, 'source', 'target', 'cost')
G_updated = nx.compose(G, H)
If you don't want to add new edges, then you can check if the edge exists and then set the edge attribute directly:
H = nx.from_pandas_edgelist(edges2, 'source', 'target', 'cost')
for edge in H.edges():
if edge in G.edges():
G.edges[edge]['cost'] = H.edges[edge]['cost']
If performance is an issue, you could also consider setting the edge attributes of G directly by using your edges2 data without building a second graph or even a second dataframe.
I am using the shortest path algorithm from LightGraphs.jl. In the end I want to collect some information about the nodes along the path. In order to do that I need to be able to extract the vertices from the edges that the function gives back.
Using LightGraphs
g = cycle_graph(4)
path = a_star(g, 1, 3)
edge1 = path[1]
Using this I get: Edge 1 => 2
How would I automatically get the vertices 1, 2 without having to look at the Edge manually? I thinking about some thing like edge1[1] or edge1.From which both does not work.
Thanks in advance!
The accessors for AbstractEdge classes are src and dst, used like this:
using LightGraphs
g = cycle_graph(4)
path = a_star(g, 1, 3)
edge1 = path[1]
s = src(edge1)
d = dst(edge1)
println("source: $s") # prints "source: 1"
println("destination: $d") # prints "destination: 2"
I have these Circles:
I want to get the list of all possible solution of maximum non-intersecting circles. This is the illustration of the solution I wanted from node A.
Therefore the possible solutions from node A:
1 = [A,B,C], 2 = [A,B,E], 3 = [A,C,B], 4 = [A,E,B] ..etc
I want to store all of the possibilities into a list, which the will be used for weighting and selecting the best result. However, I'm still trying to create the list of all possibilities.
I've tried to code the structure here, however I still confused about backtracking and recursive. Anyone could help here?
# List of circle
# List of circle
list_of_circle = ['A','B','C','D','E']
# List of all possible solutions
result = []
# List of possible nodes
ways = []
for k in list_of_circle:
if len(list_of_circle)==0:
result.append(ways)
else:
ways.append[k]
list_of_circle.remove(k)
for j in list_of_circle:
if k.intersects(j):
list_of_circle.remove(j)
return result
Here is a possible solution (pseudocode).
def get_max_non_intersect(selected_circles, current_circle_idx, all_circles):
if current_circle_idx == len(all_circles): # final case
return selected_circles
# we recursively get the biggest selection of circles if the current circle is not selected
list_without_current_circle = get_max_non_intersect(selected_circles, current_circle_idx + 1, all_circles)
# now we check if we can add the current circle to the ones selected
current_intersects_selected = false
current_circle = all_circles[current_circle_idx]
for selected_circle in selected_circles:
if intersects(current_circle, selected_circle):
current_intersects_selected = true
break
if current_intersects_selected is true: # we cannot add the current circle
return list_without_current_circle
else: # we can add the current circle
list_with_current_circle = get_max_non_intersect(selected_circles + [current_circle], current_circle_idx + 1, all_circles)
return list_with_current_circle + list_without_current_circle
I have a NetworkX problem. I create a digraph with a pandas DataFrame and there is data that I set along the edge. I now need to count the # of unique sources for nodes descendants and access the edge attribute.
This is my code and it works for one node but I need to pass a lot of nodes to this and get unique counts.
graph = nx.from_pandas_edgelist(df, source="source", target="target",
edge_attr=["domain", "category"], create_using=nx.DiGraph)
downstream_nodes = list(nx.descendants(graph, node))
downstream_nodes.append(node)
subgraph = graph.subgraph(downstream_nodes).copy()
domain_sources = {}
for s, t, v in subgraph.edges(data=True):
if v["domain"] in domain_sources:
domain_sources[v["domain"]].append(s)
else:
domain_sources[v["domain"]] = [s]
down_count = {}
for k, v in domain_sources.items():
down_count[k] = len(list(set(v)))
It works but, again, for one node the time is not a big deal but I'm feeding this routine at least 40 to 50 nodes. Is this the best way? Is there something else I can do that can group by an edge attribute and uniquely count the nodes?
Two possible enhancements:
Remove copy from line creating the sub graph. You are not changing anything and the copy is redundant.
Create a defaultdict with keys of set. Read more here.
from collections import defaultdict
import networkx as nx
# missing part of df creation
graph = nx.from_pandas_edgelist(df, source="source", target="target",
edge_attr=["domain", "category"], create_using=nx.DiGraph)
downstream_nodes = list(nx.descendants(graph, node))
downstream_nodes.append(node)
subgraph = graph.subgraph(downstream_nodes)
domain_sources = defaultdict(set)
for s, t, v in subgraph.edges(data=True):
domain_sources[v["domain"]].add(s)
down_count = {}
for k, v in domain_sources.items():
down_count[k] = len(set(v))
I'm using the bupaR process mining suite and processmapR to plot my log as a process map but when I try to set a custom position (which force the graph to use a neato layout) the edge become almost staight and the edge value hard to read:
Default graph with no custom position:
With custom position:
I tried to use
positions <- data.frame(act = c("node1","node2","node 3","node 4","node 5","Start", "End"),
y = c(5,4,3,2,1,6,0),
x = c(1,2,3,4,5,0,6),
stringsAsFactors = F)
graph = process_map(log, fixed_node_pos = positions, render = F)
map = add_global_graph_attrs(graph,
attr = "splines",
value = "true",
attr_type = "graph")
render_graph(map)
But I could not find any attribute to change the way edge are displayed, like adding more curve to them
How can I fix this problem ?
Thanks
Try the following:
map = add_global_graph_attrs(graph,
attr = "splines",
value = "curved",
attr_type = "graph")