2026年5月1日 星期五

Python 學習筆記 : 用 plotly 繪製 K 線圖 (二)

在前一篇測試中已對 Plotly 的 K 線圖類別 plotly.graph_objects.CandleStick 的用法有了基本了解, 本篇旨在利用 Figure 物件的 add_trace() 方法在畫布上添加子圖 (例如成交量或 RSI 等技術指標), 同時透過 plotly.subplots.make_subplot() 函式來規劃畫布上的子圖佈局. 

本系列測試文章索引參考 :



4. 添加成交量子圖 : 

要在畫布上繪製子圖有兩種方式, 第一種是使用較低階的絕對領域 (Domain) 劃分法, 此方法須手動切割 Y 軸空間自行布局, 好處是可以客製化布局, 缺點是維護難度較高, 調整彈性較差, 在 "最強 AI 投資分析" 這本書的第四章就是採用此方法, 參考 :


第二種方式是使用 plotly.subplots.make_subplot() 函式, 這是採用網格系統來進行排版的高階 API, 只要指定子圖的列 (row) 與欄 (col), Plotly 會在底層自動計算所有圖表的高度, 對齊與間距, 是一種較簡易的低耦合設計. 

首先匯入子圖布局函式 make_subplots() :

from plotly.subplots import make_subplots 

make_subplots() 的參數說明如下表 :


 參數名稱  說明
 rows  子圖的列數(預設為 1)
 cols  子圖的欄數(預設為 1)
 shared_xaxes  是否共用 X 軸(True / False / 'all' / 'rows' / 'columns')
 shared_yaxes  是否共用 Y 軸(True / False / 'all' / 'rows' / 'columns')
 start_cell  子圖起始位置('top-left' 或 'bottom-left')
 subplot_titles  每個子圖的標題(list)
 specs  自訂每個子圖的型態與配置(例如 type='xy', 'domain', 'scene' 等)
 row_heights  各列高度比例(list,例如 [0.7, 0.3])
 column_widths  各欄寬度比例(list,例如 [0.6, 0.4])
 horizontal_spacing  子圖之間的水平間距(0~1)
 vertical_spacing  子圖之間的垂直間距(0~1)
 insets  設定內嵌子圖(inset charts)的位置與大小
 column_titles  每一欄的標題(list)
 row_titles  每一列的標題(list)
 x_title  整體 X 軸標題
 y_title  整體 Y 軸標題
 figure  將子圖加入既有的 Figure 物件


其中最常用的參數是 rows, cols, shared_xaxes, vertical_spacing, 與 row_heights 等. 

下列程式將畫布做 2 列 1 欄布局, 第一列高度占 70% 放 K 線圖 trace; 第二列高度占 30% 放成交量長條圖 (有做漲紅跌綠顏色設定) :

# plotly_candlestick_5.py
import yfinance as yf
import plotly.graph_objects as go
import pandas as pd
from plotly.subplots import make_subplots

if __name__ == "__main__":
    df=yf.download('0050.tw', start='2026-03-01', end='2026-04-30', auto_adjust=True)
    df.columns=df.columns.map(lambda x: x[0])

    # === 建立子圖 (2 rows: 上列放 K 線圖,下列放成交量) ===
    fig=make_subplots(
        rows=2,
        cols=1,
        shared_xaxes=True,
        vertical_spacing=0.03,
        row_heights=[0.7, 0.3]   # 列高度占比
        )

    # === K 線圖 ===
    price=go.Candlestick(
        x=df.index,
        open=df['Open'],
        high=df['High'],
        low=df['Low'],
        close=df['Close'],
        increasing_line_color='red',
        decreasing_line_color='green',
        name='Price'
        )
    fig.add_trace(price, row=1, col=1)   # K 線圖放 row 1

    # === 成交量顏色(漲紅跌綠) ===
    colors=['red' if c >= o else 'green' for c, o in zip(df['Close'], df['Open'])]
    volume=go.Bar(
        x=df.index,
        y=df['Volume'],
        marker_color=colors,
        name='Volume'
        )
    fig.add_trace(volume, row=2, col=1)  # 成交量放 row 2

    # === 移除非交易日 ===
    date_range=pd.date_range(start=df.index.min(), end=df.index.max())
    breaks=date_range[~date_range.isin(df.index)]
    breaks_list=breaks.tolist()
    fig.update_xaxes(
        rangebreaks=[{'values': breaks_list}],
        showspikes=True,
        spikethickness=1,
        spikecolor='blue',
        spikedash='dot',
        spikemode='across'
        )

    # === Y 軸 spike(兩個子圖都套用)===
    fig.update_yaxes(
        showspikes=True,
        spikethickness=1,
        spikecolor='blue',
        spikedash='dot',
        spikemode='across'
        )

    # === Layout ===
    fig.update_layout(
        title='台灣五十 (0050) K線 + 成交量',
        width=800,
        height=700,
        xaxis_rangeslider_visible=False,
        hovermode='x unified'   # 很重要:跨子圖同步 hover
        )

    fig.show()

