Automatically update image in IPython notebook

二次信任 提交于 2019-12-11 12:03:04

问题


I have a number of png images that get updated somewhat regularly and want to include them in an IPython notebook, having them automatically updated in the notebook.

I thought I could do it by adapting the following matplotlib example:

import numpy as np
import matplotlib.pyplot as plt
from IPython import display
import time

%matplotlib inline

plt.ion()

fig = plt.figure()
ax = fig.gca()
fig.show()

for i in range(10):
    mu, sigma = 200, 25
    x = mu + sigma*np.random.normal(loc=2, scale=1, size=50)

    if i == 0:
        barpl = plt.bar(range(len(x)), x)
    else:
        for rect, h in zip(barpl, x):
            rect.set_height(h)
    display.clear_output(wait=True)
    display.display(plt.gcf())
    time.sleep(2)

So I used this snippet:

from IPython import display
import os

timestamp = get_latest_file_ts(directory="figures", file_name="fig1.png", strip_directory=True)

display.Image(os.path.join("figures", "fig1.png"))

while True:
    timestamp = check_if_modified_file(directory="figures", file_name="fig1.png", touched_on=timestamp, sleep_time=1, strip_directory=True)
    display.clear_output(wait=True)
    display.Image(os.path.join("figures", "fig1.png"))

But no output is produced. Apparently statements that follow Image() override the display (and I am unsure this was supposed to work even without this happening). In the above code, get_latest_file_ts() fetches the timestamp of the latest version of the image, and check_if_modified_file() keeps checking for a newer timestamp on the same file, and returns the newer timestamp when it finds it.

[UPDATE] I found a partial way to do this using widgets, but my implementation creates a new HTML block at the end of the old one. What I want instead, is to replace the old HTML block with the new one -i.e. replace the content only.

Here is the code that stacks one HTML behind the other:

from IPython.html.widgets import interact, interactive, fixed
from IPython.html import widgets
from IPython.display import clear_output, display, HTML

def show_figs(directory="figures", file_name="fig1.png"):
    s = """<figure>\n\t<img src="%s" alt="The figure" width="304" height="228">\n</figure>""" % os.path.join(directory, file_name)
    display(HTML(s))

timestamp = get_latest_file_ts(directory="figures", file_name="fig1.png", strip_directory=True)
show_figs()
while True:
    timestamp = check_if_modified_file(directory="figures", file_name="fig1.png", touched_on=timestamp, sleep_time=1, strip_directory=True)
    show_figs()

I would really appreciate a way to get the second or third snippets above to work, or some other method to get this done.


回答1:


The problem with your first attempt is that you just create the image object (display.Image) but not display it! To display the image, use the display.display function which is similar to python's print statement but uses the IPython display machinery. Your call should look like

display.display(display.Image(os.path.join("figures", "fig1.png")))

Some background

If you just create the image object, the returned object is displayed only if it is the last command in the execution block -> the image object is the "OUT" value. Note, that it is placed next to the Out[x] prompt. In this particular case, the display machinery automatically displays it.

In your case you create the image within a loop without capturing it. It is not the last command in the execution block, thus the image object is not returned as "out" value and not displayed automatically. Latter has to be manually done.

This is totally the same with any python object. If you want to see it you have to print (display) it or (in IPython) make sure it is return as "OUT".



来源:https://stackoverflow.com/questions/30989509/automatically-update-image-in-ipython-notebook

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!