散景:多个时间序列图例没有正确绘图

时间:2017-04-04 17:10:34

标签: time-series legend bokeh

散景中的传说有点笨拙。如果我将它与HoverTools和ColumnDataSource结合使用,它会尝试将一行中的所有点显示为新的图例条目。下面是一个简单的例子。所有代码都可以在Bokeh 12.4和Anaconda 2.7的标准库中使用。

# a simple time series data-set:

import pandas as pd
import numpy as np
import datetime
import matplotlib.pyplot as plt

data1, data2 = np.random.randn(365, 1)+2, np.random.randn(365, 1)-2
data = np.concatenate((data1,data2), axis=1)
start, end = datetime.datetime(2015, 1, 1), datetime.datetime(2015, 12, 31)
ts= pd.DataFrame(data=data,
                    index=pd.DatetimeIndex(start=start, end=end, freq="D"),
                    columns=["1", "2"],
                    dtype=float)
ts.plot()
plt.show()

现在使用Bokeh添加悬停工具提示和更美观的情节:

# Now use Bokeh:

from bokeh.plotting import figure
from bokeh.models import ColumnDataSource, HoverTool
from bokeh.palettes import Spectral6
from bokeh.models.formatters import DatetimeTickFormatter
from bokeh.io import push_notebook, show, output_notebook
output_notebook()

def multiTimeSeriesPlot(ts, plotFeatures):

    # pre-processing
    ts.index.rename("datetime", inplace=True)
    ts = ts.reset_index()
    ts['tooltip'] = [x.strftime("%Y-%m-%d %H:%M:%S") for x in ts['datetime']]

    data = ColumnDataSource(ts)

    # define color palette:
    mypalette=Spectral6[0:len(plotFeatures)]
    color_ix = 0

    p = figure(width=700, height=400, tools= ['hover','pan','box_zoom', 'reset', 'wheel_zoom'])

    for feature in plotFeatures:
        p.line(x='datetime', y=feature, source=data, name='line', 
        legend=feature, line_width=2, color=mypalette[color_ix])
        color_ix += 1
        p.circle(x='datetime', y=feature, source=data, name='sample', 
        legend='sample', size=4, color='darkgrey', alpha=0.2)



    p.xaxis.formatter = DatetimeTickFormatter(hours=["%d %B %Y"],
                                               days=["%d %B %Y"],
                                              months=["%d %B %Y"],
                                              years=["%d %B %Y"])
    ## Hover tools
    hover = p.select(dict(type=HoverTool))
    hover.tooltips, hover.name, hover.mode = [('when','@tooltip'), 
    ('y','$y')], 'sample', 'mouse'

    show(p)

    # And finally, call with:

multiTimeSeriesPlot(ts=ts, plotFeatures=["1", "2"])

我做错了什么?如果我不将数据转换为ColumnDataSource,则以下代码有效。但是不使用ColumnDataSource打破了工具提示模块。

1 个答案:

答案 0 :(得分:1)

我在这里回答了我自己的问题,咨询了以下内容:

In Bokeh, how do I add tooltips to a Timeseries chart (hover tool)?

根本区别在于,不是将整个数据帧转换为ColumnDataSource,而是遍历每个时间序列以绘制并将其转换为ColumnDataSource。虽然这在计算上效率低下,但它可以工作:

from bokeh.io import push_notebook, show, output_notebook
from bokeh.plotting import figure
from bokeh.models import ColumnDataSource, HoverTool
from bokeh.palettes import Spectral6
from bokeh.models.formatters import DatetimeTickFormatter
output_notebook()

def multiTimeSeriesPlot(ts, plotFeatures):

    # pre-processing
    ts.index.rename("datetime", inplace=True)
    ts = ts.reset_index()
    ts['tooltip'] = [x.strftime("%Y-%m-%d %H:%M:%S") for x in ts['datetime']]

    # define color palette:
    mypalette=Spectral6[0:len(plotFeatures)]
    color_ix = 0

    p = figure(width=700, height=400, tools= ['hover','pan','box_zoom', 'reset', 'wheel_zoom'])

    for count, feature in enumerate(plotFeatures):

        # bokeh can't show datetime object in tooltip properly,so we use string instead
        source = ColumnDataSource(data={
                    'dateX': ts["datetime"], # python datetime object as X axis
                    'v': list(ts[feature]),
                    'tooltip': ts['tooltip'], #string of datetime for display in tooltip
                    'name': [feature for n in xrange(len(ts))]
                })

        p.line('dateX', 'v',source=source,legend='name', color=mypalette[count])
        circle = p.circle('dateX', 'v',source=source, fill_color="white", size=5,
                          legend='name', color=mypalette[count])

    p.xaxis.formatter = DatetimeTickFormatter(hours=["%d %B %Y"],
                                               days=["%d %B %Y"],
                                              months=["%d %B %Y"],
                                              years=["%d %B %Y"])
    ## Hover tools
    hover = p.select(dict(type=HoverTool))
    hover.tooltips, hover.name, hover.mode = [('when','@tooltip'), 
    ('y','$y')], 'sample', 'mouse'

    show(p)

并致电:

multiTimeSeriesPlot(ts=test, plotFeatures=["1", "2"])