iT邦幫忙

2025 iThome 鐵人賽

DAY 17
0
AI & Data

從網路爬蟲到資料洞察的應用系列 第 17

畫月成交量長條圖

  • 分享至 

  • xImage
  •  

今天我們把每日成交量匯總成「月總成交量」,並把它畫成下方的長條圖。這篇文章會從資料前處理、月聚合、到畫圖細節一步步講解。

目標

  • 確保 Date 欄位是 datetime、Volume 是數值
  • 以月份(Year-Month)為單位,把每日成交量加總成月總成交量
  • 繪製長條圖
  • 美化 X 軸為 YYYY-MM、加入千分位顯示與數值標注

步驟說明

  • 讀入資料或使用現有 df
  • 把 Date 轉成 datetime,Volume 用 pd.to_numeric 轉成整數
  • 以 df['Date'].dt.to_period('M') 做月份分組,再 groupby+sum() 得到月總成交量
  • 把 Period 轉回時間型(to_timestamp()),以利 matplotlib 畫圖與格式化 X 軸
  • 畫長條圖時,若 x 軸是 datetime,width 參數是以天為單位
  • 加上 x 軸格式化(%Y-%m)、Y 軸千分位格式、以及 bar 上方標注數值,最後 tight_layout() 優化排版並savefig()

程式碼

# --- 資料前處理 ---
df['Date'] = pd.to_datetime(df['Date'])
df['Volume'] = pd.to_numeric(df['Volume'].astype(str).str.replace(',', ''), errors='coerce').fillna(0).astype(int)

# --- 月聚合:計算月總成交量 ---
df['Month'] = df['Date'].dt.to_period('M')
monthly = df.groupby('Month').agg({'Volume': 'sum'}).reset_index()
monthly['MonthStart'] = monthly['Month'].dt.to_timestamp() 
monthly.rename(columns={'Volume': '月總成交量'}, inplace=True)

plot_monthly_stats = monthly[['MonthStart', '月總成交量']]

fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 8), sharex=True,
                               gridspec_kw={'height_ratios': [1, 1.1]})

# 月總成交量長條圖
ax2.bar(plot_monthly_stats['MonthStart'], plot_monthly_stats['月總成交量'],
        color='gray', width=20)

ax2.set_xlabel('月份', fontsize=12)
ax2.set_ylabel('月總成交量', fontsize=12)
ax2.grid(True)

ax2.xaxis.set_major_locator(mdates.MonthLocator())
ax2.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m'))
plt.xticks(rotation=45)
ax2.yaxis.set_major_formatter(FuncFormatter(lambda x, p: format(int(x), ',')))

ymax = plot_monthly_stats['月總成交量'].max()
for x, y in zip(plot_monthly_stats['MonthStart'], plot_monthly_stats['月總成交量']):
    ax2.text(x, y + ymax * 0.01, f'{y:,}', ha='center', va='bottom', fontsize=9)

plt.tight_layout()
plt.show()

常見問題

  • 如果 Volume 是字串且含逗號:用 pd.to_numeric(df['Volume'].str.replace(',', ''),errors='coerce') 來處理
  • 資料只抓到部分月份:注意交易日數不同造成月總量差異,解讀時要搭配月平均或日均來看
  • X 軸擠在一起:可只顯示每 2 個月或每 3 個月的刻度,改用 mdates.MonthLocator(interval=2)
  • 要畫百分比或 log scale:可用 ax2.set_yscale('log')

那今天就先這樣。
/images/emoticon/emoticon29.gif


上一篇
畫月平均收盤價折線圖
系列文
從網路爬蟲到資料洞察的應用17
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言