散景:在热图单元格中显示文本

Bokeh: show text in heatmap cells

我制作了热图:

使用此代码:

import pandas as pd
from bokeh.models import BasicTicker, ColorBar, LinearColorMapper, PrintfTickFormatter, LabelSet
from bokeh.plotting import figure, show

df = pd.read_csv('data.csv', sep=';')

colors = ["#75968f", "#a5bab7", "#c9d9d3", "#e2e2e2", "#dfccce", "#ddb7b1", "#cc7878", "#933b41", "#550b1d"]
mapper = LinearColorMapper(palette=colors, low=df.cpu_sum.min(), high=df.cpu_sum.max())

p = figure(title="Heatmap", toolbar_location=None,
           x_range=days, y_range=list(reversed(hours)),
           x_axis_location="above", width=600, height=600)

p.rect(x="startdate_dayweek", y="startdate_hour", width=1, height=1,
       source=df,
       fill_color={'field': 'cpu_sum', 'transform': mapper},
       line_color=None)

show(p)

所以,我想在热图单元格中显示 'cpu_sum' 值,就像在这个模型上一样:

我尝试了这些代码行,但它不起作用:

labels = LabelSet(x='startdate_dayweek', y='startdate_hour', text='cpu_sum', level='glyph',
                  x_offset=1, y_offset=1, source=df,
                  render_mode='canvas')
p.add_layout(labels)

错误信息:

failed to validate LabelSet(id='21897', ...).source: expected an instance of type DataSource, got     startdate_hour startdate_dayweek  cpu_sum
0                0                 1       62
1                0                 2    27999
2                0                 3    27937
[...]
166              9                 6    22027
167              9                 7    33259

[168 rows x 3 columns] of type DataFrame

您必须进行两项更改:

  1. 确保你要添加的值是string类型,否则你会破坏数字。
  2. 创建一个类似 source= ColumnDataSource(df) 的 ColumnDataSource 并将其传递给 LabelSet 中的 source 关键字。

您可以在下面看到一个最小的示例,其中包含您的列名称但包含虚假数据。

import pandas as pd
from bokeh.models import LinearColorMapper, LabelSet, ColumnDataSource
from bokeh.plotting import figure, show, output_notebook
output_notebook()

# create data
days = []
for i in range(7):
    days.extend([i]*24)
hours = list(range(24))*7
df = pd.DataFrame({
    "startdate_dayweek":days,
    "startdate_hour":hours,
    "cpu_sum":list(range(24*7)),
})
df['cpu_str'] = df['cpu_sum'].astype(str)

# create figure
source= ColumnDataSource(df)
colors = ["#75968f", "#a5bab7", "#c9d9d3", "#e2e2e2", "#dfccce", "#ddb7b1", "#cc7878", "#933b41", "#550b1d"]
mapper = LinearColorMapper(palette=colors, low=df.cpu_sum.min(), high=df.cpu_sum.max())

p = figure(
    title="Heatmap",
    toolbar_location=None,
    x_axis_location="above",
    x_range=(-0.5,6.5),
    y_range=(-0.5,23.5),
    width=600,
    height=600
)

p.rect(
    x="startdate_dayweek",
    y="startdate_hour",
    width=1,
    height=1,
    source=source,
    fill_color={'field': 'cpu_sum', 'transform': mapper},
    line_color=None
)
labels = LabelSet(
    x='startdate_dayweek',
    y='startdate_hour',
    text='cpu_str',
    level='glyph',
    text_align='center',
    y_offset=-7,
    source=source,
    render_mode='canvas'
)
p.add_layout(labels)

show(p)