我一直在尝试创建一个折线图,将'值'表示为y轴,将'time'表示为x轴。我成功地做到了。
但是,当值之间存在较大的时间间隔时,存在从这些值连接两个点的线,这会产生难看的情况。
因此,我想摆脱这些界限。
这是我的可运行代码:
# Import Library
import random
import pandas as pd
from bokeh.core.properties import value
from bokeh.io import show, output_notebook, export_png
from bokeh.plotting import figure, output_file
from bokeh.models import ColumnDataSource, Legend, HoverTool, layouts, CustomJS, Select, Circle, RangeTool
from bokeh.layouts import column
output_notebook() # Render inline in a Jupyter Notebook
# Create Line Chart
def create_line_chart_bokeh():
# Set data
dates = ['24-11-2017', '28-11-2017', '29-11-2017',
'23-03-2018', '27-03-2018', '12-08-2018']
dates = list(map(lambda i: pd.Timestamp(i), dates))
values = [random.randrange(101) for _ in range(len(dates))]
source = ColumnDataSource(data=dict(date=dates, close=values))
# Set Hover
TOOLTIPS = [
("Average Score", "@close")
]
# Set plot
p = figure(plot_height=300, plot_width=800, tools="xpan", toolbar_location=None,
tooltips=TOOLTIPS, x_axis_type="datetime", x_axis_location="above",
background_fill_color="white", x_range=(dates[0], dates[int(len(dates)-1)]), title='Test Line Chart')
# Set Line and Circle colours
line_colour = '#59819a'
circle_colour = '#ef5b45'
p.line('date', 'close', source=source, color=line_colour)
p.circle('date', 'close', source=source, color=circle_colour, size=4)
p.yaxis.axis_label = 'Scores' # set y axis label
# Set Time Selection Box
select = figure(title="Drag the middle and edges of the selection box to change the range above",
plot_height=130, plot_width=800, y_range=p.y_range,
x_axis_type="datetime", y_axis_type=None,
tools="", toolbar_location=None, background_fill_color="#efefef")
range_tool = RangeTool(x_range=p.x_range)
range_tool.overlay.fill_color = 'navy'
range_tool.overlay.fill_alpha = 0.2
select.line('date', 'close', source=source, color=line_colour)
select.ygrid.grid_line_color = None
select.add_tools(range_tool)
select.toolbar.active_multi = range_tool
# Show the result
show(column(p, select))
return None
# Call Function
create_line_chart_bokeh()
从上面可以看出,那些圈出的区域不是通缉的。有没有人有经验或想法来解决这个问题?
这是我想要实现的目标的草案。我认为删除行的时间间隔可以调整,或固定为2或3个月的差距。
先感谢您,
更新!!
根据下面的答案,这条线现在看起来很合适。但是,悬停线本身存在轻微问题。徘徊在圆圈上工作得很好。
# Import Library
import random
import pandas as pd
from bokeh.core.properties import value
from bokeh.io import show, export_png, output_notebook
from bokeh.plotting import figure, output_file
from bokeh.models import ColumnDataSource, Legend, HoverTool, layouts, CustomJS, Select, Circle, RangeTool
from bokeh.layouts import column
from datetime import date
output_notebook() # Render inline in a Jupyter Notebook
# Create Line Chart
def create_line_chart_bokeh():
# Set data
dates = ['24-11-2017', '28-11-2017', '29-11-2017',
'23-03-2018', '27-03-2018', '12-08-2018']
dates = list(map(lambda i: pd.Timestamp(i), dates))
values = [random.randrange(101) for _ in range(len(dates))]
source = ColumnDataSource(data=dict(date=dates, close=values))
# Set Hover
TOOLTIPS = [
("Average Score", "@close")
]
# Set plot
p = figure(plot_height=300, plot_width=800, tools="xpan", toolbar_location=None,
tooltips=TOOLTIPS, x_axis_type="datetime", x_axis_location="above",
background_fill_color="white", x_range=(dates[0], dates[int(len(dates)-1)]), title='Test Line Chart')
# Set Line and Circle colours
line_colour = '#59819a'
circle_colour = '#ef5b45'
for i in range(len(dates)):
try:
diff = dates[i+1] - dates[i] #Compute difference between dates in days
if diff.days < 30:
p.line([dates[i], dates[i+1]], [values[i], values[i+1]], color=line_colour) #Only plot a line if difference in days < 30
except IndexError:
pass
p.circle('date', 'close', source=source, color=circle_colour, size=4)
p.yaxis.axis_label = 'Scores' # set y axis label
# Set Time Selection Box
select = figure(title="Drag the middle and edges of the selection box to change the range above",
plot_height=130, plot_width=800, y_range=p.y_range,
x_axis_type="datetime", y_axis_type=None,
tools="", toolbar_location=None, background_fill_color="#efefef")
range_tool = RangeTool(x_range=p.x_range)
range_tool.overlay.fill_color = 'navy'
range_tool.overlay.fill_alpha = 0.2
for i in range(len(dates)):
try:
diff = dates[i+1] - dates[i] #Compute difference between dates in days
if diff.days < 30:
select.line([dates[i], dates[i+1]], [values[i], values[i+1]], color=line_colour) #Only plot a line if difference in days < 30
except IndexError:
pass
select.ygrid.grid_line_color = None
select.add_tools(range_tool)
select.toolbar.active_multi = range_tool
# Show the result
show(column(p, select))
return None
# Call Function
create_line_chart_bokeh()
盘旋在圈子上
徘徊在线上
解决了!!
根据以下代码,我现在能够完成所有要求。我拿了一些代码并对我的项目进行了进一步的修改。
# Import Library
import random
import pandas as pd
from bokeh.core.properties import value
from bokeh.io import show, export_png, output_notebook
from bokeh.plotting import figure, output_file
from bokeh.models import ColumnDataSource, Legend, HoverTool, layouts, CustomJS, Select, Circle, RangeTool
from bokeh.layouts import column
from datetime import date
output_notebook() # Render inline in a Jupyter Notebook
# Create Line Chart
def create_line_chart_bokeh():
# Set data
dates = ['24-11-2017', '28-11-2017', '29-11-2017',
'23-03-2018', '27-03-2018', '12-08-2018']
dates = list(map(lambda i: pd.Timestamp(i), dates))
values = [random.randrange(101) for _ in range(len(dates))]
source = ColumnDataSource(data=dict(date=dates, close=values))
# Set plot
p = figure(plot_height=300, plot_width=800, tools="xpan", toolbar_location="right",
x_axis_type="datetime", x_axis_location="above",
background_fill_color="white", x_range=(dates[0], dates[int(len(dates)-1)]), title='Test Line Chart')
# Set Line and Circle colours
line_colour = '#59819a'
circle_colour = '#ef5b45'
lineSource = {'date': [], 'close': []}
date, close = [], []
for i in range(len(dates)):
try:
diff = dates[i+1] - dates[i]
if diff.days < 30:
date.extend([dates[i], dates[i+1]])
close.extend([values[i], values[i+1]])
else:
lineSource['date'].append(date)
lineSource['close'].append(close)
date, close = [], []
except IndexError:
pass
lines = p.multi_line(xs='date', ys='close', source=ColumnDataSource(lineSource), color=line_colour)
circles = p.circle('date', 'close', source=source, color=circle_colour, size=4)
p.yaxis.axis_label = 'Scores' # set y axis label
hoverCircles = HoverTool(renderers=[circles], tooltips=[("Average Score", "@close")])
p.add_tools(hoverCircles)
hoverLines = HoverTool(renderers=[lines], tooltips=[("Average Score", "$y")])
p.add_tools(hoverLines)
# Set Time Selection Box
select = figure(title="Drag the middle and edges of the selection box to change the range above",
plot_height=130, plot_width=800, y_range=p.y_range,
x_axis_type="datetime", y_axis_type=None,
tools="", toolbar_location=None, background_fill_color="#efefef")
range_tool = RangeTool(x_range=p.x_range)
range_tool.overlay.fill_color = 'navy'
range_tool.overlay.fill_alpha = 0.2
select.line('date', 'close', source=source, color=line_colour)
select.ygrid.grid_line_color = None
select.add_tools(range_tool)
select.toolbar.active_multi = range_tool
# Show the result
show(column(p, select))
return None
# Call Function
create_line_chart_bokeh()
只需用for循环绘制该行。每次检查日期之间的距离是否<30天,如果为真则绘制线条。
# Import Library
import random
import pandas as pd
from bokeh.core.properties import value
from bokeh.io import show, export_png, output_notebook
from bokeh.plotting import figure, output_file
from bokeh.models import ColumnDataSource, Legend, HoverTool, layouts, CustomJS, Select, Circle, RangeTool
from bokeh.layouts import column
from datetime import date
output_notebook() # Render inline in a Jupyter Notebook
# Create Line Chart
def create_line_chart_bokeh():
# Set data
dates = ['24-11-2017', '28-11-2017', '29-11-2017',
'23-03-2018', '27-03-2018', '12-08-2018']
dates = list(map(lambda i: pd.Timestamp(i), dates))
values = [random.randrange(101) for _ in range(len(dates))]
source = ColumnDataSource(data=dict(date=dates, close=values))
# Set plot
p = figure(plot_height=300, plot_width=800, tools="xpan", toolbar_location="right",
x_axis_type="datetime", x_axis_location="above",
background_fill_color="white", x_range=(dates[0], dates[int(len(dates)-1)]), title='Test Line Chart')
# Set Line and Circle colours
line_colour = '#59819a'
circle_colour = '#ef5b45'
lineSource = {'date': [], 'close': []}
date, close = [], []
for i in range(len(dates)):
try:
diff = dates[i+1] - dates[i]
if diff.days < 30:
date.extend([dates[i], dates[i+1]])
close.extend([values[i], values[i+1]])
else:
lineSource['date'].append(date)
lineSource['close'].append(close)
date, close = [], []
except IndexError:
pass
lines = p.multi_line(xs='date', ys='close', source=ColumnDataSource(lineSource), color=line_colour)
circles = p.circle('date', 'close', source=source, color=circle_colour, size=4)
p.yaxis.axis_label = 'Scores' # set y axis label
hoverCircles = HoverTool(renderers=[circles], tooltips=[("Average Score", "@close")])
p.add_tools(hoverCircles)
hoverLines = HoverTool(renderers=[lines], tooltips=[("Average Score", "$y")])
p.add_tools(hoverLines)
# Set Time Selection Box
select = figure(title="Drag the middle and edges of the selection box to change the range above",
plot_height=130, plot_width=800, y_range=p.y_range,
x_axis_type="datetime", y_axis_type=None,
tools="", toolbar_location=None, background_fill_color="#efefef")
range_tool = RangeTool(x_range=p.x_range)
range_tool.overlay.fill_color = 'navy'
range_tool.overlay.fill_alpha = 0.2
select.line('date', 'close', source=source, color=line_colour)
select.ygrid.grid_line_color = None
select.add_tools(range_tool)
select.toolbar.active_multi = range_tool
# Show the result
show(column(p, select))
return None
# Call Function
create_line_chart_bokeh()