matplotlib FuncAnimation clear plot each repeat cycle - animation

The code below works, but I think is overplotting the original points each repeat cycle. I want it to start from the origin, each repeat cycle, with a clear plot. Amongst many approaches to fixing this, I have tried inserting ax.clear() in both the init and update functions; not effective. I have left in the code what I thought would reset the ln, artist to having an empty set; again this is not the solution I am looking for. I would appreciate some guidance on what the correct way to reinitiate each cycle is in this toy example so that, when applied to my more complex problem, I don't incur cumulative penalties. This works fine in terms of refreshing if passing an array...Thanks for any help.
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation, writers
#from basic_units import radians
# # Set up formatting for the movie files
# Writer = writers['ffmpeg']
# writer = Writer(fps=20, metadata=dict(artist='Llew'), bitrate=1800)
#Polar stuff
fig = plt.figure(figsize=(10,8))
ax = plt.subplot(111,polar=True)
ax.set_title("A line plot on a polar axis", va='bottom')
ax.set_rticks([0.5, 1, 1.5, 2]) # fewer radial ticks
ax.set_facecolor(plt.cm.gray(.95))
ax.grid(True)
xT=plt.xticks()[0]
xL=['0',r'$\frac{\pi}{4}$',r'$\frac{\pi}{2}$',r'$\frac{3\pi}{4}$',\
r'$\pi$',r'$\frac{5\pi}{4}$',r'$\frac{3\pi}{2}$',r'$\frac{7\pi}{4}$']
plt.xticks(xT, xL)
r = []
theta = []
# Animation requirements.
ln, = plt.plot([], [], 'r:',
markersize=1.5,
alpha=1,
animated=True)
def init():
ax.set_xlim(0, 2)
ax.set_ylim(0, 2)
return ln,
def update(frame):
r.append(frame)
theta.append(5*np.pi*frame)
ln.set_data(theta, r)
return ln,
ani = FuncAnimation(fig, update, frames=np.linspace(0,2,400),
init_func=init, interval=10, blit=True,repeat=True)
plt.show()
I tried to reset the lists (and with arrays also) using this somewhat crude approach, which wiped the list, but did not re-initiate the cycle.
def update(frame,r,theta):
r.append(frame)
theta.append(5*np.pi*frame)
if len(r)>=400:
r = [0]
theta=[0]
ln.set_data(theta, r)
return ln,
In contrast, this does work as intended...
for i in range(25):
r.append(i)
print('len(r)',len(r), r)
if len(r) >=10:
r = []
print('if r>=10:',r)
print('Post conditional clause r',len(r),r)
This led me to try the following, noting that passing the internal (r,theta) within the update() outside requires declaring it as a global variable. With the following code, the plot now resets each cycle instead of overplotting. My sense is that this is a rather long way around a simple procedure -- any improvements gratefully accepted.
#This solution also works
def update(frame):
r.append(frame)
theta.append(5*np.pi*frame)
if len(r)>=400:
global r
r = []
global theta
theta=[]
ln.set_data(theta, r)
return ln,

If I understand your code and your question, you want to display only one point at each frame of the animation, is that correct?
If so, your problem is simply that you are appending each new point to all previous points in the function update(). Instead, simply update the data coordinates, like so:
def update(frame):
r = frame
theta = 2*np.pi*frame
ln.set_data(theta, r)
return ln,
EDIT Let's see if I get this right this time around.
You could choose to only show the last N points like so:
N=10
def update(frame):
r.append(frame)
theta.append(2*np.pi*frame)
ln.set_data(theta[-N:], r[-N:])
return ln,
or you can append N points to your array, then reset to an empty array. I think that might be what you were trying to do. Here, you have to be careful. If you simply do r = [] then you change which object r references to, and that breaks the animation. What you need to do is change the content of the array with the syntax r[:] = [].
def update(frame):
r_ = frame
theta_ = 2*np.pi*frame
if len(r)>N:
r[:] = [r_]
theta[:] = [theta_]
else:
r.append(r_)
theta.append(theta_)
ln.set_data(theta, r)
return ln,

Related