注意, 之前沒有子圖時是呼叫 fig=go.Figure() 建立 Figure 物件, 但此處是用 make_subplots() 來建立. 其次, 有子圖的情況時, hovermode 參數務必要設為 'x unified', 否則會有多個 tooltip 分散, 以及子圖之間不同步問題 (無子圖時因所有 trace 都在同一個座標系故不會有這些問題). 

結果如下 :






5. 添加技術指標子圖 : 

接下來要在成交量下面添加 MACD 指標, 使用 pandas-ta 套件計算, 參考 :


這樣畫布上總共有三個子圖 : K 線圖, 成交量, 與 MACD. 

程式碼如下 :

# plotly_candlestick_6.py
import yfinance as yf
import plotly.graph_objects as go
import pandas as pd
import pandas_ta as ta
from plotly.subplots import make_subplots

if __name__ == "__main__":
    # === 下載資料 ===
    df=yf.download('0050.tw', start='2026-03-01', end='2026-04-30', auto_adjust=True)
    df.columns=df.columns.map(lambda x: x[0])

    # === 計算 MACD(pandas-ta)===
    macd=ta.macd(df['Close'], fast=12, slow=26, signal=9)

    # pandas-ta 會回傳三欄 :contentReference[oaicite:0]{index=0}
    df['MACD']=macd['MACD_12_26_9']
    df['MACDs']=macd['MACDs_12_26_9']   # signal
    df['MACDh']=macd['MACDh_12_26_9']   # histogram

    # === 建立子圖 ===
    fig=make_subplots(
        rows=3,
        cols=1,
        shared_xaxes=True,
        vertical_spacing=0.02,
        row_heights=[0.5, 0.2, 0.3]
        )

    # =====================
    # 1. K線圖
    # =====================
    fig.add_trace(
        go.Candlestick(
            x=df.index,
            open=df['Open'],
            high=df['High'],
            low=df['Low'],
            close=df['Close'],
            increasing_line_color='red',
            decreasing_line_color='green',
            name='Price'
            ),
        row=1, col=1
        )

    # =====================
    # 2. 成交量
    # =====================
    vol_colors=['red' if c >= o else 'green'
                  for c, o in zip(df['Close'], df['Open'])]
    fig.add_trace(
        go.Bar(
            x=df.index,
            y=df['Volume'],
            marker_color=vol_colors,
            name='Volume'
            ),
        row=2, col=1
        )

    # =====================
    # 3. MACD
    # =====================
    # Histogram(紅綠柱)
    macd_colors=['red' if v >= 0 else 'green' for v in df['MACDh']]
    fig.add_trace(
        go.Bar(
            x=df.index,
            y=df['MACDh'],
            marker_color=macd_colors,
            name='MACD Hist'
            ),
        row=3, col=1
        )

    # MACD 線
    fig.add_trace(
        go.Scatter(
            x=df.index,
            y=df['MACD'],
            line=dict(color='blue'),
            name='MACD'
            ),
        row=3, col=1
        )
    # Signal 線
    fig.add_trace(
        go.Scatter(
            x=df.index,
            y=df['MACDs'],
            line=dict(color='orange'),
            name='Signal'
            ),
        row=3, col=1
        )

    # =====================
    # 移除非交易日
    # =====================
    date_range=pd.date_range(start=df.index.min(), end=df.index.max())
    breaks=date_range[~date_range.isin(df.index)]
    fig.update_xaxes(
        rangebreaks=[{'values': breaks.tolist()}],
        showspikes=True,
        spikethickness=1,
        spikecolor='blue',
        spikedash='dot',
        spikemode='across'
        )
    fig.update_yaxes(
        showspikes=True,
        spikethickness=1,
        spikecolor='blue',
        spikedash='dot',
        spikemode='across'
        )

    # =====================
    # Layout
    # =====================
    fig.update_layout(
        title='0050 台灣五十 - K線 + 成交量 + MACD',
        width=900,
        height=800,
        xaxis_rangeslider_visible=False,
        hovermode='x unified'
        )

    fig.show()

