Python 散景 - 混合

Python Bokeh - blending

维护者的注释:这个问题涉及多年前删除的过时 bokeh.charts API。有关使用现代 Bokeh 创建各种条形图的信息,请参阅:

https://docs.bokeh.org/en/latest/docs/user_guide/categorical.html



已过时:

我正在尝试从 Python Bokeh 库中的数据框 df 创建条形图。我的数据看起来像:

value datetime
5    01-01-2015
7    02-01-2015
6    03-01-2015
...  ... (for 3 years)

我想要一个每月显示 3 个柱状图的条形图:

我可以使用 MEAN/MAX/MIN 创建一个条形图:

from bokeh.charts import Bar, output_file, show
p = Bar(df, 'datetime', values='value', title='mybargraph',
         agg='mean', legend=None)
output_file('test.html')
show(p)

我怎么能在同一个图上有 3 个柱(平均值、最大值、最小值)?如果可能的话,堆叠在一起。

看起来 blend 可以帮到我(比如这个例子:

http://docs.bokeh.org/en/latest/docs/gallery/stacked_bar_chart.html

但我找不到有关其工作原理的详细说明。散景网站很棒,但对于这个特定项目,它并不是很详细。

维护者的注释:这个问题涉及多年前删除的过时 bokeh.charts API。有关使用现代 Bokeh 创建各种条形图的信息,请参阅:

https://docs.bokeh.org/en/latest/docs/user_guide/categorical.html



已过时:

那个混合示例让我走上了正确的轨道。

import pandas as pd
from pandas import Series
from dateutil.parser import parse
from bokeh.plotting import figure
from bokeh.layouts import row
from bokeh.charts import Bar, output_file, show
from bokeh.charts.attributes import cat, color
from bokeh.charts.operations import blend

output_file("datestats.html")

只是一些示例数据,您可以随意更改它。 首先,我必须将数据整理成正确的格式。

# Sample data
vals = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
dates = ["01-01-2015", "02-01-2015", "03-01-2015", "04-01-2015",
         "01-02-2015", "02-02-2015", "03-02-2015", "04-02-2015",
         "01-03-2015", "02-03-2015", "03-03-2015", "04-03-2015"
         ]

看起来你的日期格式是 "day-month-year" - 我使用了 dateutil.parser 所以 pandas 会正确识别它。

# Format data as pandas datetime objects with day-first custom
days = []
days.append(parse(x, dayfirst=True) for x in dates)

您还需要按月分组 - 我使用 pandas 重新采样对日期进行下采样,为每个月获取适当的值,然后合并到一个数据框中。

# Put data into dataframe broken into min, mean, and max values each for month
ts = Series(vals, index=days[0])
firstmerge = pd.merge(ts.resample('M').min().to_frame(name="min"),
                      ts.resample('M').mean().to_frame(name="mean"),
                      left_index=True, right_index=True)
frame = pd.merge(firstmerge, ts.resample('M').max().to_frame(name="max"),
                 left_index=True, right_index=True)

Bokeh 允许您使用 pandas 数据框的索引作为图表的 x 值, 作为 discussed here 但它不喜欢日期时间值,所以我为日期标签添加了一个新列。请参阅下面的时间序列评论***。

# You can use DataFrame index for bokeh x values but it doesn't like timestamp
frame['Month'] = frame.index.strftime('%m-%Y')

终于到了图表部分。就像奥运会奖牌的例子一样,我们将一些参数传递给 Bar。 随心所欲地玩这些,但 请注意 我通过完全在图表之外构建图例来添加图例。如果你有很多数据点,它在图表上的构建方式会变得非常混乱。

# Main object to render with stacking
bar = Bar(frame,
          values=blend('min', 'mean', 'max',
                       name='values', labels_name='stats'),
          label=cat(columns='Month', sort=False),
          stack=cat(columns='values', sort=False),
          color=color(columns='values',
                      palette=['SaddleBrown', 'Silver', 'Goldenrod'],
                      sort=True),
          legend=None,
          title="Statistical Values Grouped by Month",
          tooltips=[('Value', '@values')]
          )

# Legend info (displayed as separate chart using bokeh.layouts' row)
factors = ["min", "mean", "max"]
x = [0] * len(factors)
y = factors
pal = ['SaddleBrown', 'Silver', 'Goldenrod']
p = figure(width=100, toolbar_location=None, y_range=factors)
p.rect(x, y, color=pal, width=10, height=1)
p.xaxis.major_label_text_color = None
p.xaxis.major_tick_line_color = None
p.xaxis.minor_tick_line_color = None

# Display chart
show(row(bar, p))

如果您copy/paste此代码,这就是您将显示的内容
如果您自己渲染它或提供它:将鼠标悬停在每个块上以查看工具提示(值)。

我没有尽我所能抽象一切(想到颜色)。

这是您想要构建的图表类型,但似乎不同的图表样式会更丰富地显示数据,因为堆叠总计(最小值 + 平均值 + 最大值)不提供有意义的信息。但是我不知道你的数据到底是什么。

***你可以考虑 timeseries chart。这可以消除在绘图之前完成的一些数据争论。

您也可以考虑 grouping your bars 而不是堆叠它们。这样你就可以很容易地看到每个月的数字。