Julia Plotting: push!() adds to wrong line

I want to use push!() in a for loop to continue two separate plotting lines. Consider the following example:
using Plots; gr()
f = x->x*x
g = x->f(x)+.2*randn()
p = plot(-1:.1:0, f, ylim=(-1,2), c=:blue)
s = scatter!(-1:.1:0, g, c=:red)
anim = Animation()
for i=1:10
x = i/10
push!(p, x, f(x))
push!(s, x, g(x)) # without this, f gets continued as expected
frame(anim)
end
gif(anim, "test.gif", fps=2)
Why does push!(p, ...) and push!(s,...) both continue the blue line?
How to append scattered data to s instead?
I know that the second plot at this link achieves a similar result by plotting and pushing both lines at once, but that solution is not always practical, especially in more complicated plots.
In your code, p and s are the same objects.
It means that p == s will return true.
The data will be stored in p.series_list.
You can get your y-axis data in p.series_list[1][:y] for line plot, p.series_list[2][:y] for scatter plot.
Now just slightly modify the original code!
First, remove s and use p only.
Second, in the push!() function, the 2nd argument is given to indicate the data index we want to append new data.
f = x->x*x
g = x->f(x)+.2*randn()
p = plot(-1:.1:0, f, ylim=(-1,2), c=:blue)
scatter!(-1:.1:0, g, c=:red)
anim = Animation()
for i=1:10
x = i/10
push!(p, 1, x, f(x))
push!(p, 2, x, g(x))
frame(anim)
end
gif(anim, "test.gif", fps=2)

Determine subplot square dimensions from total number of plots