注意, MACD 的紅綠柱, MACD 線與信號線都是要畫在 row=3 子圖疊在一起, 結果如下 :




Python 學習筆記 : 用 plotly 繪製 K 線圖 (一)

雖然 mplfinance 套件可以繪製精美的 K 線圖, 但那是沒有互動效果的靜態圖表, 也無法直接佈署在網頁應用中. 繪製互動式 K 線圖可以使用 plotly 套件的低階繪圖模組 graph_objects  (注意, plotly.express 模組沒有繪製 K 線圖功能, 它主要用來快速繪製常見統計圖表).

本系列測試文章索引參考 :


關於 plotly.graph_objects 用法參考 :



1. 新版 (v4.0+) Plotly 的輸出方式 : 

Plotly 的繪圖輸出方式已與以往不同, v4.0 之前的 Plotly 主要商業模式是線上繪圖, 預設會將圖表上傳到他們的雲端伺服器 (Chart Studio), 如果要離線繪圖必須明確呼叫 plotly.offline 模組; 然而 Plotly v4 對原本分散的繪圖方式 (離線 vs 雲端) 進行重整, 採取了離線優先原則, 繪製圖表時不需要再區分線上或離線 (原本的雲端功能被拆分出去變成一個獨立的套件 chart-studio), 改為直接呼叫 Figure 物件的方法來處理 :
  • fig.show() : 用於開發過程中的快速預覽 (依據環境自動選擇方式)
  • fig.write_html() : 用於產生最終的報告檔案 (於網頁中繪製圖表)
當呼叫 fig.show() 時, Plotly 會自動偵測程式是在 VS Code, Jupyter Notebook, Google Colab 還是純 Python 腳本中執行, 並選擇最適合的方式來顯示圖表. plotly.offline 的功能已經被 fig.write_html() 取代了, 但為了向下相容, Plotly 官方目前仍保留對 plotly.offline.plot() 的支援. 

注意, fig.write_html() 只是單純輸出 HTML 檔, 不會自動開啟瀏覽器顯示繪圖結果, 如果希望在存檔後順便開啟瀏覽器展示繪製結果, 可以傳入 auto_open=True 參數 (預設 False), 例如 :

fig.write_html("plot.html", auto_open=True)  

或者先呼叫 write_html() 再呼叫 show() :

fig.write_html("plot.html")
fig.show()

除此之外, Plotly v4.0 也把以前的獨立套件 plotly_express 納入主套件中成為 plotly.express 模組, 確立了 Plotly 未來高階 API 使用 plotly.express; 低階 API 使用 plotly. graph_objects 的雙軌應用模式. 


2. 建立 CandleStick 物件繪製 K 線圖 : 

首先匯入 plotly.graph_objects 模組, 通常取簡名為 go :

import plotly.graph_objects as go  

plotly.graph_objects 模組中有一個 Candlestick 用來繪製 K 線圖 : 

