简体   繁体   English

如何在IPython中更新HTML块

[英]How to update HTML block in IPython

This is related to another question I posted, but is more specific (and hopefully gets more specific answers). 这与我发布的另一个问题有关,但更具体(希望能得到更具体的答案)。

I am trying to display png images on an IPython notebook, and update the display as the png files are updated. 我正在尝试在IPython笔记本上显示png图像,并在更新png文件时更新显示。

One possible solution is below. 下面是一种可能的解决方案。 Unfortunately, my implementation does not update the file, and creates a new HTML block at the end of the old one. 不幸的是,我的实现没有更新文件,而是在旧文件的末尾创建了一个新的HTML块。 What I want instead, is to replace the old HTML block with the new one -ie replace the content only. 我要代替的是用新的HTML块替换旧的HTML块-即仅替换内容。

As example code, I have two notebooks. 作为示例代码,我有两个笔记本。 One notebook generates pngs and saves them in a figures directory. 一个笔记本生成pngs并将其保存在figures目录中。

import os
import glob
import time
import matplotlib.pyplot as plt
import numpy as np

for ix in range(20):
    N = 50
    x = np.random.rand(N)
    y = np.random.rand(N)
    colors = np.random.rand(N)
    area = np.pi * (15 * np.random.rand(N))**2 # 0 to 15 point radiuses

    fig = plt.figure(figsize=(8,8))
    plt.scatter(x, y, s=area, c=colors, alpha=0.5)
    fig.savefig(os.path.join("figures", "fig1.png"), bbox_inches="tight")
    plt.close(fig)
    time.sleep(3)

A second notebook shows the png s It is supposed top show a single png which updates. 第二个笔记本显示png s。假定顶部显示一个更新的png。 Instead it stacks the same png on itself, every time the png is updated. 相反,它叠加在同一png本身,每次时间png被更新。

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

def get_latest_file_ts(directory="figures", file_name="fig1.png", strip_directory=True):
    """
    Continuously check for modifications to the file file_name in directory. If file has been
    modified after touched_on, return the Unix timestamp of the modification time.
    :param directory: string / the directory where the file is
    :param file_name: string / the file name
    :param strip_directory: boolean /  if True, strip the directory part of the file name
    :return:
    """
    if strip_directory:
        fname = os.path.join(directory, file_name)
    else:
        fname = file_name
    try:
        return os.stat(fname).st_mtime
    except:
        print "FileNotFoundException: Could not find file %s" % fname
        return None


def check_if_modified_file(directory="figures", file_name="fig1.png",
                       touched_on=1420070400, sleep_time=1, strip_directory=True):
    """
    Continuously check for modifications to the file file_name in directory. If file has been
    modified after touched_on, return the Unix timestamp of the modification time.
    :param directory: string / the directory where the file is
    :param file_name: string / the file name
    :param touched_on: float / the Unix timestamp on which the file was last modified
    :param sleep_time: float / wait time between interactions
    :param strip_directory: boolean /  if True, strip the directory part of the file name
    :return:
    """
    if strip_directory:
        fname = os.path.join(directory, file_name)
    else:
        fname = file_name
    while True:
        try:
            latest_touch = os.stat(fname).st_mtime
            if latest_touch == touched_on:
                time.sleep(sleep_time)
            else:
                return latest_touch
        except:
            print "FileNotFoundException: Could not find %s" % fname
            return None

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(directory="figures", file_name="fig1.png")
cnt = 1
while True and cnt < 4:
    timestamp = check_if_modified_file(directory="figures", file_name="fig1.png", touched_on=timestamp, sleep_time=1, strip_directory=True)
    display(HTML(""))
    show_figs(directory="figures", file_name="fig1.png")
    time.sleep(1)
    cnt += 1

(as you can see I have added upper limits on the executions of both the generator and consumer loops) (如您所见,我在生成器循环和使用者循环上都添加了上限)

Any help on how to make widgets update HTML content would be awesome. 关于如何使小部件更新HTML内容的任何帮助都将非常棒。

The problem that you only see the first image is very likely related to caching of the browser. 您仅看到第一个图像的问题很可能与浏览器的缓存有关。 To overcome this issue a simple solution is to add a varying query string to the image src as shown eg here . 为了克服这个问题,一个简单的解决方案是一个变化的查询字符串添加到图片src如图所示如这里 Thus your show_figs method could look like: 因此,您的show_figs方法可能类似于:

import time
def show_figs(directory="figures", file_name="fig1.png"):
    s = """<figure>\n\t<img src="{0}?{1}" alt="The figure" width="304" height="228">\n</figure>""".format(os.path.join(directory, file_name),time.time())
    display(HTML(s))

In combination with the clear_output function you should be able to get your updated image. clear_output函数结合使用,您应该能够获取更新的图像。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM