答案 0 :(得分:0)
此代码在理论点旁边以文本形式显示百分比误差。您也可以在画布上从理论点到实验点画一条线,差异数据将显示在工具提示中。第一次单击(释放按钮)将启动“差异”行。再次单击将结束它。工具提示始终保留在图上,但是您可以轻松对其进行调整,使其在第二次单击后消失。
import numpy as np
from bokeh.plotting import figure, show
from bokeh.models import ColumnDataSource, CustomJS
from bokeh.events import *
source = ColumnDataSource({'x': [], 'y': []})
p = figure(plot_width = 900)
x_data = np.arange(10)
source_expected = dict(x = x_data, y = np.random.random(10), color=['blue']*10)
source_measured = dict(x = x_data, y = np.random.random(10), color=['grey']*10)
line_expected = p.line('x', 'y', line_color = 'blue', source = source_expected)
circle_expected = p.circle('x', 'y', color = 'color', source = source_expected, size = 10)
line_measured = p.line('x', 'y', line_color = 'grey', source = source_measured)
# circle_measured = p.circle('x', 'y', color = 'color', fill_color = 'white', source = source_measured, size = 60)
circle_measured = p.circle('x', 'y', color = 'color', source = source_measured, size = 10)
source_error = {'x': [], 'y': [], 'error': [], 'percent': [], 'text': [], 'color': []}
i = 0
for expected, measured in zip(source_expected['y'], source_measured['y']):
source_error['x'].append(x_data[i])
source_error['y'].append(measured)
error = expected - measured
percent = (error/expected) * 100
source_error['error'].append(error)
source_error['percent'].append(percent)
source_error['text'].append('+{}%'.format('%.2f' % percent) if percent > 0 else '{}%'.format('%.2f' % percent))
source_error['color'].append('green' if expected == measured else 'red')
i = i + 1
# text_measured = p.text('x', 'y', text = 'text', text_color = 'color', text_font_size = '9pt', x_offset = -25, y_offset = 6, source = source_error)
text_measured = p.text('x', 'y', text = 'text', text_color = 'color', text_font_size = '9pt', x_offset = 10, y_offset = 5, source = source_error)
line = p.line('x', 'y', line_color = 'red', line_dash = 'dashed', source = source)
callback_tap = '''
if (typeof custom_tooltip == 'undefined') {
custom_tooltip = document.createElement('div');
custom_tooltip.setAttribute('id','tooltip_div');
custom_tooltip.style = 'position: absolute; left: 0px; top: 0px; z-index: 9999; border:1px solid black; padding: 10px; background: white; font-family: arial; font-size: 12px'
document.body.prepend(custom_tooltip);
}
if (true === Bokeh.drawing) {
Bokeh.drawing = false
}
else {
if (!Bokeh.drawing) {
src.data = {'x':[], 'y':[]}
src.change.emit()
}
src.data['x'].push(cb_obj.x)
src.data['y'].push(cb_obj.y)
Bokeh.drawing = true
Bokeh.sx_start = cb_obj.sx
Bokeh.x_start = cb_obj.x
Bokeh.sy_start = cb_obj.sy
Bokeh.y_start = cb_obj.y
}'''
callback_mousemove = '''
function print(...args) {
for (i in args) {
console.log(args[i])
}
}
if (Bokeh.drawing) {
if (src.data['x'].length > 1) {
src.data['x'].pop()
src.data['y'].pop()
}
src.data['x'].push(cb_obj.x)
src.data['y'].push(cb_obj.y)
src.change.emit()
tooltip = document.getElementById('tooltip_div')
tooltip.style.left = cb_obj.sx + 30 + 'px'
tooltip.style.top = cb_obj.sy + 10 + 'px'
var error = Math.round((Bokeh.y_start - cb_obj.y) * 100) / 100
var percent = Math.round(error * 100 / Bokeh.y_start)
tooltip.innerHTML = 'Distance X: ' + Math.round(Bokeh.sx_start - cb_obj.sx) + ' px' + ' (' + (Math.round((Bokeh.x_start - cb_obj.x) * 100) / 100) + ' units)' +
'<br />' +
'Distance Y: ' + Math.round(Bokeh.sy_start - cb_obj.sy) + ' px' + ' (' + (Math.round((Bokeh.y_start - cb_obj.y) * 100) / 100) + ' units)' +
'<br />' +
'Error: ' + error + ' units' +
'<br />' +
'% Error: ' + percent + ' %'
}'''
p.js_on_event('tap', CustomJS(args = {'src': source, }, code = callback_tap))
p.js_on_event('mousemove', CustomJS(args = {'src': source, }, code = callback_mousemove))
show(p)
结果:
将注释的行与其旁边的行交换会使错误百分比显示在代表理论点的大圆圈中。看起来像这样:
此脚本是为 Python v3.7.2 和 Bokeh v1.3.0
编写的