7

I want to "visually" animate Markov chains like here : http://markov.yoriz.co.uk/ but using Python instead of html css and javascript.

I don't know if there is any library that makes this easy, till now I managed to make a visual representation of Markov chains using Networkx library like in the figure below, but couldn't get it to be animated (or simulated)

Here is my code so far:

from networkx.drawing.nx_pydot import write_dot import networkx as nx import matplotlib.pyplot as plt states = [(0, 0), (1, 0), (2, 0),] Q = [[5, 5, 0.4], [1, 2, 3], [4, 0.7, 0] ] G = nx.MultiDiGraph() labels={} edge_labels={} for i, origin_state in enumerate(states): for j, destination_state in enumerate(states): rate = Q[i][j] if rate > 0: G.add_edge(origin_state, destination_state, weight=rate, label="{:.02f}".format(rate)) edge_labels[(origin_state, destination_state)] = label="{:.02f}".format(rate) plt.figure(figsize=(10,7)) node_size = 200 pos = {state:list(state) for state in states} nx.draw_networkx_edges(G,pos,width=1.0,alpha=0.5) nx.draw_networkx_labels(G, pos, font_weight=2) nx.draw_networkx_edge_labels(G, pos, edge_labels) plt.axis('off'); plt.show() write_dot(G, 'mc.dot') from subprocess import check_call nfile = 'w.png' check_call(['dot', '-Tpng', 'mc.dot', '-o', nfile]) import matplotlib.image as mpimg img = mpimg.imread(nfile) plt.axis('off') plt.imshow(img) plt.show() 

enter image description here

2

1 Answer 1

1

You can do that by sampling from your Markov chain over a certain number of steps (100 in the code below) and modifying the color of the selected node at each step (see more here on how to change color of the nodes with graphviz). You can then create a png file of your network for each step and use imageio to generate a GIF from the png images (see more details on how to do that here).

Below is the full code:

import networkx as nx from networkx.drawing.nx_agraph import to_agraph import numpy as np import imageio #Markov chain parameters states = [(0, 0), (1, 0), (2, 0),] Q = [[0.2, 0.3, 0.5], [0.1, 0.2, 0.7], [0.3, 0.7, 0] ] #Sampling the markov chain over 100 steps N_steps=100 node_ind=0 node_sel=[node_ind] for i in range(N_steps): temp_ni=np.random.choice(3,p=Q[node_ind]) node_sel.append(temp_ni) node_ind=temp_ni #Setting up network G = nx.MultiDiGraph() [G.add_node(s,style='filled',fillcolor='white',shape='circle',fixedsize='true',width=0.5) for s in states] labels={} edge_labels={} for i, origin_state in enumerate(states): for j, destination_state in enumerate(states): rate = Q[i][j] if rate > 0: G.add_edge(origin_state, destination_state, weight=rate, label="{:.02f}".format(rate),len=2) #Setting up node color for each iteration for k in range(N_steps): for i,n in enumerate(G.nodes(data=True)): if i==node_sel[k]: n[1]['fillcolor']='blue' else: n[1]['fillcolor']='white' A = to_agraph(G) A.layout() A.draw('net_'+str(k)+'.png') #Create gif with imageio images = [] filenames=['net_'+str(k)+'.png' for k in range(N_steps)] for filename in filenames: images.append(imageio.imread(filename)) imageio.mimsave('markov_chain.gif', images,fps=3) 

And here is the result:

enter image description here

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.