散景:多折线图中的图例外图
Bokeh: Legend outside plot in multi line chart
我在 Bokeh 中有一个多线图:
import pandas as pd
from bokeh.plotting import figure, show
from bokeh.palettes import Category20c_7
from bokeh.io import output_file
from bokeh.models import SingleIntervalTicker, LinearAxis, ColumnDataSource
output_file("conso_daily.html")
treatcriteria_daily_data = pd.read_csv("treatcriteria_evolution.csv", sep=';')
final_daily_data = treatcriteria_daily_data.groupby(['startdate_weekyear','startdate_dayweek'],as_index = False).sum().pivot('startdate_weekyear','startdate_dayweek').fillna(0)
# keep only integer values in x axis
def interval_integer(plot):
ticker = SingleIntervalTicker(interval=1, num_minor_ticks=1)
xaxis = LinearAxis(ticker=ticker)
plot.add_layout(xaxis, 'below')
numlines = len(final_daily_data.columns)
palette = Category20c_7[0:numlines]
# remove the last week if there is not all the data
data_without_last_week = final_daily_data[(final_daily_data != 0).all(1)]
cpu_values_daily = data_without_last_week.values.T.tolist()
weeks = []
for i in range(0,len(data_without_last_week.columns)):
weeks.append(data_without_last_week.index)
df = {'week': weeks,
'day': ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'],
'color': ['red', 'orange', 'yellow', 'green', 'grey', 'pink', 'purple'],
'HCPU': cpu_values_daily}
source = ColumnDataSource(df)
p = figure(width=800, height=500)
p.multi_line(xs='week', ys='HCPU', legend='day', color='color',
line_width=5, line_alpha=0.6, hover_line_alpha=1.0,
source=source)
p.xaxis.visible = False
p.left[0].formatter.use_scientific = False
interval_integer(p)
show(p)
我想在绘图区域外显示图例,因为顶部曲线(星期日)被隐藏了。
我尝试关注此线程,但它适用于单行而不适用于多行:
使用此代码,我搜索以在绘图区域外显示图例,但它不起作用:
legend = Legend(items=[
('Monday', [p[0]]),
('Tuesday', [p[1]]),
('Wednesday', [p[2]]),
('Thursday', [p[3]]),
('Friday', [p[4]]),
('Saturday', [p[5]]),
('Sunday', [p[6]]),
], location=(0, -30))
p.add_layout(legend, 'right')
TypeError: 'Figure' object is not subscriptable
谢谢。
编辑:这是我的数据'final_daily_data'如果有用的话:
mc_cpu_hours \
startdate_dayweek 1 2 3
startdate_weekyear
27 527644.000731 468053.338183 517548.838022
28 349896.850976 481313.693908 372385.568095
29 168595.113447 388117.184580 373894.548600
30 176007.786269 364379.872622 366155.953075
31 177517.591864 0.000000 0.000000
startdate_dayweek 4 5 6 7
startdate_weekyear
27 573669.325129 515710.534260 511711.421986 841073.028107
28 378069.713821 385937.231788 385856.666340 842468.209151
29 343235.942227 376405.876236 400007.946715 662019.708660
30 375948.240935 366151.336263 395790.387672 700936.336812
31 0.000000 0.000000 0.000000 686023.780120
您的问题在 legend = Legend(items=[('Monday', [p[0]]), ...])
中,或者更精确地在 p[0]
,...,p[7]
中。图形对象不可订阅,因为它不是列表或字典,这会引发错误。我认为在你的情况下定义 Legend()
-class 空白就足够了,没有任何进一步的信息。
小例子
import pandas as pd
from bokeh.plotting import figure, show, output_notebook
from bokeh.models import Legend
output_notebook()
source = pd.DataFrame({
'xs':[[1,2,3,4],[1,2,3,4]],
'ys':[[1,2,3,4],[4,3,2,1]],
'label':['a','b'],
'color':['blue','green']
})
p = figure(width=400, height=300)
p.add_layout(Legend(),'right')
p.multi_line(xs='xs', ys='ys', legend_field ='label', color='color', source=source)
show(p)
输出
我在 Bokeh 中有一个多线图:
import pandas as pd
from bokeh.plotting import figure, show
from bokeh.palettes import Category20c_7
from bokeh.io import output_file
from bokeh.models import SingleIntervalTicker, LinearAxis, ColumnDataSource
output_file("conso_daily.html")
treatcriteria_daily_data = pd.read_csv("treatcriteria_evolution.csv", sep=';')
final_daily_data = treatcriteria_daily_data.groupby(['startdate_weekyear','startdate_dayweek'],as_index = False).sum().pivot('startdate_weekyear','startdate_dayweek').fillna(0)
# keep only integer values in x axis
def interval_integer(plot):
ticker = SingleIntervalTicker(interval=1, num_minor_ticks=1)
xaxis = LinearAxis(ticker=ticker)
plot.add_layout(xaxis, 'below')
numlines = len(final_daily_data.columns)
palette = Category20c_7[0:numlines]
# remove the last week if there is not all the data
data_without_last_week = final_daily_data[(final_daily_data != 0).all(1)]
cpu_values_daily = data_without_last_week.values.T.tolist()
weeks = []
for i in range(0,len(data_without_last_week.columns)):
weeks.append(data_without_last_week.index)
df = {'week': weeks,
'day': ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'],
'color': ['red', 'orange', 'yellow', 'green', 'grey', 'pink', 'purple'],
'HCPU': cpu_values_daily}
source = ColumnDataSource(df)
p = figure(width=800, height=500)
p.multi_line(xs='week', ys='HCPU', legend='day', color='color',
line_width=5, line_alpha=0.6, hover_line_alpha=1.0,
source=source)
p.xaxis.visible = False
p.left[0].formatter.use_scientific = False
interval_integer(p)
show(p)
我想在绘图区域外显示图例,因为顶部曲线(星期日)被隐藏了。
我尝试关注此线程,但它适用于单行而不适用于多行:
使用此代码,我搜索以在绘图区域外显示图例,但它不起作用:
legend = Legend(items=[
('Monday', [p[0]]),
('Tuesday', [p[1]]),
('Wednesday', [p[2]]),
('Thursday', [p[3]]),
('Friday', [p[4]]),
('Saturday', [p[5]]),
('Sunday', [p[6]]),
], location=(0, -30))
p.add_layout(legend, 'right')
TypeError: 'Figure' object is not subscriptable
谢谢。
编辑:这是我的数据'final_daily_data'如果有用的话:
mc_cpu_hours \
startdate_dayweek 1 2 3
startdate_weekyear
27 527644.000731 468053.338183 517548.838022
28 349896.850976 481313.693908 372385.568095
29 168595.113447 388117.184580 373894.548600
30 176007.786269 364379.872622 366155.953075
31 177517.591864 0.000000 0.000000
startdate_dayweek 4 5 6 7
startdate_weekyear
27 573669.325129 515710.534260 511711.421986 841073.028107
28 378069.713821 385937.231788 385856.666340 842468.209151
29 343235.942227 376405.876236 400007.946715 662019.708660
30 375948.240935 366151.336263 395790.387672 700936.336812
31 0.000000 0.000000 0.000000 686023.780120
您的问题在 legend = Legend(items=[('Monday', [p[0]]), ...])
中,或者更精确地在 p[0]
,...,p[7]
中。图形对象不可订阅,因为它不是列表或字典,这会引发错误。我认为在你的情况下定义 Legend()
-class 空白就足够了,没有任何进一步的信息。
小例子
import pandas as pd
from bokeh.plotting import figure, show, output_notebook
from bokeh.models import Legend
output_notebook()
source = pd.DataFrame({
'xs':[[1,2,3,4],[1,2,3,4]],
'ys':[[1,2,3,4],[4,3,2,1]],
'label':['a','b'],
'color':['blue','green']
})
p = figure(width=400, height=300)
p.add_layout(Legend(),'right')
p.multi_line(xs='xs', ys='ys', legend_field ='label', color='color', source=source)
show(p)
输出