简体   繁体   English

Jupyter Notebook中的流式网格显示

[英]Streaming Grid Display in Jupyter Notebook

I am trying to display live price updates coming from a redis pubsub channel in a grid in Jupyter. 我正在尝试在Jupyter的网格中显示来自Redis pubsub通道的实时价格更新。 Everytime there is a price update, the message will be added at the end of the grid. 每当有价格更新时,该消息就会添加到表格的末尾。 In order words, a gridview widget will be tied to a Dataframe so everytime it changes, the gridview will change. 换句话说,gridview小部件将绑定到数据框,因此每次更改时,gridview都会更改。 The idea is to get something like this: 想法是得到这样的东西: 在此处输入图片说明

I tried to do that by displaying and clearing the output. 我试图通过显示和清除输出来做到这一点。 However, I am not getting a the streaming grid that gets updated in-place but rather displaying and clearing the output which is very annoying. 但是,我没有得到就地更新的流式网格,而是显示和清除非常烦人的输出。

Here is the output widget in one jupyter cell 这是一个jupyter单元中的输出小部件

import ipywidgets as iw
from IPython.display import display 

o = iw.Output()
def output_to_widget(df, output_widget): 
    output_widget.clear_output()
    with output_widget: 
        display(df)
o

Here is the code to subscribe to redis and get handle the message 这是订阅redis并获取消息的代码

import redis, json, time

r = redis.StrictRedis(host = HOST, password = PASS, port = PORT, db = DB)
p = r.pubsub(ignore_subscribe_messages=True)
p.subscribe('QUOTES')

mdf = pd.DataFrame()
while True:
    message = p.get_message()
    if message:
        json_msg = json.loads(message['data'])
        df = pd.DataFrame([json_msg]).set_index('sym')
        mdf = mdf.append(df)
        output_to_widget(mdf, o)
    time.sleep(0.001)

Try changing the first line of output_to_widget to output_widget.clear_output(wait = True) . 尝试将output_to_widget的第一行更改为output_widget.clear_output(wait = True)

https://ipython.org/ipython-doc/3/api/generated/IPython.display.html https://ipython.org/ipython-doc/3/api/generated/IPython.display.html

I was able to get it to work using Streaming DataFrames from the streamz library. 我能够使用streamz库中的Streaming DataFrames使它正常工作。

Here is the class to emit the data to the streamming dataframe. 这是将数据发送到流数据帧的类。

class DataEmitter:
def __init__(self, pubsub, src):
    self.pubsub = pubsub
    self.src = src
    self.thread = None

def emit_data(self, channel):
    self.pubsub.subscribe(**{channel: self._handler})
    self.thread = self.pubsub.run_in_thread(sleep_time=0.001)

def stop(self):
    self.pubsub.unsubscribe()
    self.thread.stop()    

def _handler(self, message):
    json_msg = json.loads(message['data'])
    df = pd.DataFrame([json_msg])
    self.src.emit(df)

and here is the cell to display the streaming dataframe 这是显示流数据帧的单元格

r = redis.StrictRedis(host = HOST, password = PASS, port = PORT, db = DB)
p = r.pubsub(ignore_subscribe_messages=True)
source = Stream()
emitter = DataEmitter(p, source, COLUMNS)
emitter.emit_data(src='PRICE_UPDATES')

#sample for how the dataframe it's going to look like
example = pd.DataFrame({'time': [], 'sym': []})
sdf = source.to_dataframe(example=example)
sdf

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

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