An error occurred while loading the file. Please try again.
-
Martin Bauer authoredcc52a9f3
jupytersetup.py 5.72 KiB
import pystencils.plot2d as plt
import matplotlib.animation as animation
from IPython.display import HTML
from tempfile import NamedTemporaryFile
import base64
import sympy as sp
__all__ = ['log_progress', 'make_imshow_animation', 'display_animation', 'set_display_mode']
def log_progress(sequence, every=None, size=None, name='Items'):
"""Copied from https://github.com/alexanderkuk/log-progress"""
from ipywidgets import IntProgress, HTML, VBox
from IPython.display import display
is_iterator = False
if size is None:
try:
size = len(sequence)
except TypeError:
is_iterator = True
if size is not None:
if every is None:
if size <= 200:
every = 1
else:
every = int(size / 200) # every 0.5%
else:
assert every is not None, 'sequence is iterator, set every'
if is_iterator:
progress = IntProgress(min=0, max=1, value=1)
progress.bar_style = 'info'
else:
progress = IntProgress(min=0, max=size, value=0)
label = HTML()
box = VBox(children=[label, progress])
display(box)
index = 0
try:
for index, record in enumerate(sequence, 1):
if index == 1 or index % every == 0:
if is_iterator:
label.value = '{name}: {index} / ?'.format(
name=name,
index=index
)
else:
progress.value = index
label.value = u'{name}: {index} / {size}'.format(
name=name,
index=index,
size=size
)
yield record
except:
progress.bar_style = 'danger'
raise
else:
progress.bar_style = 'success'
progress.value = index
label.value = "{name}: {index}".format(
name=name,
index=str(index or '?')
)
VIDEO_TAG = """<video controls width="80%">
<source src="data:video/x-m4v;base64,{0}" type="video/mp4">
Your browser does not support the video tag.
</video>"""
def __animation_to_html(animation, fps):
if not hasattr(animation, 'encoded_video'):
with NamedTemporaryFile(suffix='.mp4') as f:
animation.save(f.name, fps=fps, extra_args=['-vcodec', 'libx264', '-pix_fmt',
'yuv420p', '-profile:v', 'baseline', '-level', '3.0'])
video = open(f.name, "rb").read()
animation.encoded_video = base64.b64encode(video).decode('ascii')
return VIDEO_TAG.format(animation.encoded_video)
def make_imshow_animation(grid, grid_update_function, frames=90, **_):
from functools import partial
fig = plt.figure()
im = plt.imshow(grid, interpolation='none')
def update_figure(*_, **kwargs):
image = kwargs['image']
image = grid_update_function(image)
im.set_array(image)
return im,
return animation.FuncAnimation(fig, partial(update_figure, image=grid), frames=frames)
# ------- Version 1: Embed the animation as HTML5 video --------- ----------------------------------
def display_as_html_video(animation, fps=30, show=True, **_):
try:
plt.close(animation._fig)
res = __animation_to_html(animation, fps)
if show:
return HTML(res)
else:
return HTML("")
except KeyboardInterrupt:
pass
# ------- Version 2: Animation is shown in extra matplotlib window ----------------------------------
def display_in_extra_window(*_, **__):
fig = plt.gcf()
try:
fig.canvas.manager.window.raise_()
except Exception:
pass
plt.show()
# ------- Version 3: Animation is shown in images that are updated directly in website --------------
def display_as_html_image(animation, show=True, iterations=10000, *args, **kwargs):
from IPython import display
try:
if show:
animation._init_draw()
for i in range(iterations):
if show:
fig = plt.gcf()
display.display(fig)
animation._step()
if show:
display.clear_output(wait=True)
except KeyboardInterrupt:
display.clear_output(wait=False)
# Dispatcher
animation_display_mode = 'image_update'
display_animation_func = None
def display_animation(*args, **kwargs):
from IPython import get_ipython
ipython = get_ipython()
if not ipython:
return
if not display_animation_func:
raise Exception("Call set_display_mode first")
return display_animation_func(*args, **kwargs)
def set_display_mode(mode):
from IPython import get_ipython
ipython = get_ipython()
if not ipython:
return
global animation_display_mode
global display_animation_func
animation_display_mode = mode
if animation_display_mode == 'video':
ipython.magic("matplotlib inline")
display_animation_func = display_as_html_video
elif animation_display_mode == 'window':
ipython.magic("matplotlib qt")
display_animation_func = display_in_extra_window
elif animation_display_mode == 'image_update':
ipython.magic("matplotlib inline")
display_animation_func = display_as_html_image
else:
raise Exception("Unknown mode. Available modes 'image_update', 'video' and 'window' ")
def activate_ipython():
from IPython import get_ipython
ipython = get_ipython()
if ipython:
set_display_mode('image_update')
ipython.magic("config InlineBackend.rc = { }")
ipython.magic("matplotlib inline")
plt.rc('figure', figsize=(16, 6))
sp.init_printing()
activate_ipython()