如何在折线图(Bokeh)中删除时间间隔之间的线?

问题描述 投票:0回答:1

我一直在尝试创建一个折线图,将'值'表示为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()

LineChart

从上面可以看出,那些圈出的区域不是通缉的。有没有人有经验或想法来解决这个问题?

这是我想要实现的目标的草案。我认为删除行的时间间隔可以调整,或固定为2或3个月的差距。

Example

先感谢您,

更新!!

根据下面的答案,这条线现在看起来很合适。但是,悬停线本身存在轻微问题。徘徊在圆圈上工作得很好。

# 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()

盘旋在圈子上

Circle

徘徊在线上

Line

解决了!!

根据以下代码,我现在能够完成所有要求。我拿了一些代码并对我的项目进行了进一步的修改。

# 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()
python pandas bokeh
1个回答
0
投票

只需用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()

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.