Coneain
Coneain

Reputation: 308

how to plot asynchronously in matplotlib?

1. Background

I draw a quadratic function curve (ax^2+bx+c, a>0) which has a minimum value, and I use an iterable method to search this value. After every step, there generates a point. What I want to do is draw this point dynamically.

2. Pseudocode

f(x)=ax^2+bx+c, a>0
g(t) is the mentioned method which is used to search the minimum value

plot f(x)
plot initial point (x0,y0)

for t in range(10000):
  new_x,new_y = g(t)

  move (x0,y0) to new position (new_x,new_y)

3. Solution

3.1 interactive plot

3.1.1 Example
import matplotlib
import matplotlib.pyplot as plt
import numpy as np

matplotlib.use("TkAgg")

plt.figure()
plt.grid(True)
plt.ion()

ft = np.linspace(0, 100, 1000)
plt.plot(ft, ft ** 2 + 1, c='r')
for t in range(100):
    plt.scatter(t, t ** 2 + 1, marker='.', c='b')

    plt.pause(1e-6)

plt.ioff()
plt.show()
3.1.2 Note
  1. It works, but it runs slowly.
  2. This method generates a track, which is redundant.

3.2 Animation

3.2.1 Example

import numpy as np
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.animation as animation

matplotlib.use("TkAgg")
def update_points(num):

    point_ani.set_data(x[num], y[num])
    return point_ani,


x = np.linspace(0, 100, 1000)
y = x**2+1

fig = plt.figure(tight_layout=True)
plt.plot(x, y)
point_ani, = plt.plot(x[0], y[0], "ro")
plt.grid(ls="--")
ani = animation.FuncAnimation(fig,
                              update_points,
                              interval=1,
                              blit=True)
plt.show()

print('finish')

3.2.2 Note

This method works without any track, but the entire moving path of point has to be known before drawing.

So, suppose there is an artist, it draws every time it receives a new point; it waits if no point is received. How to implement?

Upvotes: 2

Views: 2215

Answers (1)

Sameeresque
Sameeresque

Reputation: 2602

Using the Gradient descent method described in this Wikipedia link, here is the Python implementation, and the animation indicating the new "minima" at each step.

import numpy as np
import matplotlib.pyplot as plt
###initializing the parameters##################
next_x = -5  # We start the search at x=-5
gamma = 0.01  # Step size multiplier
precision = 0.000001  # Desired precision of result
max_iters = 10000  # Maximum number of iterations
########setup the plot################
fig, ax = plt.subplots()
ax.set_ylabel('y')
ax.set_xlabel('x')
ft = np.linspace(-50, 50, 1000)
line, = ax.plot(ft, ft**2 + 1,c='r',linestyle='-')
ax.set_title('Gradient descent showing the minima at each step')
plt.ion()   # set interactive mode
plt.show()
#################################
a=1
b=0
c=1
# Derivative function
def df(a,b,c,x):
    return 2*a*x + b
# function
def f(a,b,c,x):
    return a*x**2+b*x+c
for _ in range(max_iters):
    current_x = next_x
    next_x = next_x - gamma * df(a,b,c,current_x)
    step = next_x - current_x
    #do the plotting after setting up canvas
    plt.gcf().canvas.draw()
    #show the new minima as a '.'
    line, = ax.plot(next_x,f(a,b,c,next_x),'.',c='black')
    plt.pause(0.1)
    #remove the track
    line.remove()
    del line
    if abs(step) <= precision:
        break
print ("Minima at :{}".format(next_x))

animated

Upvotes: 1

Related Questions