问题
How can I add a legend to lines in Step graph example for bokeh:
https://docs.bokeh.org/en/latest/docs/reference/models/glyphs/step.html
I would like to have legend in 'top right' corner of plot for each line in color and style of the line.
The default code for the example is:
import numpy as np
from bokeh.models import ColumnDataSource, DataRange1d, Plot, LinearAxis, Grid
from bokeh.models.glyphs import Step
from bokeh.io import curdoc, show
N = 11
x = np.linspace(-2, 2, N)
y = x**2
source = ColumnDataSource(dict(x=x, y1=y, y2=y+2, y3=y+4))
xdr = DataRange1d()
ydr = DataRange1d()
plot = Plot(
title=None, x_range=xdr, y_range=ydr, plot_width=300, plot_height=300,
h_symmetry=False, v_symmetry=False, min_border=0,toolbar_location=None)
glyph1 = Step(x="x", y="y1", line_color="#f46d43", mode="before")
plot.add_glyph(source, glyph1)
glyph2 = Step(x="x", y="y2", line_dash="dashed", line_color="#1d91d0", mode="center")
plot.add_glyph(source, glyph2)
glyph3 = Step(x="x", y="y3", line_width=3, line_color="#cab2d6", mode="after")
plot.add_glyph(source, glyph3)
xaxis = LinearAxis()
plot.add_layout(xaxis, 'below')
yaxis = LinearAxis()
plot.add_layout(yaxis, 'left')
plot.add_layout(Grid(dimension=0, ticker=xaxis.ticker))
plot.add_layout(Grid(dimension=1, ticker=yaxis.ticker))
curdoc().add_root(plot)
show(plot)
回答1:
You can add a legend entry for each glyph manually by selecting the corresponding renderer in your plot and then connecting it to a LegendItem
.
Here's the full code using your example:
import numpy as np
from bokeh.models import ColumnDataSource, DataRange1d, Plot, LinearAxis, Grid, Legend, LegendItem
from bokeh.models.glyphs import Step
from bokeh.io import curdoc, show
N = 11
x = np.linspace(-2, 2, N)
y = x**2
source = ColumnDataSource(dict(x=x, y1=y, y2=y+2, y3=y+4))
xdr = DataRange1d()
ydr = DataRange1d()
p1 = Plot(
title=None, x_range=xdr, y_range=ydr, plot_width=300, plot_height=300,
h_symmetry=False, v_symmetry=False, min_border=0, toolbar_location=None)
glyph1 = Step(x="x", y="y1", line_color="#f46d43", mode="before")
p1.add_glyph(source, glyph1)
glyph2 = Step(x="x", y="y2", line_dash="dashed", line_color="#1d91d0", mode="center")
p1.add_glyph(source, glyph2)
glyph3 = Step(x="x", y="y3", line_width=3, line_color="#cab2d6", mode="after")
p1.add_glyph(source, glyph3)
xaxis = LinearAxis()
p1.add_layout(xaxis, 'below')
yaxis = LinearAxis()
p1.add_layout(yaxis, 'left')
p1.add_layout(Grid(dimension=0, ticker=xaxis.ticker))
p1.add_layout(Grid(dimension=1, ticker=yaxis.ticker))
li1 = LegendItem(label='red', renderers=[p1.renderers[0]])
li2 = LegendItem(label='blue', renderers=[p1.renderers[1]])
li3 = LegendItem(label='purple', renderers=[p1.renderers[2]])
legend1 = Legend(items=[li1, li2, li3], location='top_right')
p1.add_layout(legend1)
curdoc().add_root(p1)
show(p1)
This should be the result:
回答2:
Just for completeness, it's worth mentioning that the code you link is demonstrating the very low level bokeh.models
API. If that's what you need, that's perfectly fine. But in case you are simply unaware, most usage can be done more simply with the higher level bokeh.plotting
API:
import numpy as np
from bokeh.io import output_file, show
from bokeh.models import ColumnDataSource
from bokeh.plotting import figure
N = 11
x = np.linspace(-2, 2, N)
y = x**2
source = ColumnDataSource(dict(x=x, y1=y, y2=y+2, y3=y+4))
plot = figure(title=None, plot_width=300, plot_height=300, toolbar_location=None)
plot.step(x="x", y="y1", line_color="#f46d43", mode="before",
source=source, legend="step 1")
plot.step(x="x", y="y2", line_dash="dashed", line_color="#1d91d0", mode="center",
source=source, legend="step 2")
plot.step(x="x", y="y3", line_width=3, line_color="#cab2d6", mode="after",
source=source, legend="step 3")
output_file("plot.html")
show(plot)
This code produces the same image as the answer above.
来源:https://stackoverflow.com/questions/48439142/bokeh-add-legend-to-step-graph