I'm trying to figure out how to calculate subplot dimensions when I know the total number of plots I need and I'd like the arrangement to be a square (with possibly a few empty subplots).
For example if I need 22 subplots then I would make a grid of 5x5 for a total of 25 subplots, then just leave three of them empty.
So I guess I'm looking for an algorithm where I'd input 22 and get out 5, for example. Anyone know of a short way to do this in python (maybe lambda function if possible)?
(Also open to other alternatives or pre-made solutions for doing this, I'm doing multiple subplot matrices for a dictionary of pandas dataframes)
This should work for what you're trying to do. I haven't tried anything with a lambda function but I doubt it would be difficult to modify this. There won't be any empty plots because the algorithm stops once it's out of values to plot.
I broke up the dictionary into key and value lists because I was originally working with lists when I wrote this. Everything up to the try clause would work without converting your values to a list. If you wanted to fill in with empty plots rather than using the somewhat hack-y break_test bit, you can put all of your code for the subplots inside a try clause.
Weird break version:
fig = plt.figure()
# Makes organizing the plots easier
key_list, val_list = [k, v for k, v in dict.getitems()]
# We take advantage of the fact that int conversions always round down
floor = int(np.sqrt(len(val_list))
# If the number of plots is a perfect square, we're done.
# Otherwise, we take the next highest perfect square to build our subplots
if floor ** 2 == len(val_list):
sq_chk = floor
else:
sq_chk = floor + 1
plot_count = 0
# The try/except makes sure we can gracefully stop building plots once
# we've exhausted our dictionary values.
for i in range(sq_chk):
for j in range(sq_chk):
try:
break_test = val_list[plot_count]
except:
break
ax = fig.add_subplot(sq_chk, sq_chk, plot_count + 1)
ax.set_title(key_list[plot_count])
...
# Whatever you want to do with your plots
...
plot_count += 1
plt.show()
No break version:
fig = plt.figure()
key_list, val_list = [k, v for k, v in dict.getitems()]
floor = int(np.sqrt(len(dict))
if floor ** 2 == len(dict):
sq_chk = floor
else:
sq_chk = floor + 1
plot_count = 0
# Everything from the original snippet should be nested in the try clause
for i in range(sq_chk):
for j in range(sq_chk):
try:
ax = fig.add_subplot(sq_chk, sq_chk, plot_count + 1)
ax.set_title(key_list[plot_count])
...
# Whatever you want to do with your plots
...
plot_count += 1
except:
plot_count +=1
plt.show()

Tensorflow tf.nn.in_top_k Error targets[0] is out of range

I have a tensorflow program with four output labels. I trained the model and am now evaluating separate data with it.
The issue is that after I use the code
import tensorflow as tf
import main
import Process
import Input
eval_dir = "/Users/Zanhuang/Desktop/NNP/model.ckpt-30"
checkpoint_dir = "/Users/Zanhuang/Desktop/NNP/checkpoint"
def evaluate():
with tf.Graph().as_default() as g:
images, labels = Process.eval_inputs()
forward_propgation_results = Process.forward_propagation(images)
init_op = tf.initialize_all_variables()
saver = tf.train.Saver()
top_k_op = tf.nn.in_top_k(forward_propgation_results, labels, 1)
with tf.Session(graph=g) as sess:
sess.run(init_op)
saver.restore(sess, eval_dir)
tf.train.start_queue_runners(sess=sess)
print(sess.run(top_k_op))
def main(argv=None):
evaluate()
if __name__ == '__main__':
tf.app.run()
In total, I only have one class.
My code for the error rate, where I introduce the labels in a one hot matrix is here:
def error(forward_propagation_results, labels):
labels = tf.one_hot(labels, 4)
tf.transpose(labels)
labels = tf.cast(labels, tf.float32)
mean_squared_error = tf.square(tf.sub(labels, forward_propagation_results))
cost = tf.reduce_mean(mean_squared_error)
train = tf.train.GradientDescentOptimizer(learning_rate = 0.05).minimize(cost)
tf.histogram_summary('accuracy', mean_squared_error)
tf.add_to_collection('losses', cost)
tf.scalar_summary('LOSS', cost)
return train, cost
The problem is invalid data in your labels tensor. From your comment, the labels tensor is a vector containing a single value: [40]. The value 40 is larger than the number of columns in the forward_propagation_result (which is 4).
The tf.nn.in_top_k(predictions, targets, k) op has the following behavior:
For each row predictions[i, :]:
result[i] is true if predictions[i, targets[i]] is one of the k largest elements in that row; otherwise it is false.
There is no value predictions[0, 40], because (as your comment shows) that argument is a 1 x 4 matrix. Therefore TensorFlow gives you an out of range error. This suggests that either your evaluation data are wrong, or you should be using a different evaluation function.

PyMC: sampling step by step?

I would like to know why the sampler is incredibly slow when sampling step by step.
For example, if I run:
mcmc = MCMC(model)
mcmc.sample(1000)
the sampling is fast. However, if I run:
mcmc = MCMC(model)
for i in arange(1000):
mcmc.sample(1)
the sampling is slower (and the more it samples, the slower it is).
If you are wondering why I am asking this.. well, I need a step by step sampling because I want to perform some operations on the values of the variables after each step of the sampler.
Is there a way to speed it up?
Thank you in advance!
------------------ EDIT -------------------------------------------------------------
Here I present the specific problem in more details:
I have two models in competition and they are part of a bigger model that has a categorical variable functioning as a 'switch' between the two.
In this toy example, I have the observed vector 'Y', that could be explained by a Poisson or a Geometric distribution. The Categorical variable 'switch_model' selects the Geometric model when = 0 and the Poisson model when =1.
After each sample, if switch_model selects the Geometric model, I want the variables of the Poisson model NOT to be updated, because they are not influencing the likelihood and therefore they are just drifting away. The opposite is true if the switch_model selects the Poisson model.
Basically what I do at each step is to 'change' the value of the non-selected model by bringing it manually one step back.
I hope that my explanation and the commented code will be clear enough. Let me know if you need further details.
import numpy as np
import pymc as pm
import pandas as pd
import matplotlib.pyplot as plt
# OBSERVED VALUES
Y = np.array([0, 1, 2, 3, 8])
# PRIOR ON THE MODELS
pi = (0.5, 0.5)
switch_model = pm.Categorical("switch_model", p = pi)
# switch_model = 0 for Geometric, switch_model = 1 for Poisson
p = pm.Uniform('p', lower = 0, upper = 1) # Prior of the parameter of the geometric distribution
mu = pm.Uniform('mu', lower = 0, upper = 10) # Prior of the parameter of the Poisson distribution
# LIKELIHOOD
#pm.observed
def Ylike(value = Y, mu = mu, p = p, M = switch_model):
if M == 0:
out = pm.geometric_like(value+1, p)
elif M == 1:
out = pm.poisson_like(value, mu)
return out
model = pm.Model([Ylike, p, mu, switch_model])
mcmc = pm.MCMC(model)
n_samples = 5000
traces = {}
for var in mcmc.stochastics:
traces[str(var)] = np.zeros(n_samples)
bar = pm.progressbar.progress_bar(n_samples)
bar.update(0)
mcmc.sample(1, progress_bar=False)
for var in mcmc.stochastics:
traces[str(var)][0] = mcmc.trace(var)[-1]
for i in np.arange(1,n_samples):
mcmc.sample(1, progress_bar=False)
bar.update(i)
for var in mcmc.stochastics:
traces[str(var)][i] = mcmc.trace(var)[-1]
if mcmc.trace('switch_model')[-1] == 0: # Gemetric wins
traces['mu'][i] = traces['mu'][i-1] # One step back for the sampler of the Poisson parameter
mu.value = traces['mu'][i-1]
elif mcmc.trace('switch_model')[-1] == 1: # Poisson wins
traces['p'][i] = traces['p'][i-1] # One step back for the sampler of the Geometric parameter
p.value = traces['p'][i-1]
print '\n\n'
traces=pd.DataFrame(traces)
traces['mu'][traces['switch_model'] == 0] = np.nan
traces['p'][traces['switch_model'] == 1] = np.nan
print traces.describe()
traces.plot()
plt.show()
The reason this is so slow is that Python's for loops are pretty slow, especially when they are compared to FORTRAN loops (Which is what PyMC is written in basically.) If you could show more detailed code, it might be easier to see what you are trying to do and to provide faster alternative algorithms.
Actually I found a 'crazy' solution, and I have the suspect to know why it works. I would still like to get an expert opinion on my trick.
Basically if I modify the for loop in the following way, adding a 'reset of the mcmc' every 1000 loops, the sampling fires up again:
for i in np.arange(1,n_samples):
mcmc.sample(1, progress_bar=False)
bar.update(i)
for var in mcmc.stochastics:
traces[str(var)][i] = mcmc.trace(var)[-1]
if mcmc.trace('switch_model')[-1] == 0: # Gemetric wins
traces['mu'][i] = traces['mu'][i-1] # One step back for the sampler of the Poisson parameter
mu.value = traces['mu'][i-1]
elif mcmc.trace('switch_model')[-1] == 1: # Poisson wins
traces['p'][i] = traces['p'][i-1] # One step back for the sampler of the Geometric parameter
p.value = traces['p'][i-1]
if i%1000 == 0:
mcmc = pm.MCMC(model)
In practice this trick erases the traces and the database of the sampler every 1000 steps. It looks like the sampler does not like having a long database, although I do not really understand why. (of course 1000 steps is arbitrary, too short it adds too much overhead, too long it will cause the traces and database to be too long).
I find this hack a bit crazy and definitely not elegant.. does any of the experts or developers have a comment on it? Thank you!

Evolutionary Algorithm to guess a string, messed up by replication

i am working on a python script to test out genetic programming.
As an exercise i have made a simple Script that tries to guess
a string without the whole population part.
My Code is:
# acts as a gene
# it has three operations:
# Mutation : One character is changed
# Replication: a sequencepart is duplicated
# Extinction : A sequencepart is lost
# Crossover : the sequence is crossed with another Sequence
import random
class StringGene:
def __init__(self, s):
self.sequence = s
self.allowedChars = "ABCDEFGHIJKLMOPQRSTUVWXYZ/{}[]*()+-"
def __str__(self):
return self.sequence
def Mutation(self):
x = random.randint(0, len(self.sequence)-1)
r = random.randint(0, len(self.allowedChars)-1)
d = self.sequence
self.sequence = d[:x-1]+ self.allowedChars[r] + d[x:]
def Replication(self):
x1 = random.randint(0, len(self.sequence)-1)
x2 = random.randint(0, len(self.sequence)-1)
self.sequence =self.sequence[:x1]+ self.sequence[x1:x2] + self.sequence[x2:]
self.sequence = self.sequence[:32]
def Extinction(self):
x1 = random.randint(0, len(self.sequence)-1)
x2 = random.randint(0, len(self.sequence)-1)
self.sequence = self.sequence[:x1] + self.sequence[x2:]
def CrossOver(self, s):
x1 = random.randint(0, len(self.sequence)-1)
x2 = random.randint(0, len(s)-1)
self.sequence = self.sequence[:x1+1]+ s[x2:]
#x1 = random.randint(0, len(self.sequence)-1)
#self.sequence = s[:x2 ] + self.sequence[x1+1:]
if __name__== "__main__":
import itertools
def hamdist(str1, str2):
if (len(str2)>len(str1)):
str1, str2 = str2, str1
str2 = str2.ljust(len(str1))
return sum(itertools.imap(str.__ne__, str1, str2))
g = StringGene("Hi there, Hello World !")
g.Mutation()
print "gm: " + str(g)
g.Replication()
print "gr: " + str(g)
g.Extinction()
print "ge: " + str(g)
h = StringGene("Hello there, partner")
print "h: " + str(h)
g.CrossOver(str(h))
print "gc: " + str(g)
change = 0
oldres = 100
solutionstring = "Hello Daniel. Nice to meet you."
best = StringGene("")
res = 100
print solutionstring
while (res > 0):
g.Mutation()
g.Replication()
g.Extinction()
res = hamdist(str(g), solutionstring)
if res<oldres:
print "'"+ str(g) + "'"
print "'"+ str(best) + "'"
best = g
oldres = res
else :
g = best
change = change + 1
print "Solution:" + str(g)+ " " + str(hamdist(solutionstring, str(g))) + str (change)
I have a crude hamming distance as a measure how far the solution string
differs from the current one. However i want to be able to have a varying
length in the guessing, so i introduced replication and deletion of parts
of the string.
Now, however the string grows infinitely and the Solution String is never
found. Can you point out, where i went wrong?
Can you suggest improvements?
cheers
Your StringGene objects are mutable, which means that when you do an operation like best = g, you are making both g and best reference the same object. Since after that first step you only have a single object, every mutation gets applied permanently, whether or not it's successful, and all comparisons between g and best are comparisons between the same object.
You either need to implement a copy operator, or make instances immutable, and have each mutation operator return a modified version of the 'gene'.
Also, if the first mutation fails to improve the string, you set g to best, which is an empty string, throwing away your starting string entirely.
Finally, the canonical test string is "Methinks it is like a weasel".
The simplest thing might be to limit how long the guessed string is allowed to be. Don't allow guesses above a certain length.
I had a look at your code and I'm not good enough in Python to find any bugs, but it might be that you're simply referencing or indexing the array incorrectly, resulting in always adding new characters to the guess-string, so your string is always increasing in length... I don't know if that's the bug, but things like that have happened to me before, so double-check your array indicies. ;)
I think your fitness function is too simple. I would play with using two variables, one the size distance and the other your "hamdist". The further the size difference is, the more it effects the total fitness. So add the two together with some percentage constant.
I'm also not very familiar with python, but it looks to me that this is not what you're doing.
First of all, what you are doing is a genetic algorithm, not genetic programming (which is a related, but a different concept).
I don't know Python, but it looks you have a major problem in your extinction function. As far as I can tell, if x1 > x2 it causes the string to increase in size instead of decreasing (the part between x1 and x2 is effectively doubled). What would happen in the replication function when x1 > x2, I can't tell without knowing Python.
Also keep in mind, that maintaining a population is key to effectively solving problems with genetic algorithms. Crossovers are the essential part of the algorithm, and they make little or no sense if they are not made between population members (also, the more varied the population is, the better, most of the time). The code you presented is dependant on mutations of a single specimen to achieve your expected result, and thus highly unlikely to produce anything useful faster than a simple brute force method.

Resources