如何解决自定义JS回调,仅允许将一个圆圈显示在散景的“圆圈”图中
我是Bokeh的新手
我正在尝试使用Bokeh复制https://www.worldometers.info/coronavirus/中显示的线图。这是我的完整代码
from datetime import datetime,timedelta,date
import requests
import json
from bokeh.plotting import output_notebook,figure,show
from bokeh.models import ColumnDataSource,HoverTool,Title
def DateFormatter(x):
s = '01222020'
global given_date
given_date = datetime(month=int(s[:2]),day=int(s[2:4]),year=int(s[4:]))
given_date += timedelta(days=x)
final = str(given_date.strftime('%m{}%d{}%y').format('/','/'))
if int(final[0:2])<10 and int(final[3:5])<10:
final = final[1:]
final = final[0 : 2 : ] + final[3 : :]
elif int(final[0:2])<10:
final = final[1:]
elif int(final[3:5])<10:
final = final[0 : 2 : ] + "/" + final[4 : :]
return final
def DateFormatterForPlot(x):
s_plot = '01222020'
global given_date_plot
given_date_plot = datetime(month=int(s_plot[:2]),day=int(s_plot[2:4]),year=int(s_plot[4:]))
given_date_plot += timedelta(days=x-1)
final_plot1 = str(given_date_plot.strftime('%b %d'))
if int(final_plot1[4:6])<10:
final_plot1 = final_plot1[0 : 4 : ] + final_plot1[5 : :]
return final_plot1
finallist=[]
l2 = []
plot_list = []
country = "India"
chart_type = "cases"
base_site = f'https://disease.sh/v3/covid-19/historical/{country}?lastdays=all'
r = requests.get(base_site)
if r.status_code == 200:
packages_json = r.json()
today_date = str(date.today().strftime('%m{}%d{}%y').format('/','/'))
if int(today_date[0:2])<10 and int(today_date[3:5])<10:
today_date = today_date[1:]
today_date = today_date[0 : 2 : ] + today_date[3 : :]
elif int(today_date[0:2])<10:
today_date = today_date[1:]
elif int(today_date[3:5])<10:
today_date = today_date[0 : 2 : ] + "/" + today_date[4 : :]
for i in range(1,1000):
current_date = DateFormatter(i)
if current_date==today_date:
f_date = datetime(2020,1,22)
delta = given_date - f_date
break;
for i in range(delta.days):#Day 157 is 26th June
try:
a = DateFormatter(i)
packages_str = json.dumps(packages_json['timeline'][chart_type][a],indent=2)
finallist.append(int(packages_str))
except KeyError:
pass
count = 0
for i in finallist:
count = count + 1
for i in range(1,count+1):
l2.append(i)
for i in l2:
plot_list.append(DateFormatterForPlot(i))
else:
print("Not a valid country")
source = ColumnDataSource(data=dict(y=finallist,x=l2,desc=plot_list))
TOOLTIPS = """
<style>
.bk-tooltip>div:not(:first-child) {display:none;}
</style>
<b>X: </b> @desc <br>
<b>Y: </b> @y{0,0}
"""
plot = figure(background_fill_color='#fafafa',x_axis_label='Days',y_axis_label='Coronavirus {}'.format(chart_type.capitalize()),plot_width=1200,plot_height=400,toolbar_location=None)
plot.line('x','y',source=source,legend = 'Number of {}'.format(chart_type.capitalize()),line_width=2,color='gray')
cr = plot.circle('x',size=10,fill_color="grey",hover_fill_color="gainsboro",fill_alpha=0.1,line_color=None,hover_line_color="white",hover_fill_alpha=1)
plot.add_tools(HoverTool(tooltips=TOOLTIPS,renderers=[cr]))
plot.add_layout(Title(text="Coronavirus {} Example Graph".format(chart_type.capitalize()),align="center"),"above")
plot.legend.location = 'top_left'
plot.left[0].formatter.use_scientific = False #Used to disable scientific notation on y-axis
这里出现的问题是,当光标悬停在图形的密度较高的区域时,会显示多个圆形字形。
我认为Hovertool有一个CustomJS回调,只允许在鼠标悬停在其上方显示一个圆圈字形,但我无法实现它。
代码段的输出可以在此处查看http://geetanshjindal.pythonanywhere.com/charts/
我正在使用最新的bokeh版本2.1.1和python版本3.6
解决方法
我认为您有三种选择,所有这些都与降低密实度有关。
- 减小圆形字形的大小,以使它们不重叠。
size=5
对于您的绘图宽度似乎可以正常工作。 - 增加绘图宽度,以使圆形字形更加隔开。当然,这将添加一个滚动条,因此可能不是最佳的用户体验。
- 不要删除Bokeh工具栏,并鼓励用户与绘图进行交互-放大以查看所有圆形字形。
使用CSS选择性地显示工具提示的方法很有趣,但是它向用户隐藏了决策(“仅在重叠的两个圆圈的第一个圆圈显示工具提示”),可能引起混乱。
一种替代方法是完全删除工具提示,并在关键位置添加批注(传递一百万个案例?),然后将带有所有日期和值的表格放在侧面作为参考。
对于annotations,您可以结合使用Label和Bezier曲线模型:
from bokeh.models import Label,Bezier
test_label = Label(x=50,y=550000,x_units='data',y_units='data',text='Custom description of the datapoint',render_mode='css',border_line_color='white',border_line_alpha=1.0,border_line_width=3,background_fill_color='white',background_fill_alpha=1.0)
# play around with control point values for best effect
curve_source = ColumnDataSource(dict(
x0=[150],y0=[395048],x1=[130],y1=[600000],cx0=[150],cy0=[500000],cx1=[150],cy1=[600000]
)
)
test_curve = Bezier(
x0="x0",y0="y0",x1="x1",y1="y1",cx0="cx0",cy0="cy0",cx1="cx1",cy1="cy1",line_color="green",line_width=1)
plot.add_glyph(curve_source,test_curve)
plot.add_layout(test_label)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。