如何在holoviews + bokeh中获得带有图例标签的全高垂直线?

时间:2019-03-07 18:28:59

标签: python bokeh holoviews

我想用holoviews后端在bokeh中绘制一条垂直线,该后端的标签在我的图例中显示。无论这条线是单独放置还是覆盖其他元素,我都需要将此线作为绘图的整个高度。我该如何实现?

示例

我在示例中添加了曲线图,因为否则,即使是可以出现在图例中的元素,也都使用其标签作为标题。

import numpy as np
import holoviews as hv
hv.extension("bokeh")

x = np.linspace(0, 1)
curve = hv.Curve((x, np.sin(x)), label="sin(x)")
vline = hv.VLine(0.5, label="vline")
curve * vline

这给出了下面的图:

enter image description here

,其中没有垂直线标签。如何显示标签?

1 个答案:

答案 0 :(得分:2)

this issue中所述,但文档中尚未提及,VLineHLine不会出现在图例中,也没有计划增加对它们的支持(基本上,在bokeh的创建方式有所不同,因此没有简单的方法将它们放入图例中。可以改用Spikes。但是,如another issue中所述,峰值不能很好地重叠。特别是,如果没有给出明确的高度,他们不会将其高度调整为情节的整个高度。这是我提出的两种解决方法。

解决方法1

您可以显式找出垂直线应与之重叠的另一个元素的高度,并使用它来创建适当高度的尖峰。这行得通,但它相当脆弱,因为您需要在充分了解可能被峰值覆盖的所有方面进行调整。

import numpy as np
import holoviews as hv
hv.extension("bokeh")

x = np.linspace(0, 1)
curve = hv.Curve((x, np.sin(x)), label="sin(x)")
height = curve.data["y"].max() - curve.data["y"].min()
spikes = hv.Spikes(([0.5], [height]), vdims="height", label="mid")
spikes * curve

image

解决方法2

这同时使用VLineSpikes。尖峰将不可见,除非它将为图例添加一个条目。 vline将位于尖峰的顶部,并且vline已经进行了自我调整以填充图形的整个高度。这需要创建一个额外的元素,但是它更加健壮,因为您可以将此峰值和vline的乘积与其他任何元素重叠,并且仍然获得一条填充图高度并显示在图例中的线。但是,由于图例条目基于尖峰,因此只有确保它们具有相似的外观(例如,vline和尖峰具有相同的颜色),它才会看起来像vline。

# need to make sure the colors are the same for spikes/vlines
# would look a bit better if I adjusted the spike thickness too
spikes = hv.Spikes([0.5], label="mid").opts(color="black")
vline = hv.VLine(0.5).opts(color="black")

spikes * curve * vline

image

将来,Spikes会在未明确指定高度的情况下将自身缩放为全高,这样就不需要这些替代方法了。