>>> import plotly.graph_objects as go   
>>> dir(go)   
['AngularAxis', 'Annotation', 'Annotations', 'Bar', 'Barpolar', 'Box', 'Candlestick', 'Carpet', 'Choropleth', 'Choroplethmap', 'Choroplethmapbox', 'ColorBar', 'Cone', 'Contour', 'Contourcarpet', 'Contours', 'Data', 'Densitymap', 'Densitymapbox', 'ErrorX', 'ErrorY', 'ErrorZ', 'Figure', 'FigureWidget', 'Font', 'Frame', 'Frames', 'Funnel', 'Funnelarea', 'Heatmap', 'Histogram', 'Histogram2d', 'Histogram2dContour', 'Histogram2dcontour', 'Icicle', 'Image', 'Indicator', 'Isosurface', 'Layout', 'Legend', 'Line', 'Margin', 'Marker', 'Mesh3d', 'Ohlc', 'Parcats', 'Parcoords', 'Pie', 'RadialAxis', 'Sankey', 'Scatter', 'Scatter3d', 'Scattercarpet', 'Scattergeo', 'Scattergl', 'Scattermap', 'Scattermapbox', 'Scatterpolar', 'Scatterpolargl', 'Scattersmith', 'Scatterternary', 'Scene', 'Splom', 'Stream', 'Streamtube', 'Sunburst', 'Surface', 'Table', 'Trace', 'Treemap', 'Violin', 'Volume', 'Waterfall', 'XAxis', 'XBins', 'YAxis', 'YBins', 'ZAxis', 'bar', 'barpolar', 'box', 'candlestick', 'carpet', 'choropleth', 'choroplethmap', 'choroplethmapbox', 'cone', 'contour', 'contourcarpet', 'densitymap', 'densitymapbox', 'funnel', 'funnelarea', 'heatmap', 'histogram', 'histogram2d', 'histogram2dcontour', 'icicle', 'image', 'indicator', 'isosurface', 'layout', 'mesh3d', 'ohlc', 'parcats', 'parcoords', 'pie', 'sankey', 'scatter', 'scatter3d', 'scattercarpet', 'scattergeo', 'scattergl', 'scattermap', 'scattermapbox', 'scatterpolar', 'scatterpolargl', 'scattersmith', 'scatterternary', 'splom', 'streamtube', 'sunburst', 'surface', 'table', 'treemap', 'violin', 'volume', 'waterfall']

呼叫 Candlestick 類別的建構式 Candlestick() 會建立一個 Candlestick 物件, 這在 Plotly 文件中被稱為 Trace 物件 (畫布上的數據內容, 例如一組 K 線). 一個完整的 Plotly 圖表 (Figure) 是由 data 和 layout 兩大部分組成的, 而 Candlestick 物件就是放在 data 清單中的一個成員. 

Candlestick() 建構式的參數如下表 : 


 參數名稱  說明
 x  時間序列數據(通常為日期字串或 datetime 物件)。
 open  開盤價序列 (Open prices)。
 high  最高價序列 (High prices)。
 low  最低價序列 (Low prices)。
 close  收盤價序列 (Close prices)。
 increasing_line_color  上漲時 K 線外框與影線的顏色(例:'red')。
 decreasing_line_color  下跌時 K 線外框與影線的顏色(例:'green')。
 name  此數據序列在圖例中顯示的名稱。
 text  滑鼠懸停時顯示的額外文字內容。
 hoverinfo  設定懸停顯示的資訊內容(如 'all', 'x+y' 等)。
 opacity  設定 K 線圖層的透明度(0.0 到 1.0)。
 whiskerwidth  設定上下影線相對於 K 線實體寬度的比例。


其中前 7 個參數 x, open, high, low, close, 以及 increasing_line_color 與 decreasing_line_color (漲跌顏色, 漲紅跌綠) 最常用, 例如 : 

>>> price=go.Candlestick( 
    x=['2026-05-01', '2026-05-02'],
    open=[100, 110],
    high=[115, 120],
    low=[95, 105],
    close=[110, 105],
    increasing_line_color='red',
    decreasing_line_color='green'    
    )
>>> type(price)  
<class 'plotly.graph_objs._candlestick.Candlestick'>   

這樣就建立了一個 CandleStick 物件了. 接下來只要將此 trace 放入串列, 傳給 go.Figure() 的 data 參數即可建立 Figure 畫布物件 : 

>>> fig=go.Figure(data=[price])   
>>> type(fig)   
<class 'plotly.graph_objs._figure.Figure'>  

最後呼叫 fig.show() 即可展示所繪製之圖表 :

>>> fig.show()   

fig.show() 會開啟一個 127.0.0.1:port 的網頁來繪製圖表 :




可見當滑鼠移到 K 棒上時就會動態地彈出其 OHLC 價格資訊. 注意, Plotly 預設會在 K 線圖底下開啟一個範圍滑桿 (RangeSlider 物件), 可透過滑動或縮放來觀察不同時段的價格細節. 若想取消此預設之範圍滑桿, 可呼叫 fig.update_layout() 並傳入 xaxis_rangeslider_visible=False 參數 :

