使用Holoviews/HVPlot创建一个绘图网格,并设置最大列数。

7
我想使用holoviews/hvplot,在一个包含多个唯一数据点的维度上,将几个数据绘制成网格。
考虑这个例子:
import seaborn as sns
import hvplot.pandas

iris = sns.load_dataset('iris')
plot = iris.hvplot.scatter(x="sepal_length", y="sepal_width", col="species")
hvplot.show(plot)

上面的代码根据鸢尾花数据集中物种部分创建了几个图表,结果如下图所示:
hvplot gridspace example with too many columns

但现在想象一下,如果不是3个不同的物种,而是20个。图表会变得太宽,因此我想在几个图表后换行。但我找不到任何“最大列数”参数。普通网格需要另一列来定义行,但我没有。

请给出任何建议。
2个回答

3
以上调用返回的HoloViews对象是GridSpace,它使用列标题来表示外部行和列维度上的值。如果您在这种图中断行,则列标题会混合在一起,因此我非常确定这种方法不能直接使用。
尽管如此,您可以从GridSpace中提取单个项并将它们放入HoloViews布局中(该布局允许换行),只要您重新标记每个图以便于识别物种维度上的值即可。
import seaborn as sns, hvplot.pandas, holoviews as hv

iris = sns.load_dataset('iris')
plot = iris.hvplot.scatter(x="sepal_length", y="sepal_width", col="species")
p2   = hv.Layout([i.relabel(n).opts() for n,i in plot.items()]).cols(2)
hvplot.show(p2)

screenshot


感谢James,因为你在某种程度上诱使我远离纯matplotlib,所以非常感谢你在最初的困难时期提供帮助:D。无论如何,你在列表推导式中调用.opts()是否有原因呢?这似乎并不是绝对必要的。 - MichaelA
好问题。如果不加.opts(),图表会太大超出我的屏幕,但我不知道为什么仅添加.opts()会影响它。 - James A. Bednar
无论如何,Sander的解决方案比我的更好;我喜欢hvPlot,但更了解HoloViews,所以即使hvPlot已经处理了它,我仍会退回到HoloViews的解决方案... - James A. Bednar

3
在您的情况下,我不会使用关键字“row”和“col”创建一个Layout,而是使用一个Gridspace。当您拥有一个布局时,可以使用.cols(2)轻松调整列数。
使用hvplot时,您必须使用关键字“by”和“subplots=True”而不是“col”。请参见以下代码:
iris.hvplot.scatter(
    x='sepal_length',
    y='sepal_width',
    by='species',
    subplots=True,
).cols(2)


产生的图形:

创建布局以显示图形


这听起来比实际上要困难得多 - 不管怎样,有没有选项可以使y轴共享。.opts(shared_axes=True) 对我来说似乎不起作用。 - MichaelA
你使用的是 hvplot 和 holoviews 的哪个版本?正如你在我的图片中看到的,我的坐标轴是共享和链接的,因为所有绘图的 y 轴和 x 轴名称都相同。你可以通过以下方式安装最新版本:https://stackoverflow.com/questions/59363729/install-the-latest-git-versions-of-holoviews-hvplot-panel-datashader-and-para - Sander van den Oord
关于难度:这就是hvplot的好处,它会为您完成所有这些操作 :) 因此,您需要使用更少的holoviews和bokeh细节。 - Sander van den Oord
很抱歉,我的问题表述不够准确。我的坐标轴也是共享的,但我想要消除重复的y和x标签。(在我的实际情况中,我的y标签相当长)。原始的col方法已经做到了这一点,但我找不到网格部分的解决方案。 - MichaelA
然后,您需要迭代绘图以从除第一个绘图之外的所有绘图中删除ylabel,这类似于James Bednar的解决方案:all_plots = [];for nr, species in enumerate(iris.species.unique()): plot = iris[iris.species == species].hvplot(kind='scatter', x='sepal_length', y='sepal_width', width=400)
if nr>0: plot.opts(ylabel='')
all_plots.append(plot);hv.Layout(all_plots).cols(2)
- Sander van den Oord

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接