Python 如何在Bokeh中将数据标签添加到条形图?

Python 如何在Bokeh中将数据标签添加到条形图?,python,bokeh,Python,Bokeh,在Bokeh指南中有可以创建的各种条形图的示例 此代码将创建一个: from bokeh.charts import Bar, output_file, show from bokeh.sampledata.autompg import autompg as df p = Bar(df, 'cyl', values='mpg', title="Total MPG by CYL") output_file("bar.html") show(p) 我的问题是,是否可以将数据标签添加到图表的每

在Bokeh指南中有可以创建的各种条形图的示例

此代码将创建一个:

from bokeh.charts import Bar, output_file, show
from bokeh.sampledata.autompg import autompg as df

p = Bar(df, 'cyl', values='mpg', title="Total MPG by CYL")

output_file("bar.html")

show(p)
我的问题是,是否可以将数据标签添加到图表的每个条形图中?我在网上搜索了一下,但没有找到一个明确的答案。

请BOKEH维护人员注意,下面的答案中提到了BOKEH的部分。图表只对历史感兴趣。
bokeh.charts
API被弃用,随后从bokeh删除。有关稳定的
bokeh.plotting
API的信息,请参见此处和上方的答案


是的,您可以向图表的每个栏添加标签。有几种方法可以做到这一点。默认情况下,标签与数据绑定。但您可以更改显示的内容。以下是使用您的示例执行此操作的几种方法:

from bokeh.charts import Bar, output_file, show
from bokeh.sampledata.autompg import autompg as df
from bokeh.layouts import gridplot

from pandas import DataFrame
from bokeh.plotting import figure, ColumnDataSource
from bokeh.models import Range1d, HoverTool

# output_file("bar.html")

""" Adding some sample labels a few different ways.
    Play with the sample data and code to get an idea what does what.
    See below for output.
"""
样本数据(新标签):

我使用了一些逻辑来确定新的dataframe列。当然,您可以使用
df
中已有的另一列(这完全取决于您使用的数据)。这里真正需要的是为数据帧提供一个新列

# One method
labels = []
for number in df['cyl']:
    if number == 3:
        labels.append("three")
    if number == 4:
        labels.append("four")
    if number == 5:
        labels.append("five")
    if number == 6:
        labels.append("six")
    if number == 8:
        labels.append("eight")

df['labels'] = labels
获取新数据帧列的另一种方法。同样,我们只需要提供
df
一个用于条形图的新列

# Another method
def new_labels(x):
    if x % 2 != 0 or x == 6:
        y = "Inline"
    elif x % 2 == 0:
        y = "V"
    else:
        y = "nan"
    return y

df["more_labels"] = df["cyl"].map(new_labels)
现在条形图:

我有两种方法。p1只指定新标签。请注意,因为我使用了字符串,所以它在图表上按字母顺序排列。p2使用原始标签,并在同一条上添加我的新标签

# Specifying your labels
p1 = Bar(df, label='labels', values='mpg',
         title="Total MPG by CYL, remapped labels, p1",
         width=400, height=400, legend="top_right")
p2 = Bar(df, label=['cyl', 'more_labels'], values='mpg',
         title="Total MPG by CYL, multiple labels, p2", width=400, height=400,
         legend="top_right")
另一种方式:

Bokeh有三个主要的“接口级别”。高级
图表
提供快速便捷的访问,但功能有限<代码>绘图提供更多选项<代码>型号提供了更多选项

这里我使用的是plotting界面和包含
rect
方法的
Figure
类。这使您可以更详细地控制图表

# Plot with "intermediate-level" bokeh.plotting interface
new_df = DataFrame(df.groupby(['cyl'])['mpg'].sum())
factors = ["three", "four", "five", "six", "eight"]
ordinate = new_df['mpg'].tolist()
mpg = [x * 0.5 for x in ordinate]

p3 = figure(x_range=factors, width=400, height=400,
            title="Total MPG by CYL, using 'rect' instead of 'bar', p3")
p3.rect(factors, y=mpg, width=0.75, height=ordinate)
p3.y_range = Range1d(0, 6000)
p3.xaxis.axis_label = "x axis name"
p3.yaxis.axis_label = "Sum(Mpg)"
添加特定标签的第四种方法:

这里我使用的是
悬停
绘图工具。将鼠标悬停在每个栏上以显示指定的标签

# With HoverTool, using 'quad' instead of 'rect'
top = [int(x) for x in ordinate]
bottom = [0] * len(top)
left = []
[left.append(x-0.2) for x in range(1, len(top)+1)]
right = []
[right.append(x+0.2) for x in range(1, len(top)+1)]
cyl = ["three", "four", "five", "six", "eight"]
source = ColumnDataSource(
    data=dict(
        top=[int(x) for x in ordinate],
        bottom=[0] * len(top),
        left=left,
        right=right,
        cyl=["three", "four", "five", "six", "eight"],
    )
)

hover = HoverTool(
    tooltips=[
        ("cyl", "@cyl"),
        ("sum", "@top")
    ]
)

p4 = figure(width=400, height=400,
            title="Total MPG by CYL, with HoverTool and 'quad', p4")
p4.add_tools(hover)
p4.quad(top=[int(x) for x in ordinate], bottom=[0] * len(top),
        left=left, right=right, color="green", source=source)
p4.xaxis.axis_label = "x axis name"
在网格中显示所有四个图表:

grid = gridplot([[p1, p2], [p3, p4]])
show(grid)
这些是我所知道的方式。可能还有其他人。改变任何你喜欢的,以满足你的需要。下面是运行所有这些将输出的内容(您必须运行它或提供它才能获得hovertool):

使用标签集 使用Labelset在每个单条上创建标签

在我的示例中,我将vbar与绘图界面一起使用,它的级别比图表界面低一点,但可能有一种方法可以将其添加到条形图中

from bokeh.palettes import PuBu
from bokeh.io import show, output_notebook
from bokeh.models import ColumnDataSource, ranges, LabelSet
from bokeh.plotting import figure
output_notebook()

source = ColumnDataSource(dict(x=['Áætlaðir','Unnir'],y=[576,608]))

x_label = ""
y_label = "Tímar (klst)"
title = "Tímar; núllti til þriðji sprettur."
plot = figure(plot_width=600, plot_height=300, tools="save",
        x_axis_label = x_label,
        y_axis_label = y_label,
        title=title,
        x_minor_ticks=2,
        x_range = source.data["x"],
        y_range= ranges.Range1d(start=0,end=700))


labels = LabelSet(x='x', y='y', text='y', level='glyph',
        x_offset=-13.5, y_offset=0, source=source, render_mode='canvas')

plot.vbar(source=source,x='x',top='y',bottom=0,width=0.3,color=PuBu[7][2])

plot.add_layout(labels)
show(plot)


您可以在这里找到关于labelset的更多信息:

谢谢您的精彩回答,Ben。我在寻找一种方法,用图表在每个图表的顶部显示总和,但我想这是不可能的。啊,我明白了。是的,可能不使用图表界面,但我确信有办法做到这一点。有没有办法自动将数据标签居中,而不是手动偏移?将
text\u align='center'
添加到LabelSet构造函数中。