>>> fig.update_layout(xaxis_rangeslider_visible=False)   
Figure({
    'data': [{'close': [110, 105],
              'decreasing': {'line': {'color': 'green'}},
              'high': [115, 120],
              'increasing': {'line': {'color': 'red'}},
              'low': [95, 105],
              'open': [100, 110],
              'type': 'candlestick',
              'x': [2026-05-01, 2026-05-02]}],
    'layout': {'template': '...', 'xaxis': {'rangeslider': {'visible': False}}}
})
>>> fig.show()  




fig.update_layout() 是 Plotly 中最核心的佈局控制方法, 它負責處理圖表內除了數據本身以外的所有視覺元素, 例如標題, 座標軸, 圖例及畫布大小等, 常用參數如下 : 


 參數名稱  說明
 title  圖表標題。可傳入字串或 dict(包含 text, font, x, y 等屬性)。預設為 None。
 width / height  設定畫布的寬度與高度(像素)。預設通常隨容器自動縮放。
 xaxis / yaxis  設定座標軸屬性(如標題、範圍、網格)。例如 xaxis_title='時間'。
 xaxis_rangeslider_visible  設定 X 軸下方的範圍滑桿是否顯示。預設值 True。
 showlegend  是否顯示圖例。預設值:當有多組數據序列時為 True。
 legend  設定圖例的位置與外觀(如 x, y 位置、orientation 'h' 或 'v')。
 margin  設定圖表與邊界的距離。傳入 dict(l, r, t, b) 分別代表左、右、上、下邊距。
 template  設定圖表主題(如 'plotly_dark', 'ggplot2', 'seaborn' 等)。預設為 'plotly'。
 hovermode  設定懸停資訊的觸發模式('x', 'y', 'closest', False)。預設為 'closest'。
 font  設定圖表全域字體(family, size, color)。預設字體依環境而定。
 paper_bgcolor  設定整張畫布(紙張)的背景顏色。預設為 '#fff'。
 plot_bgcolor  設定繪圖區域(座標軸內)的背景顏色。預設為 '#E5ECF6'。


這些參數中以 title, width, heigh, 與 showlegend 等最常用. 

下面範例從 yfinance 取得股價資料後用 plotly 繪製 K 線圖 :

# plotly_candlestick_1.py
import yfinance as yf
import plotly.graph_objects as go

if __name__ == "__main__":
    df=yf.download('0050.tw', start='2026-03-01', end='2026-04-30', auto_adjust=True)
    df.columns=df.columns.map(lambda x: x[0])
    price=go.Candlestick(
        x=df.index,
        open=df['Open'],
        high=df['High'],
        low=df['Low'],
        close=df['Close'],
        increasing_line_color='red',
        decreasing_line_color='green'    
        )
    fig=go.Figure(data=[price])
    fig.update_layout(
        title='台灣五十股價',
        width=800,
        height=600,
        xaxis_rangeslider_visible=False
        )
    fig.show() 

此處以 width 與 height 參數設定畫布尺寸, 以 title 設定圖表標題, 結果如下 :




3. 移除 K 線圖中的非交易日空格 : 

仔細看上面範例中的 K 線圖, 會發現例假日股市休息, 從 yfinance 取得的收盤資料都會跳過這些日期, 只傳回交易日之資料, 但 Plotly 在繪製 K 線圖時會自動把 X 軸的日期序列補齊, 但因為無 OHLC 欄位值, 所以 K 棒為空格, 看起來不連續, 這可以透過呼叫 fig.update_xaxes() 方法, 並傳入rangebreaks 參數來移除, 其值為一個非交易日的日期串列的字典 (鍵為 values), 例如 :

# plotly_candlestick_2.py
import yfinance as yf
import plotly.graph_objects as go
import pandas as pd  

if __name__ == "__main__":
    df=yf.download('0050.tw', start='2026-03-01', end='2026-04-30', auto_adjust=True)
    df.columns=df.columns.map(lambda x: x[0])
    price=go.Candlestick(
        x=df.index,
        open=df['Open'],
        high=df['High'],
        low=df['Low'],
        close=df['Close'],
        increasing_line_color='red',
        decreasing_line_color='green'    
        )
    fig=go.Figure(data=[price])
    # 移除 X 軸的非交易日
    date_range=pd.date_range(start=df.index.min(), end=df.index.max())
    breaks=date_range[~date_range.isin(df.index)]  # 取出 df 空缺之日期
    breaks_list=breaks.tolist()  # 轉成串列
    fig.update_xaxes(rangebreaks=[{'values': breaks_list}])  # 移除非交易日空缺
    fig.update_layout(
        title='台灣五十股價',
        width=800,
        height=600,        
        xaxis_rangeslider_visible=False
        )
    fig.show() 

