iT邦幫忙

0

Bokeh 畫圖 X 軸縮成一團

  • 分享至 

  • xImage

下方程式碼, 是我從 Chatgpt 生成的範例 , 我執行後有兩個問題

  1. p 和 p2 分開顯示都沒問題,但顯示 layout( p,p2 合併一起顯示) , 所產生的圖繪縮成一團.
    https://ithelp.ithome.com.tw/upload/images/20240626/20111654ugMtWWir54.jpg
  2. p 和 p2 分開顯示都沒問題 , 但是懸浮資料方格 , 在 p 這張圖中會顯示錯誤 , 會有重影狀況, 並且底下層有顯示資訊, 上層顯示為 "???"

嘗試了很多方式, 都沒有抓出哪部分錯誤, 再麻煩幫忙 , 謝謝
https://ithelp.ithome.com.tw/upload/images/20240626/20111654UrNebnUfcX.png

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)


隨便看 隨便猜
時間軸太細
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 個回答

1
海綿寶寶
iT邦大神 1 級 ‧ 2024-06-26 22:59:29
最佳解答

我拿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)
  1. 在 HoverTool 的 formatters 中,使用了 '@Date_str': 'datetime',但 'Date_str' 實際上是一個字符串,不是日期時間對象。應該改為:
formatters={'@Date_str': 'printf'},  # 使用 'printf' 而不是 'datetime'
  1. 為了使圖表更易讀,可以考慮在 x 軸上添加標籤:
p.xaxis.axis_label = '日期'
p.yaxis.axis_label = '價格'
p2.xaxis.axis_label = '日期'
p2.yaxis.axis_label = '成交量'
  1. 為了使兩個圖表的 x 軸範圍保持一致,可以在創建第二個圖表時設置 x_range:
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)          
不明
【**此則訊息已被站方移除**】

我要發表回答

立即登入回答