2025年1月5日 星期日

Python 學習筆記 : 在 Gradio 與 Streamlit app 上繪製 K 線圖

Python 用來繪製 K 線圖的主要套件是 mplfinance, 它可根據傳入的 OHLCV 價量資料 DataFrame 繪製 K 線, 並提供了豐富的函式可繪製疊圖與副圖, 搭配 Ta-Lib 套件則可在副圖中繪製各種技術指標, 我也寫了一個 kbar.py 模組來簡化畫 K 線圖時的參數設定, 參考 :

但若要同時可在命令列以及 Gradio 與 Streamlit 的 web app 中利用此 kbar.py 繪製 K 線圖的話, 必須改寫之前的 kbar.py, 因為 mplfinance 的 plot() 函式預設傳回 None, 這在命令列執行沒有問題, 但若要在 Gradio 與 Streamlit 的 web app 中使用 mplfinance 畫 K 線圖, 則必須傳入 returnfig=True 參數, 這樣 plot() 函式就會傳回 (fig, ax) 元組, 只要將畫布物件 fig 傳給 Gradio 的 Plot() 函式或 Streamlit 的 pyplot() 函式即可. 修改後的 kbar.py 如下 : 

# kbar.py
import mplfinance as mpf

class KBar():
    def __init__(self, df):
        self.df=df
        self.addplots=[]
    def addplot(self, data, **kwargs):
        plot=mpf.make_addplot(data, **kwargs)
        self.addplots.append(plot)
    def plot(self, embedding=False, **kwargs):
        color=mpf.make_marketcolors(up='red', down='green', inherit=True)   
        font={'font.family': 'Microsoft JhengHei'}   
        style=mpf.make_mpf_style(base_mpf_style='default',
                                 marketcolors=color,
                                 rc=font)
        kwargs['type']='candle'
        kwargs['style']=style
        kwargs['addplot']=self.addplots
        if embedding:
            fig, ax=mpf.plot(self.df, returnfig=True, **kwargs)
            return fig
        else:
            mpf.plot(self.df, **kwargs)

主要是在 KBar 類別的 plot() 方法中添加 embedding 參數, 預設值為 False, 因此在命令列呼叫 plot() 方法時不必傳入 embedding 參數; 但在 Gradio 或 Streamlit app 中則要傳入 embedding=True. 

以下測試使用 yfinance 套件取得台股的 OHLCV 價量資料, 用法參考 :



1. 在 Gradio app 中繪製 K 線圖 : 

Gradio 是 HuggingFace 所維護的開放原始碼 web app 套件, 關於 Gradio 用法參考 :


以下是在 Gradio 中使用 mplfinance 畫 K 線圖範例 :

# gradio_kbar_1.py 
import gradio as gr
import kbar  # 匯入 kbar
import yfinance as yf  # 匯入 Yahoo Finance 
from talib.abstract import RSI, MFI  # 匯入 Ta-Lib 的技術指標類別

def plot_kbar():
    df=yf.download('0050.tw', start='2024-07-01', end='2024-08-21')  # 取得價量資料
    df.columns=[column.lower() for column in df.columns]  # Ta-Lib 要求欄位名稱為全小寫
    kb=kbar.KBar(df)  # 建立 KBar 物件
    rsi=RSI(df)  # 建立 RSI 指標物件
    mfi=MFI(df, timeperiod=14)  # 建立 MFI 指標物件
    if not rsi.isna().all():  # 確保 RSI 有值
        kb.addplot(rsi, panel=2, ylabel='RSI')
    if not mfi.isna().all():  # 確保 MFI 有值
        kb.addplot(mfi, panel=3, ylabel='MFI')
    # 繪製 K 線圖與技術指標副圖    
    fig=kb.plot(volume=True, mav=[3, 5, 7], embedding=True, title='台灣五十')  
    return fig  # 傳回 Figure 物件

iface=gr.Interface(
    fn=plot_kbar,  # 繪製函數
    inputs=[],              # 無需用戶輸入
    outputs=gr.Plot(),      # 輸出為 Gradio 的 Plot 物件
    title='Gradio Candle Chart',
    flagging_mode='never',
    )

iface.launch()

此例在呼叫 KBar 物件的 plot() 方法時傳入 embedding=True 參數, 這樣就會傳回畫布物件 fig, 將其傳回給 Gradio.Plot() 即可在 Gradio app 中顯示 mplfinance 繪製的圖形, 結果如下 :




2. 在 Streamlit app 中繪製 K 線圖 :

Streamlit 是一個輕量好用的 Python web app 套件, 廣泛應用在機器學習, 資料科學, 與人工智慧專案的展示應用上. 下面是在 Streamlit app 中用 mplfinance 繪製 K 線圖範例 : 

# streamlit_kbar_1.py
import streamlit as st
import kbar  # 匯入 kbar
import yfinance as yf  # 匯入 Yahoo Finance
from talib.abstract import RSI, MFI  # 匯入 Ta-Lib 的技術指標類別

df=yf.download('0050.tw', start='2024-07-01', end='2024-08-21')  # 取得價量資料
df.columns=[column.lower() for column in df.columns]  # Ta-Lib 要求欄位名稱為全小寫
kb=kbar.KBar(df)  # 建立 KBar 物件
rsi=RSI(df)  # 建立 RSI 指標物件
mfi=MFI(df, timeperiod=14)  # 建立 MFI 指標物件
if not rsi.isna().all():  # 確保 RSI 有值
    kb.addplot(rsi, panel=2, ylabel='RSI')
if not mfi.isna().all():  # 確保 MFI 有值
    kb.addplot(mfi, panel=3, ylabel='MFI')
# 繪製顯示成交量與 3, 5, 7 日均線之 K 線圖
fig=kb.plot(volume=True, mav=[3, 5, 7], embedding=True)  
st.title("Streamlit Candle Chart")
st.pyplot(fig)

此例在呼叫 KBar 物件的 plot() 方法時傳入 embedding=True 參數, 這樣就會傳回畫布物件 fig, 將其傳給 Streamlit 的 pyplot() 函式即可在 Streamlit app 中顯示 mplfinance 繪製的圖形, 結果如下 :



沒有留言 :