此處使用 Pandas 的 date_range() 函式取得 df 起迄日期間的所有連續日期序列, 然後用串列運算與 df 比對抓出 df 中空缺之日期即為非交易日, 轉成串列後做為字典 values 鍵之值. 結果如下 :




可見非交易日的空 K 棒已消失, 整個 K 線圖 X 軸看起來是連續無空缺了. 

fig.update_xaxes() 常用參數如下表 :


 參數名稱  說明
 title  X 軸標題。可傳入字串或 dict(text='...', font=...)。
 type  座標軸類型:'linear' (數值), 'date' (時間), 'category' (類別), 'log' (對數)。
 range  設定顯示範圍 [min, max],對於時間軸 ['2026-01-01', '2026-05-01']。
 rangebreaks  隱藏特定時間區段(如週末或收盤時段)。常用於金融圖表。
 rangeslider_visible  是否顯示底部的時間範圍滑桿(True/False)。
 showgrid  是否顯示垂直網格線(True/False)。預設為 True。
 gridcolor / gridwidth  設定網格線的顏色與寬度。
 tickformat  設定刻度文字格式(如 '%Y-%m-%d' 顯示日期,'.2f' 顯示兩位小數)。
 tickangle  刻度文字的旋轉角度(例如 -45 代表順時針旋轉 45 度)。
 side  X 軸的位置。可設定為 'bottom' (預設) 或 'top'。
 nticks  設定刻度的最大數量(Plotly 會嘗試在此範圍內自動分配)。
 fixedrange  是否鎖定縮放(True 代表禁止使用者縮放該軸)。
 showspikes  是否顯示 Y 軸輔助線。預設 False (不顯示)。
 spikemode  X 軸輔助線模式 : 'toaxis' (預設指向坐標軸)、'across' (橫跨整個繪圖區)。
 spikecolor  X 軸輔助線顏色 : 顏色名稱或色碼 (預設 None 視資料點自動指配)。
 spikethickness  X 軸輔助線厚度 : 預設 3px。
 spikedash  X 軸輔助線樣式 : 'dash' (預設), 'dot', 'solid'。


除了有 X 軸設定方法 fig.update_xaxes() 外, 還有 Y 軸設定方法 fig.update_yaxes(), 參數結構類似 :


 參數名稱  說明
 title  Y 軸標題。可設定為字串或 dict(text='...', font=...)。
 type  座標軸類型:'linear' (預設)、'log' (對數軸)、'date'。
 range  設定 Y 軸顯示數值範圍。例如 [0, 1000]。
 autorange  是否自動縮放範圍:True, False 或 'reversed'(數值由大到小反轉)。
 showgrid  是否顯示水平網格線(True/False)。
 zeroline  是否加粗顯示數值為 0 的那條基準線。預設為 True。
 tickformat  刻度數值格式。例如 ',d' (千分位整數)、'.2f' (兩位小數)、'%' (百分比)。
 tickprefix / ticksuffix  在刻度數值前後加上符號(如 tickprefix='$' 或 ticksuffix='元')。
 side  Y 軸的位置。可設定為 'left' (預設) 或 'right' (常見於雙 Y 軸設計)。
 secondary_y  多軸圖表中指定此資料是否為第二個 Y 軸(配合 make_subplots 使用)。
 fixedrange  是否固定 Y 軸。設為 True 時,使用者無法透過滑鼠縮放 Y 軸方向。
 showspikes  是否顯示 Y 軸輔助線。預設 False (不顯示)。
 spikemode  Y 軸輔助線模式 : 'toaxis' (預設指向坐標軸)、'across' (橫跨整個繪圖區)。
 spikecolor  Y 軸輔助線顏色 : 顏色名稱或色碼 (預設 None 視資料點自動指配)。
 spikethickness  Y 軸輔助線厚度 : 預設 3px。
 spikedash  Y 軸輔助線樣式 : 'dash' (預設), 'dot', 'solid'。


4. 添加輔助十字線 : 

