After testing all four options, I opted to use the last to embed the plot with animation directly in the notebook. Note that this takes ~200KB, where the multiple-image version from JSAnimation + Matplotlib takes roughly ~40MB:
import numpy
import tplot.color
palette = tplot.color.brewer("Set3")
# Generate some fake data
numpy.random.seed(1234)
x = numpy.random.random(500)
y = numpy.random.random(len(x))
marker = numpy.random.choice(["s", "o", "^"], len(x))
color = numpy.array([palette.color(i) for i in range(len(x))])
sort_order = numpy.argsort(marker)
# Create the plot
canvas = tplot.canvas()
axes = canvas.axes(xlabel="f0", ylabel="f1")
scatterplot = axes.scatterplot(x[sort_order], y[sort_order], size=40, marker=marker[sort_order], color=color[sort_order], opacity=0.2, style={"stroke":"none", "stroke-width":0.4})
label = canvas.text(300, 20, "Frame 0", style={"text-anchor":"middle", "font-weight":"bold"})
canvas.legend(
("Triangles", "^", {"fill":"none", "stroke":"black"}),
("Circles", "o", {"fill":"none", "stroke":"black"}),
("Rectangles", "s", {"fill":"none", "stroke":"black"}),
position=(450, 100, 100, 70),
)
def animation(state):
state.set_text(label, "Frame %s" % state.frame())
if state.frame() == 0:
for i in range(len(x)):
state.set_item_style(scatterplot, i, {"opacity" : 0.2, "stroke" : "none"})
else:
state.set_item_style(scatterplot, state.frame()-1, {"opacity" : 1.0, "stroke" : "black"})
canvas.animate(frames=len(x) + 1, callback=animation)
canvas
A cairo backend can be used to generate bitmap images:
import tplot.cairo
tplot.cairo.png(canvas, "test.png")
The cairo backend can also generate multiple animation frames:
import IPython.display
for frame, png in enumerate(tplot.cairo.png_frames(canvas)):
IPython.display.clear_output(wait=True)
print "Writing frame %s" % frame
with open("test-%s.png" % frame, "w") as file:
file.write(png.getvalue())
Writing frame 500
And it can be used to generate video (piping the frames to ffmpeg):
def progress(frame):
IPython.display.clear_output(wait=True)
print "Writing frame %s" % frame
tplot.cairo.mp4(canvas, "test.mp4", progress=progress)
Writing frame 500