Python:散景悬停日期时间

qacovj5a  于 2023-06-20  发布在  Python
关注(0)|答案(3)|浏览(111)

我正在尝试通过Python中的散景来获得线条图。我是新的散景,我正试图应用悬停工具提示超过情节。图的X轴具有被转换成时期字符串的时间戳值。我在这里回顾了一些相同的问题,并试图使用我的情况下的变通方法,但它似乎不起作用。在图上,它给出了???,时间应该显示在哪里。
对我的代码有什么建议吗?
时间戳的格式为2016-12-29 02:49:12
还有,有人能告诉我如何格式化x-axis刻度以垂直显示吗?

p = figure(width=1100,height=300,tools='resize,pan,wheel_zoom,box_zoom,reset,previewsave,hover',logo=None)
p.title.text = "Time Series for Price in Euros"
p.grid.grid_line_alpha = 0
p.xaxis.axis_label = "Day"
p.yaxis.axis_label = "Euros"
p.ygrid.band_fill_color = "olive"
p.ygrid.band_fill_alpha = 0.1
p.circle(df['DateTime'],df['EuP'], size=4, legend='close',
  color='darkgrey', alpha=0.2)
p.xaxis.formatter = DatetimeTickFormatter(formats=dict(
hours=["%d %B %Y"],
days=["%d %B %Y"],
months=["%d %B %Y"],
years=["%d %B %Y"],
))

source = ColumnDataSource(data=dict(time=[x.strftime("%Y-%m-%d %H:%M:%S")for x in df['DateTime']]))
hover = p.select(dict(type=HoverTool))
hover.tooltips = {"time":'@time', "y":"$y"}
hover.mode = 'mouse'
p.line(df['DateTime'],df['EuP'],legend='Price',color='navy',alpha=0.7)
oewdyzsn

oewdyzsn1#

自从这个答案最初发布以来,新的工作已经进入散景,使事情变得更简单。日期时间字段可以通过悬停工具直接格式化为日期时间,方法是指定格式化程序,例如:

HoverTool(tooltips=[('date', '@DateTime{%F}')],
          formatters={'@DateTime': 'datetime'})

不再需要在数据源中预先设置日期字段的格式,如下所示。有关详细信息,请参阅设置工具提示字段格式

旧答案

您的工具提示的问题是,您创建了一个带有日期字符串表示的源,但是p.line()调用并不知道它。所以你必须传入一个columndatasource,它有工具提示,x和y值。
下面是你的代码的一个工作变体:

from bokeh.plotting import figure, show
from bokeh.models.formatters import DatetimeTickFormatter
from bokeh.models import ColumnDataSource
from bokeh.models.tools import HoverTool
import pandas as pd
import numpy as np

data = {
    'DateTime' : pd.Series(
        ['2016-12-29 02:49:12',
        '2016-12-30 02:49:12',
        '2016-12-31 02:49:12'],
        dtype='datetime64[ns]'),
    'EuP' : [20,40,15]
}
df = pd.DataFrame(data)
df['tooltip'] = [x.strftime("%Y-%m-%d %H:%M:%S") for x in df['DateTime']]
p = figure(width=1100,height=300,tools='resize,pan,wheel_zoom,box_zoom,reset,previewsave,hover',logo=None)
p.title.text = "Time Series for Price in Euros"
p.grid.grid_line_alpha = 0
p.xaxis.axis_label = "Day"
p.yaxis.axis_label = "Euros"
p.ygrid.band_fill_color = "olive"
p.ygrid.band_fill_alpha = 0.1
p.circle(df['DateTime'],df['EuP'], size=4, legend='close',
  color='darkgrey', alpha=0.2)
p.xaxis.formatter = DatetimeTickFormatter(formats=dict(
 hours=["%d %B %Y"],
 days=["%d %B %Y"],
 months=["%d %B %Y"],
 years=["%d %B %Y"],
))
hover = p.select(dict(type=HoverTool))
tips = [('when','@tooltip'), ('y','$y')]
hover.tooltips = tips
hover.mode = 'mouse'
p.line(x='DateTime', y='EuP', source=ColumnDataSource(df),
       legend='Price',color='navy',alpha=0.7)
