Binance websocket实时绘图而不阻塞代码? 进口后台实时更新数据动画情节

问题描述

我正在尝试使用 WebSocket 从 Binance (ETHUSDT) 获取和绘制实时数据。获取数据没问题,但我无法在使用 matplotlib 时获得实时绘图。

代码中,我每次收到消息时都会更新收盘价,并尝试实时绘制这些数据。该图显示在屏幕上,但会阻止进一步的代码执行。我必须手动关闭绘图才能收到下一条消息。

我的问题是:如何在不阻塞代码的情况下实时绘制数据?

import websocket,json
import matplotlib.pyplot as plt
import numpy as np

TradE_SYMBOL = "ETHUSDT"
SOCKET = "wss://stream.binance.com:9443/ws/ethusdt@kline_1m"

closes = np.array([])    

#  CREATING AXIS
plt.axis([0,1000,1])

def on_message(ws,message):
    global closes
    message = json.loads(message)

    candle = message['k']
    close = candle['c']
    closes = np.append(closes,float(close))

    # PLottING HERE
    plt.plot(closes)
    plt.show()


ws = websocket.WebSocketApp(SOCKET,on_message=on_message)
ws.run_forever()

解决方法

Matplotlib 需要在主线程上运行 GUI。

您可以在后台线程上设置 websocket 连接。

进口

import json
import threading
import websocket
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import numpy as np

后台实时更新数据

在线程中运行 websocket 数据更改。

TRADE_SYMBOL = "ETHUSDT"
SOCKET = "wss://stream.binance.com:9443/ws/ethusdt@kline_1m"
closes = np.array([])

def on_message(ws,message):
    global closes
    message = json.loads(message)
    candle = message['k']
    close = candle['c']
    closes = np.append(closes,float(close))

def wsthread(closes):
    ws = websocket.WebSocketApp(SOCKET,on_message=on_message)
    ws.run_forever()

t = threading.Thread(target=wsthread,args=(closes,))
t.start()

动画情节

现在,对 closes 数组的更改进行动画处理。

请参阅 matplotlib.animation.FuncAnimation 的文档。

fig,ax = plt.subplots()
plt.axis([0,100,3000])
x= np.arange(100)
y=[np.nan] * 100
line,= ax.plot(x,y)

def animate(i):
    global y
    # shift left to most recent 100 closing prices
    y[:len(closes)] = closes[-100:]
    line.set_ydata(y)
    return line,def init():
    line.set_ydata([np.nan] * 100)
    return line,anim = FuncAnimation(
    fig,animate,interval=20,init_func=init,blit=True
)

plt.show()