輔助十字線是當滑鼠在畫布上移動時會出現一個平行於 X 與 Y 軸十字線的互動效果, 開啟輔助十字線顯示需要將 fig.update_xaxes() 與 fig.update_yaxes() 的 showspike 參數設為 True. 例如 :

# plotly_candlestick_3.py
import yfinance as yf
import plotly.graph_objects as go
import pandas as pd

if __name__ == "__main__":
    df=yf.download('0050.tw', start='2026-03-01', end='2026-04-30', auto_adjust=True)
    df.columns=df.columns.map(lambda x: x[0])
    price=go.Candlestick(
        x=df.index,
        open=df['Open'],
        high=df['High'],
        low=df['Low'],
        close=df['Close'],
        increasing_line_color='red',
        decreasing_line_color='green'    
        )
    fig=go.Figure(data=[price])
    # 移除 X 軸的非交易日
    date_range=pd.date_range(start=df.index.min(), end=df.index.max())
    breaks=date_range[~date_range.isin(df.index)]  # 取出 df 空缺之日期
    breaks_list=breaks.tolist()  # 轉成串列
    fig.update_xaxes(rangebreaks=[{'values': breaks_list}],
                     showspikes=True)
    fig.update_yaxes(showspikes=True)    
    fig.update_layout(
        title='台灣五十股價',
        width=800,
        height=600,        
        xaxis_rangeslider_visible=False
        )
    fig.show() 

此處將 X/Y 軸設定參數 showspikes 設為 True 後, 當滑鼠移到 K 棒上面時就會顯示指向座標軸的 輔助線, 由於 spikemode 預設 'toaxis', 故輔助線是指向坐標軸, 而非貫穿繪圖區的十字線; 由於 spikecolor 預設為 None, 所以滑鼠移到紅 K 棒時輔助線為紅色, 移到綠 K 棒時輔助線為綠色 :





下面是傳入全部輔助線參數的範例 :

# plotly_candlestick_4.py
import yfinance as yf
import plotly.graph_objects as go
import pandas as pd

if __name__ == "__main__":
    df=yf.download('0050.tw', start='2026-03-01', end='2026-04-30', auto_adjust=True)
    df.columns=df.columns.map(lambda x: x[0])
    price=go.Candlestick(
        x=df.index,
        open=df['Open'],
        high=df['High'],
        low=df['Low'],
        close=df['Close'],
        increasing_line_color='red',
        decreasing_line_color='green'    
        )
    fig=go.Figure(data=[price])
    # 移除 X 軸的非交易日
    date_range=pd.date_range(start=df.index.min(), end=df.index.max())
    breaks=date_range[~date_range.isin(df.index)]  # 取出 df 空缺之日期
    breaks_list=breaks.tolist()  # 轉成串列
    fig.update_xaxes(rangebreaks=[{'values': breaks_list}],
                     showspikes=True,
                     spikethickness=1,
                     spikecolor='blue',
                     spikedash='dot',
                     spikemode='across')
    fig.update_yaxes(showspikes=True,
                     spikethickness=1,
                     spikecolor='blue',
                     spikedash='dot',
                     spikemode='across')  
    fig.update_layout(
        title='台灣五十股價',
        width=800,
        height=600,        
        xaxis_rangeslider_visible=False,
        #hovermode='x'
        )
    fig.show() 

此例傳入輔助線參數更改預設值, 結果如下 :




可見 spikethickness=1 讓輔助線變細了, spikecolor='blue' 則使其顏色不論紅 K 或綠 K 都顯示藍色; 而 spikemode='across' 則使輔助線貫穿整個畫布成為名符其實的十字線. 注意, 預設須當滑鼠移到 K 棒上時才會顯示輔助線, 如果要讓滑鼠在畫布任何位置都顯示輔助線, 則在呼叫 fig.update_layout() 要傳入 hovermode='x' 參數, 因為 K 線圖是按時間 (X 軸) 排列的, 每一格時間通常都有資料, 所以滑鼠左右移動時, 輔助線會非常流暢地跟隨. 

momo 購買泰達椅 Pro

因下周要帶爸與岳父母去沖繩旅遊, 為了在排隊時沒椅子坐, 上 momo 買了僅 1 kg 的泰達椅 Pro : 





滿一件折 350, 還另送 350 元 momo 幣 : 




實付 2630 元, 送 momo 幣 350 元, 實際上只花 2280 元.