[Solution has been added to the EDIT sections in this post]
2 animated subplots are stacked vertically.
I would like to show a black vertical line through them according to the mouse position.
Up to now I can only completely mess the figure when moving the mouse...
How to clear the old vertical lines between updates?
(Just out of curiosity: since mouse movement control, my PC fan goes crazy when executing the code even without moving the mouse. Is mouse so "calculation expensive"?!?)
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from time import sleep
val1 = np.zeros(100)
val2 = np.zeros(100)
level1 = 0.2
level2 = 0.5
fig, ax = plt.subplots()
ax1 = plt.subplot2grid((2,1),(0,0))
lineVal1, = ax1.plot(np.zeros(100))
ax1.set_ylim(-0.5, 1.5)
ax2 = plt.subplot2grid((2,1),(1,0))
lineVal2, = ax2.plot(np.zeros(100), color = "r")
ax2.set_ylim(-0.5, 1.5)
def onMouseMove(event):
ax1.axvline(x=event.xdata, color="k")
ax2.axvline(x=event.xdata, color="k")
def updateData():
global level1, val1
global level2, val2
clamp = lambda n, minn, maxn: max(min(maxn, n), minn)
level1 = clamp(level1 + (np.random.random()-.5)/20.0, 0.0, 1.0)
level2 = clamp(level2 + (np.random.random()-.5)/10.0, 0.0, 1.0)
# values are appended to the respective arrays which keep the last 100 readings
val1 = np.append(val1, level1)[-100:]
val2 = np.append(val2, level2)[-100:]
yield 1 # FuncAnimation expects an iterator
def visualize(i):
lineVal1.set_ydata(val1)
lineVal2.set_ydata(val2)
return lineVal1,lineVal2
fig.canvas.mpl_connect('motion_notify_event', onMouseMove)
ani = animation.FuncAnimation(fig, visualize, updateData, interval=50)
plt.show()
Edit1
As solved by Ophir:
def onMouseMove(event):
ax1.lines = [ax1.lines[0]]
ax2.lines = [ax2.lines[0]]
ax1.axvline(x=event.xdata, color="k")
ax2.axvline(x=event.xdata, color="k")
Edit2
In case there are more datasets in the same plot such as in:
ax1 = plt.subplot2grid((2,1),(0,0))
lineVal1, = ax1.plot(np.zeros(100))
lineVal2, = ax2.plot(np.zeros(100), color = "r")
ax1.set_ylim(-0.5, 1.5)
each dataset's line is stored in ax1.lines[]
:
ax1.lines[0]
is lineVal1
ax1.lines[1]
is lineVal2
ax1.lines[2]
is the vertical line if you already drew it.This means onMouseMove
has to be changed to:
def onMouseMove(event):
ax1.lines = ax1.lines[:2] # keep the first two lines
ax1.axvline(x=event.xdata, color="k") # then draw the vertical line
replace your onMouseMove
with the following one:
(I used How to remove lines in a Matplotlib plot)
def onMouseMove(event):
ax1.lines = [ax1.lines[0]]
ax2.lines = [ax2.lines[0]]
ax1.axvline(x=event.xdata, color="k")
ax2.axvline(x=event.xdata, color="k")