Bokeh绘制谷歌金融数据K线图无显示,求排查X轴(df.index)问题
Hey there, I’ve run into this exact problem before—blank Bokeh candlestick charts almost always boil down to issues with the time axis handling. Let’s work through this step by step:
First, Check Your Data Source & Index Format
The iex data source now requires an API key to fetch data properly (pandas_datareader updated this requirement a while back), plus the returned df.index might not be a datetime type that Bokeh can recognize. Start by verifying your data loads correctly and checking the index type:
# Verify data structure and index type print(df.head()) print(type(df.index))
If the index isn’t datetime64[ns] or your DataFrame is empty, that’s a sure reason for the blank chart. Also, make sure you’re passing your IEX API key—you can set it via an environment variable or directly in the call:
import os # Replace with your actual API key, or store it in the IEX_API_KEY environment variable df = data.DataReader(name="GOOG", data_source="iex", start=start, end=end, api_key=os.getenv('IEX_API_KEY'))
Adjust Bokeh’s Time Axis Configuration
Bokeh needs explicit confirmation that your X-axis is datetime-based, and you have to ensure the X-coordinate data is in a format it can parse. Here’s a complete, corrected version of your code, including the missing inc_dec function logic:
from pandas_datareader import data import datetime import pandas as pd from bokeh.plotting import figure, show, output_file import os # Set date range start = datetime.datetime(2016, 3, 1) end = datetime.datetime(2016, 3, 10) # Load data with IEX API key df = data.DataReader(name="GOOG", data_source="iex", start=start, end=end, api_key=os.getenv('IEX_API_KEY')) # Ensure index is datetime type (critical for Bokeh) df.index = pd.to_datetime(df.index) # Function to determine if price increased/decreased def inc_dec(close, open): return "Increase" if close > open else "Decrease" if close < open else "Equal" # Add status column for candlestick coloring df["Status"] = [inc_dec(c, o) for c, o in zip(df.close, df.open)] # Calculate midpoint for candlestick rectangles df["Mid"] = (df.open + df.close) / 2 # Calculate height of candlestick bodies df["BodyHeight"] = abs(df.close - df.open) # Create figure with datetime X-axis p = figure(x_axis_type='datetime', width=1000, height=300, title="Google (GOOG) Stock Candlestick Chart") p.xaxis.axis_label = "Date" p.yaxis.axis_label = "Price" # Format X-axis tick labels to show readable dates p.xaxis.major_label_overrides = { i: date.strftime('%b %d') for i, date in enumerate(df.index) } # Plot high-low wicks p.segment(df.index, df.high, df.index, df.low, color="black") # Plot bullish (green) candlesticks p.rect(df.index[df.Status == "Increase"], df.Mid[df.Status == "Increase"], width=0.5, height=df.BodyHeight[df.Status == "Increase"], fill_color="#00FF00", line_color="black") # Plot bearish (red) candlesticks p.rect(df.index[df.Status == "Decrease"], df.Mid[df.Status == "Decrease"], width=0.5, height=df.BodyHeight[df.Status == "Decrease"], fill_color="#FF0000", line_color="black") # Output and show the chart output_file("GOOG_Candlestick.html") show(p)
Key Fixes Explained
- Index Conversion:
df.index = pd.to_datetime(df.index)ensures Bokeh can interpret the X-axis values as dates. - Datetime Axis Spec: Setting
x_axis_type='datetime'when creating thefiguretells Bokeh to render the X-axis as a time series. - Data Validation: Make sure your
dfisn’t empty—runprint(df.shape)to confirm you have rows of data. If you don’t want to use IEX, you can switch to theyfinancelibrary (a maintained alternative for Yahoo Finance data) instead.
If the chart still doesn’t show up, double-check that your API key is valid and that the date range you selected has available trading data (March 2016 should be fine for GOOG, but holidays/weekends will have gaps).
内容的提问来源于stack exchange,提问作者Sayeed

