2

I made a plot animation. The relevant part of my code is this:

#Create Gif Animation
upd = 24
progression = 10    #x-axis
xstart = -5
xlim = [xstart,5]
ylim = [-70,80]
line, = ax.plot(xlim, ylim, 'r-', linewidth=2)

def update(ii):
    line.set_xdata(xstart + (ii)/upd)
    return line
anim = FuncAnimation(fig, update, frames=np.arange(0, progression * upd) + 1, interval = (1000/upd)*progression)
print('Progress... Creating Animation')
anim.save('/home/artur/Desktop/anim.gif', writer='imagemagick', fps=upd)

-

line, = ax.plot(xlim, ylim, 'r-', linewidth=2)

creates a vertical line and

def update(ii):
    line.set_xdata(xstart + (ii)/upd)
    return line
anim = FuncAnimation(fig, update, frames=np.arange(0, progression * upd) + 1, interval = (1000/upd)*progression)

creates the animation, handles the update rate etc. The red line represents time progression.

enter image description here

Now, how do I make this work for two stacked graphs? How do I draw the same line just over both ax objects?

enter image description here

In this case two pd.DataFrames are plotted on two axis. I hope I could make my problem clear.

Edit

This problem was described here already but HYRY provided a much better solution.

#Create Gif Animation
upd = 1
progression = 20    #x-axis
xstart = -10
xlim, ylim = [xstart,10], [0, 40]
xlim2, ylim2 = [xstart,10], [-70, 70]
line = plt.Line2D([0, 0],
                  [axes[1].get_position().y0,
                   axes[0].get_position().y1],
                  color="red", ls="-",
                  transform=BlendedGenericTransform(axes[0].transData, fig.transFigure))
def update(ii):
    xdata = xstart + (ii)/upd
    line.set_xdata(xdata)
    fig.add_artist(line)
    return line
anim = FuncAnimation(fig, update, frames=np.arange(0, progression * upd) + 1, interval = (1000/upd)*progression)
print('Progress: Creating Animation')
anim.save('/home/artur/Desktop/anim3.gif', writer='imagemagick', fps=upd)

enter image description here

Artur Müller Romanov
  • 4,417
  • 10
  • 73
  • 132
  • You can pass `clip_on=False` to `plot`, which allows you to extend the line over the axes. Alternatively, you could use `ConnectionPatch` https://matplotlib.org/3.1.0/api/_as_gen/matplotlib.patches.ConnectionPatch.html – Ardweaden Jul 26 '19 at 07:03

1 Answers1

1

you can use axvline() to draw a vertical line over the Y span of an Axes.

If you really want to draw a hole line over two Axes, then you can create a Line2D object and add it to the figure.

To use different transform for X and Y direction, you can use BlendedGenericTransform.

Here is the code for the two methods:

import numpy as np
from matplotlib.transforms import BlendedGenericTransform
fig, axes = pl.subplots(2, 1, sharex=True)
t = np.linspace(0, 10)
axes[0].plot(t, np.sin(t))
axes[1].plot(t, np.cos(t))
vlines = [ax.axvline(5, color="green", ls="dotted") for ax in axes]
fig_line = pl.Line2D([0, 0], [axes[1].get_position().y0, axes[0].get_position().y1], 
                     color="red", ls="dotted",
                     transform=BlendedGenericTransform(axes[0].transData, fig.transFigure))
fig_line.set_xdata([6.0, 6.0])
fig.add_artist(fig_line)
HYRY
  • 94,853
  • 25
  • 187
  • 187