下方程式碼, 是我從 Chatgpt 生成的範例 , 我執行後有兩個問題
嘗試了很多方式, 都沒有抓出哪部分錯誤, 再麻煩幫忙 , 謝謝
from bokeh.plotting import figure, show, output_file
from bokeh.models import ColumnDataSource, HoverTool
from bokeh.layouts import column
import pandas as pd
# 準備數據
data = {
'Date': pd.date_range(start='2021-01-01', periods=10, freq='D'),
'Open': [100, 105, 103, 107, 104, 101, 108, 110, 107, 105],
'Close': [105, 103, 107, 104, 108, 102, 109, 111, 106, 104],
'High': [110, 108, 109, 109, 110, 103, 112, 115, 108, 107],
'Low': [99, 101, 102, 103, 103, 100, 106, 109, 104, 102],
'Volume': [1200, 1500, 1800, 1600, 1700, 1300, 1900, 2000, 1650, 1550]
}
df = pd.DataFrame(data)
df['Date_str'] = df['Date'].dt.strftime('%Y-%m-%d')
# 設置數據源
source = ColumnDataSource(df)
# 創建蠟燭圖
p = figure(x_axis_type="datetime", title="蠟燭圖與成交量",
sizing_mode="stretch_width", height=350)
# 添加懸停工具
hover = HoverTool(
tooltips=[
("Date", "@Date_str"),
("Open", "@Open"),
("Close", "@Close"),
("High", "@High"),
("Low", "@Low")
],
formatters={'@Date_str': 'datetime'}, # 確保此處無誤
mode='vline'
)
p.add_tools(hover)
p.grid.grid_line_alpha=0.3
inc = df.Close > df.Open
dec = df.Open > df.Close
w = 12*60*60*1000 # 半天的毫秒數
p.segment('Date', 'High', 'Date', 'Low', source=source, color="black")
p.vbar(df.Date[inc], w, df.Open[inc], df.Close[inc], fill_color="#D5E1DD", line_color="black")
p.vbar(df.Date[dec], w, df.Open[dec], df.Close[dec], fill_color="#F2583E", line_color="black")
# 創建成交量圖
p2 = figure(x_axis_type="datetime", title="成交量",
sizing_mode="stretch_width", height=300) # 保持x軸一致
p2.vbar('Date', w, 'Volume', source=source, color="gray", alpha=0.7)
# 添加第二個懸停工具
hover2 = HoverTool(
tooltips=[
("Date", "@Date_str"),
("Volume", "@Volume")
],
formatters={'@Date_str': 'datetime'},
mode='vline'
)
p2.add_tools(hover2)
# 使用column布局將兩個圖形放在一起
layout = column(p, p2)
# 輸出文件
output_file("candlestick_and_volume.html")
show(layout)
我拿code去問claude
這段程式碼基本上看起來是正確的,但有幾個小問題需要注意:
1. 在創建蠟燭圖時,使用了 DataFrame 索引來設置顏色:
```python
p.vbar(df.Date[inc], w, df.Open[inc], df.Close[inc], fill_color="#D5E1DD", line_color="black")
p.vbar(df.Date[dec], w, df.Open[dec], df.Close[dec], fill_color="#F2583E", line_color="black")
這可能會導致問題,因為 Bokeh 期望使用 ColumnDataSource 中的列名。應該改為:
p.vbar('Date', w, 'Open', 'Close', source=source, fill_color="#D5E1DD", line_color="black", name="inc")
p.vbar('Date', w, 'Open', 'Close', source=source, fill_color="#F2583E", line_color="black", name="dec")
然後在 ColumnDataSource 中添加 inc 和 dec 列:
df['inc'] = df.Close > df.Open
df['dec'] = df.Open > df.Close
source = ColumnDataSource(df)
formatters={'@Date_str': 'printf'}, # 使用 'printf' 而不是 'datetime'
p.xaxis.axis_label = '日期'
p.yaxis.axis_label = '價格'
p2.xaxis.axis_label = '日期'
p2.yaxis.axis_label = '成交量'
p2 = figure(x_axis_type="datetime", title="成交量",
sizing_mode="stretch_width", height=300, x_range=p.x_range)
這樣可以確保兩個圖表的 x 軸同步縮放。
除了這些小問題外,程式碼整體結構是正確的,應該能夠生成一個包含蠟燭圖和成交量圖的 HTML 文件。
是否需要我解釋一下這些修改,或者您有其他問題嗎?
十分感謝你的解答, 我修改如下 , 第二個問題 HoverTool 顯示的問題, 已經得到解答, 但第一個問題 , 使用 x_range=p.x_range 仍然會有縮成一團狀況.
分別看 p , p2 都正常, 弄在一塊就會有問題 ...
from bokeh.plotting import figure, show, output_file
from bokeh.models import ColumnDataSource, HoverTool
from bokeh.layouts import column
import pandas as pd
# 準備數據
data = {
'Date': pd.date_range(start='2021-01-01', periods=10, freq='D'),
'Open': [100, 105, 103, 107, 104, 101, 108, 110, 107, 105],
'Close': [105, 103, 107, 104, 108, 102, 109, 111, 106, 104],
'High': [110, 108, 109, 109, 110, 103, 112, 115, 108, 107],
'Low': [99, 101, 102, 103, 103, 100, 106, 109, 104, 102],
'Volume': [1200, 1500, 1800, 1600, 1700, 1300, 1900, 2000, 1650, 1550]
}
df = pd.DataFrame(data)
df['Date_str'] = df['Date'].dt.strftime('%Y-%m-%d')
# 設置數據源
df['inc'] = df.Close > df.Open
df['dec'] = df.Open > df.Close
source = ColumnDataSource(df)
# 創建蠟燭圖
p = figure(x_axis_type="datetime", title="蠟燭圖與成交量",
sizing_mode="stretch_width", height=350)
# 添加懸停工具
hover = HoverTool(
tooltips=[
("Date", "@Date_str"),
("Open", "@Open"),
("Close", "@Close"),
("High", "@High"),
("Low", "@Low")
],
formatters={'@Date_str': 'datetime'}, # 確保此處無誤
mode='vline'
)
p.add_tools(hover)
p.grid.grid_line_alpha=0.3
inc = df.Close > df.Open
dec = df.Open > df.Close
w = 12*60*60*1000 # 半天的毫秒數
p.segment('Date', 'High', 'Date', 'Low', source=source, color="black")
p.vbar('Date', w, 'Open', 'Close', source=source, fill_color="#D5E1DD", line_color="black", name="inc")
p.vbar('Date', w, 'Open', 'Close', source=source, fill_color="#F2583E", line_color="black", name="dec")
# 創建成交量圖
p2 = figure(x_axis_type="datetime", title="成交量",
sizing_mode="stretch_width", height=300, x_range=p.x_range) # 保持x軸一致
p2.vbar('Date', w, 'Volume', source=source, color="gray", alpha=0.7)
p.xaxis.axis_label = '日期'
p.yaxis.axis_label = '價格'
p2.xaxis.axis_label = '日期'
p2.yaxis.axis_label = '成交量'
# 添加第二個懸停工具
hover2 = HoverTool(
tooltips=[
("Date", "@Date_str"),
("Volume", "@Volume")
],
formatters={'@Date_str': 'printf'},
mode='vline'
)
p2.add_tools(hover2)
# 使用column布局將兩個圖形放在一起
layout = column(p, p2)
# 輸出文件
output_file("candlestick_and_volume.html")
show(layout)
我找到修改方式 , 把 sizing_mode="stretch_width" 改成固定 width
p = figure(x_axis_type="datetime", title="蠟燭圖與成交量",
width=800, height=350)
p2 = figure(x_axis_type="datetime", title="成交量",
width=800, height=300, x_range=p.x_range)