我有一些数据在某些地方缺少值。出于某种原因,只有在数据中的最后一个中断之后悬停在数据上才会显示悬停上的一个框,如预期的那样。最后一个中断和倒数第二个之间的数据显示3个框。 (屏幕截图由于某种原因没有捕获鼠标。在左图中,它位于曲线中的孔左侧,右图中 - 右侧。)在数据的第二个和第三个到最后一个中断之间悬停数据生成5个盒子。等等......额外框中的值不随光标移动而改变,并且也都不同,并且框被移位并仅显示在最后一个数据块中。有什么想过这里发生了什么?
我尝试制作一个最小的例子,然后问题消失了......也许有人可以发现原始代码有什么问题?
import numpy as np
import pandas as pd
import warnings
from bokeh.layouts import widgetbox
from bokeh.plotting import figure, show, output_file, output_notebook
from bokeh.palettes import Spectral11, colorblind, Inferno, BuGn, brewer
from bokeh.models import HoverTool, value, LabelSet, Legend, ColumnDataSource, LinearColorMapper, BasicTicker, PrintfTickFormatter, ColorBar
from bokeh.models.widgets import DateRangeSlider, CheckboxButtonGroup
from bokeh.models import CustomJS, ColumnDataSource
from bokeh.layouts import column, row
from json import loads
import ast
warnings.filterwarnings('ignore')
minD = data['Date'].values[0]
maxD = data['Date'].values[-1]
def datetime(x):
return np.array(x, dtype=np.datetime64)
TOOLS = 'save,pan,box_zoom,reset,wheel_zoom'
p = figure(y_axis_type="linear",
plot_height=400, tools=TOOLS, plot_width=1300,
x_range=(minD, maxD), x_axis_type="datetime")
source = ColumnDataSource(data={
'Date': datetime(data['Date']),
'x': data['x'],
'y': data['y'],
'z': data['z']})
p.xaxis.axis_label = 'Date'
p.yaxis.axis_label = 'Position (m)'
def add_plot(y, color):
new_plot = p.line(x='Date', y=y, line_width=1, color=color, source=source)
return new_plot
x = add_plot('x', 'red')
y = add_plot('y', 'green')
z = add_plot('z', 'blue')
checkbox = CheckboxButtonGroup(labels=['x', 'y', 'z'], active=[0, 1, 2])
checkbox.callback = CustomJS(args=dict(x=x, y=y, z=z), code="""
//console.log(cb_obj.active);
x.visible = false;
y.visible = false;
z.visible = false;
for (i in cb_obj.active) {
//console.log(cb_obj.active[i]);
if (cb_obj.active[i] == 0) {
x.visible = true;
} else if (cb_obj.active[i] == 1) {
y.visible = true;
} else if (cb_obj.active[i] == 2) {
z.visible = true;
}
}
""")
callback = CustomJS(args=dict(p=p), code="""
var a = cb_obj.value;
p.x_range.start = a[0];
p.x_range.end = a[1];
""")
start_date = pd.to_datetime(minD)
end_date = pd.to_datetime(maxD)
range_slider = DateRangeSlider(start=start_date, end=end_date,
value=(start_date, end_date), step=1)
range_slider.js_on_change('value', callback)
def get_hovertools():
hovers = {'x': x, 'y': y, 'z': z}
for k, v in hovers.items():
hovers[k] = HoverTool(mode='vline', renderers=[v])
hovers[k].tooltips = [('Date', '@Date{%F %H:%M:%S.%u}'),
(k, '@{'+k+'}{%0.2f}m')]
hovers[k].formatters = {'Date': 'datetime', k: 'printf'}
p.add_tools(hovers[k])
get_hovertools()
layout = column(p, widgetbox(checkbox), widgetbox(range_slider))
show(layout)
您在mode = 'vline'
中使用HoverTool
,因此如果线条非常陡峭,则字形中可能有许多点具有相似的y坐标,因此悬停将全部击中它们并显示多个框。将模式设置为mode = "mouse"
应该会有所帮助
事实证明我的一些日期是NaT
...真的很奇怪,它是如何决定处理它们,只是在最后一个NaT
之后显示适当的悬停框值......散景让我感到困惑.....