show(p)

另外请注意,散景工具提示中缺少格式选项是一个悬而未决的问题。可能有一种更简单的方法,不必将日期字符串格式化为单独的列:
https://github.com/bokeh/bokeh/issues/1239
也有人能告诉我如何格式化x轴记号垂直显示?
我看起来很好,抱歉我帮不上忙。
希望这有帮助!
PS,如果你下次发布一个带有导入语句的工作脚本,以及一个模拟的数据框,以便可以测试,那就更好了。我花了一些时间才把这一切整理好。不过我正在学习散景,所以很好:)

zf2sa74q

zf2sa74q2#

抱歉没有评论,我没有足够的声誉。
@Alex接受的答案对我不起作用(Bokeh 2.0.1),因为它在格式化程序中缺少一个简单的@-符号。工作代码如下:

HoverTool(tooltips=[('date', '@DateTime{%F}')],
          formatters={'@DateTime': 'datetime'})
jljoyd4f

jljoyd4f3#

我为自己创造了一个属于自己的世界。

class Visualization():
    WIDTH = 1000
    TOOLS = "pan,wheel_zoom,box_zoom,reset,save"
 
class ScatterChart(Visualization):
    def __init__(self, data, spec:Dict):
        self.data = data
        self.x_column = spec["x_axis"]
        self.y_column = spec["y_axis"]    
        self.series_ = spec["series_column"]
        
        self.xlabel = spec['xlabel'] 
        self.ylabel = spec['ylabel'] 
        self.title = spec['title'] 
        
    def prepare_data(self):
        
        # Get  Axis Type
        self.xtype = 'datetime' if self.data.dtypes[self.x_column].type is np.datetime64 else 'linear'
        self.ytype = 'datetime' if self.data.dtypes[self.x_column].type is np.datetime64 else 'linear'
        
        return self.data
    
    def render(self):
        df_ = self.prepare_data()
        
        format_= {}
        tool_tip=[]
        
        # For axis
        for col in [self.x_column, self.y_column , self.series_]:
            
            if self.data.dtypes[col].type is np.datetime64:
                format_['@' + str(col) ] = "datetime" # formatter
                tool_tip.append(tuple([str(col) , '@' + str(col) + '{%F}'])) # tool-tip
                
            else:
                format_['@' + str(col) ] = "numeral" # 
                tool_tip.append(tuple([str(col) , '@' + str(col)]))
            
        
        # print(format_)
        # print(tool_tip)
        
        
        # Add Hover parameters
        hover = HoverTool(tooltips= tool_tip
            , formatters=format_   )
        
        
        
        p=figure(
                 width = super().WIDTH,
                 height = 500,
                 x_axis_label = self.xlabel,
                 x_axis_type=self.xtype,
                 y_axis_label = self.ylabel,
                 y_axis_type=self.ytype,
                 title = self.title,
                 tools = super().TOOLS
                 )
        
        # Get Only Top 10 groups/series to display
        for value, color in zip(islice(self.data.groupby(by=[self.series_]
                            )[self.series_].count().sort_values(ascending=False).rename('cnt').reset_index()[self.series_].tolist(), 10), Category10[10]):
            
            p.scatter(
                    x=self.x_column,
                    y=self.y_column,
                    source=df_.loc[(df_[self.series_]==value)],
                    color=color,
                    legend_group=self.series_
                      )
            
        p.add_tools(hover)
        p.toolbar.logo = None
        p.legend.location = "top_left"
        p.legend.click_policy="hide"
                
        return p
    
# end of ScatterChart

这是我如何初始化它

from visualization import ScatterChart
sc = ScatterChart( 
    df,
    {'x_axis' :'ts', 
     'y_axis': 'Discus',
     'series_column': 'Competition',
      'xlabel':'Discus',
      'ylabel':'Javeline',
     'title':'Discus Vs Javeline'
     })
d = sc.render()
show(d)

相关问题