Binance websocket实时绘图没有阻塞代码?

roa*_*r38 6 python matplotlib websocket real-time-updates binance

我正在尝试使用 WebSocket 从币安 (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, 0, 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()
Run Code Online (Sandbox Code Playgroud)

Olu*_*ule 3

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

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

进口

import json
import threading
import websocket
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import numpy as np
Run Code Online (Sandbox Code Playgroud)

后台数据实时更新

在线程中运行 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()
Run Code Online (Sandbox Code Playgroud)

动画情节

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

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

fig, ax = plt.subplots()
plt.axis([0, 100, 0, 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()
Run Code Online (Sandbox Code Playgroud)