I have an simple example, run in jupyter notebook:
- hvplot.ohlc without missing-date gaps
- wanted to fix Hover (add Date in the right format, and add Volume info)
packages:
python 3.12
bokeh 3.3.2
hvplot 0.9.0
holoviews 1.18.1
import pandas as pd
import hvplot.pandas
data = pd.DataFrame({
"Open": [100.00, 101.25, 102.75],
"High": [104.10, 105.50, 110.00],
"Low": [94.00, 97.10, 99.20],
"Close": [101.15, 99.70, 109.50],
"Volume": [10012, 5000, 18000],
}, index=[pd.Timestamp("2022-08-01"), pd.Timestamp("2022-08-03"), pd.Timestamp("2022-08-04")])
df = pd.DataFrame(data)
# remove datetime gaps
df = df.reset_index(names="Date")
df['Idx'] = pd.RangeIndex(0, df.shape[0], 1)
# fix hover ------
from bokeh.models import HoverTool
hover = HoverTool(
tooltips=[
('Date', '@Date{%Y-%m-%d}'),
('Open', '@Open{0.00}'),
('High', '@High{0.00}'),
('Low', '@Low{0.00}'),
('Close', '@Close{0.00}'),
('Volume', '@Volume{0}'),
],
formatters={'@Date': 'datetime'},
mode='vline'
)
# fix hover ------
ohlc_cols = ["Open", "High", "Low", "Close"]
ohlc = df.hvplot.ohlc(x='Idx', y=ohlc_cols, hover_cols=["Date", *ohlc_cols, "Volume"], tools=[hover])
# fix x tick labels ------
import holoviews as hv
from bokeh.io import show
fig = hv.render(ohlc)
fig.xaxis.major_label_overrides = {
i: dt.strftime("%b %d") for i, dt in enumerate(df['Date'])
}
# fix x tick labels ------
show(fig)
The solution, or more a workaround, is to manupilate the ColumnDataSource of the first renderer in the bokeh figure.
You can do so b adding the line below:
Explanation
To understand why the line above is the solution, I want to explain, what
df.hvplot.ohlc()
does.This function creates a bokeh figure with 2 renderers, the first rederer is for all whiskers, which gets the HoverTool, and the seconde renderer draws the boxes. The DataFrame is converted to a
ColumnsDataSource
in the inside. TheColumnsDataSource
s don't have any information about the"Volume"
, because only used columns used by the whiskers and boxes are stored inside theColumnDataSource
. The HoverTool can't find information for theVolumne
, so it prints???
. But we can extend the source by this information.Minimal Example
I adapted your example, because I think it is simpler, but the downside is, that there is one empty date.
Output