【问题标题】:Bokeh y axis ticks in bits and have it scale from an SI magnitude perspective散景 y 轴以位为单位,并从 SI 幅度的角度对其进行缩放
【发布时间】:2020-12-04 18:41:24
【问题描述】:

这里的第一个问题非常有意识,我的方法可能不是正确的,而是祈祷!

我希望在 Bokeh Y 轴上(相对于 x 轴上的时间)从 pandas DataFrame 中绘制每秒位数,虽然我可以使用 PrintfTickFormatter 手动调整我的刻度,但它们不会按比例缩放我已经实现了:

p.yaxis[0].formatter = PrintfTickFormatter(format="%3f M")

我的原始数据以字节为单位,所以我在绘制为位之前在我的 DataFrame 中将其转换(在计算当前字节和先前字节之间的差异并转换为位之后,然后在这种情况下除以 600 以获得每秒值)但通常我的数据是兆位或千兆位,所以我真的不想以位为单位绘制,因为它变得难以理解,我真的不想像上面那样使用 PrintfTickFormatter 手动调整,因为我必须将 CumulbitsPerSecond 除以相关绘制之前的单位(除非我可以在此格式化程序中以某种方式缩放和解释 SI 单位,或者根据绘制的值实现某种 y 轴循环)。

例如,这是一个示例 DataFrame:

                            CumulativeBytes  CumulBytesDiff  CumulbitsDiff  CumulbitsPerSecond
DateTime
2020-12-05 09:40:03.175453          1000000             NaN            NaN                 NaN
2020-12-05 09:50:03.175453          3000000       2000000.0     16000000.0        26666.666667
2020-12-05 10:00:03.175453          4000000       1000000.0      8000000.0        13333.333333
2020-12-05 10:10:03.175453          7000000       3000000.0     24000000.0        40000.000000
2020-12-05 10:20:03.175453          8000000       1000000.0      8000000.0        13333.333333
2020-12-05 10:30:03.175453          9200000       1200000.0      9600000.0        16000.000000
2020-12-05 10:40:03.175453         10600000       1400000.0     11200000.0        18666.666667

我正在寻找的正是 NumeralTickFormatter 字节 y 刻度轴调整器所做的:

p.yaxis[0].formatter = NumeralTickFormatter(format="0.0b")

...但对于位。也许 FuncTickFormatter 可能会有所帮助,但我无法理解如何在 python3.6 Bokeh 2.2.3 中实现它。

如果命名为 df,则绘制上述 DataFrame 的示例代码如下:

from bokeh.plotting import figure, output_file, show
from bokeh.models import ColumnDataSource, NumeralTickFormatter, PrintfTickFormatter

output_file('stackoverflowq.html')

p = figure(x_axis_type="datetime")

p.line(x='DateTime', y='CumulbitsPerSecond', color='blue', source=df)

# Only allows me to reference bytes when I need to plot bits
#p.yaxis.formatter = NumeralTickFormatter(format="0.0b")

# Requires manual adjustment of bits to Kilobits in the instance with the dataframe above
#p.yaxis[0].formatter = PrintfTickFormatter(format="%3f Kbps")

p.xaxis.axis_label = 'Date Time'
p.yaxis.axis_label = 'bits per second'

show(p)

谁能给点建议?也很高兴提供 DataFrame 代码,但希望这已经足够了。

输出图如下,在这种情况下,我希望 Y 轴刻度显示为 Kb 或 Kbps,如果位值在兆位区域内,则显示为 Mb 或 Mbps 等。

谢谢!

【问题讨论】:

  • 欢迎来到stackoverflow!我建议您发布一些您尝试过的示例代码(连同一些示例数据)——您将更有可能得到有用的回复。
  • 嗨 C.Braun!感谢您在更改代码 sn-ps 开始时对大写字母进行的可读性编辑。我将使用一些示例代码和可能的示例图来编辑查询,尽管努力保持简短。也许我只需要以某种方式将问题改写为“如何以与 SI 单位匹配的标量方式在 y 轴上绘制位?”就这样吧!

标签: python bokeh


【解决方案1】:

据我了解,您正在寻找这样的东西:

p.yaxis.formatter = FuncTickFormatter(code='''if (tick < 1000){
                                                  return (tick) + ' ' + 'BpS'
                                              }
                                              else if (tick < 1000000){
                                                  return (tick/1000) + ' ' + 'KiBpS'
                                              }
                                              else{
                                                  return (tick/1000000) + ' ' + 'MBpS'
                                                }'''
                                     )

这是您问题的 JavaScript 解决方案。

最小示例

import pandas as pd

from bokeh.plotting import figure, output_notebook, show
from bokeh.models import ColumnDataSource, FuncTickFormatter
output_notebook()

df = pd.DataFrame({'BitsPerSeconde': [26, 13333, 40000, 1333300, 16666]})
p = figure()

p.line(x='index', y='BitsPerSeconde', color='blue', source=df)
p.yaxis.formatter = FuncTickFormatter(code='''if (tick < 1000){return (tick) + ' ' + 'BpS'}
                                              else if (tick < 1000000){
                                                  return (tick/1000) + ' ' + 'KiBpS'
                                                  }
                                              else{
                                                  return (tick/1000000) + ' ' + 'MBpS'
                                                }'''
                                     )
p.yaxis.axis_label = 'bits per second'
show(p)

这是输出。

【讨论】:

  • 嗨 mosc9575 - 非常感谢你!我已经能够根据需要使用/适应(基本上只是放弃使用大写 B 以避免解释为字节),所以我很感激!就使用 Javascript 计算刻度的处理时间而言,您是否会说这会增加很多开销(也许很难量化,但如果我有 50 行,每行有 144 个值要绘制)?有人建议然后删除,使用一种预处理方法,我根据 DataFrame 中的 df.max() 值计算一个字符串,尽管我担心这种方法会阻止单位之间的缩放。
猜你喜欢
  • 1970-01-01
  • 2020-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-18
  • 1970-01-01
  • 1970-01-01
  • 2020-08-25
相关资源
最近更新 更多