Python Bokeh - 混合

标签 python bar-chart bokeh

维护人员的说明:此问题涉及已过时的 bokeh.charts API,该 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 个条形的条形图:

  • 一根柱形图表示当月“值”的平均值
  • 一栏表示当月“值(value)”的最大值
  • 一个柱形表示该月“值”的平均值

我可以使用 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 网站很棒,但对于这个特定项目来说,它并不是很详细。

最佳答案

维护人员的说明:此问题涉及已过时的 bokeh.charts API,该 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"
         ]

看起来你的日期格式是“日-月-年” - 我使用了 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 resample 对日期进行下采样,获取每个月的适当值,然后合并到数据帧中。

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

最后我们进入图表部分。就像奥运会奖牌的例子一样,我们将一些论点传递给巴尔。 您可以随心所欲地使用这些内容,但注意我是通过将图例完全构建在图表之外来添加图例的。如果您有很多数据点,那么图表上的构建方式会变得非常困惑。

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

Bokeh_output

如果您复制/粘贴此代码,您将显示以下内容。
如果您自己渲染它或提供它:将鼠标悬停在每个 block 上以查看工具提示(值)。

我没有抽象出我能想到的一切(我想到了颜色)。

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

***您可能会考虑 timeseries chart 。这可以消除在绘图之前完成的一些数据整理。

您也可以考虑grouping your bars而不是堆叠它们。这样您就可以轻松可视化每个月的数字。

关于Python Bokeh - 混合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39394634/

相关文章:

python - 在Python中的多重继承中使用相同的函数

python - 原始输入和打印同时进行

python - 如何让 Celery 返回一个 json 对象而不是 bytea?

python - 如何在 Flask 服务器中将 python JSON 转换为 html 表?

Python .csv转pandas dataframe绘制bokeh的烛台图

python - Bokeh 数据表未显示在 Flask 中

python - 如何将月份和年份数据绘制到条形图上?

r - 当有 2 组时在格子中的条形图中添加错误栏

r - 用正值和负值标记堆叠条形图

python - Bokeh 以交互方式更改正在绘制的列