如何在使用IJava内核的Jupyter Notebook中嵌入Tablesaw图表?

4
我希望使用IJava内核在Jupyter Notebook中嵌入Tablesaw交互式图表。我意识到Tablesaw可能无法直接实现这一点,但我愿意花费一些精力来实现它。我是Java专家,但我对Jupyter Notebook和IJava内核都很陌生,所以不知道从哪里开始。是否有一些API可以用于Jupyter Notebook或IJava以嵌入对象?
首先,我安装了Anaconda,然后在Jupyter Notebook中轻松安装了IJava内核。到目前为止,在Windows 10上使用OpenJDK 11没有任何问题!接下来,我尝试使用Tablesaw。我能够添加其Maven依赖项,加载CSV文件并创建一个图表。非常好!
但是,为了生成图表,Tablesaw使用Plotly生成临时HTML文件,并调用浏览器显示交互式图表。换句话说,图表不会出现在Jupyter Notebook中
Tablesaw展示了一个嵌入图表的示例,使用的是BeakerX内核(不是IJava)。正如您可以看到的那样(向下滚动至“Play(Money)ball with Linear Regression”),他们正在Jupyter笔记本中直接嵌入Tablesaw的Plot。因此,我知道在具有Java内核的Jupyter Notebook中概念上嵌入交互式Tablesaw图表是可能的。
这种能力是特定于BeakerX吗?我想切换到BeakerX,但从文档中我没有看到关于BeakerX支持Java 9+的任何内容。此外,IJava似乎是一种更简洁的实现,直接构建在JShell之上。
我应该从哪里开始找出如何像BeakerX一样使用IJava内核,在Jupyter Notebook中将Tablesaw的Plot对象作为交互式图形嵌入?
2个回答

3

IJava内核有两个主要的display_data函数; displayrender。两者都与base kernel中的Renderer相连接。我们可以为tablesaw的Figure类型注册一个渲染函数。

  1. Add the tablesaw-jsplot dependency (and all required transitive dependencies) via the loadFromPOM cell magic:

    %%loadFromPOM
    <dependency>
        <groupId>tech.tablesaw</groupId>
        <artifactId>tablesaw-jsplot</artifactId>
        <version>0.30.4</version>
    </dependency>
    
  2. Register a render function for IJava's renderer.

    1. We create a registration for tech.tablesaw.plotly.components.Figure.
    2. If an output type is not specified during the render then we want it to default to text/html (with the preferring call).
    3. If an html render is requested, we build the target <div> as well as the javascript that invokes a plotly render into that <div>. Most of this logic is done via tablesaw's asJavascript method but hooks into Jupyter notebook's require AMD module setup.

    import io.github.spencerpark.ijava.IJava;
    
    IJava.getKernelInstance().getRenderer()
        .createRegistration(tech.tablesaw.plotly.components.Figure.class)
        .preferring(io.github.spencerpark.jupyter.kernel.display.mime.MIMEType.TEXT_HTML)
        .register((figure, ctx) -> {
            ctx.renderIfRequested(io.github.spencerpark.jupyter.kernel.display.mime.MIMEType.TEXT_HTML, () -> {
                String id = UUID.randomUUID().toString().replace("-", "");
    
                figure.asJavascript(id);
                Map<String, Object> context = figure.getContext();
    
                StringBuilder html = new StringBuilder();
                html.append("<div id=\"").append(id).append("\"></div>\n");
                html.append("<script>require(['https://cdn.plot.ly/plotly-1.44.4.min.js'], Plotly => {\n");
                html.append("var target_").append(id).append(" = document.getElementById('").append(id).append("');\n");
                html.append(context.get("figure")).append('\n');
                html.append(context.get("plotFunction")).append('\n');
                html.append("})</script>\n");
                return html.toString();
            });
        });
    
  3. Then we can create a table to display (taken from the Tablesaw docs).

    import tech.tablesaw.api.*;
    import tech.tablesaw.plotly.api.*;
    import tech.tablesaw.plotly.components.*;
    
    String[] animals = {"bear", "cat", "giraffe"};
    double[] cuteness = {90.1, 84.3, 99.7};
    
    Table cuteAnimals = Table.create("Cute Animals")
        .addColumns(
            StringColumn.create("Animal types", animals),
            DoubleColumn.create("rating", cuteness)
        );
    cuteAnimals
    
  4. Finally we can create a Figure for the table and display it via one of 3 methods for displaying things in IJava.

    VerticalBarPlot.create("Cute animals", cuteAnimals, "Animal types", "rating");
    

    which is equivalent to a render call where the "text/html" is implicit because we set it as the preferred type (preferring during registration)

    render(VerticalBarPlot.create("Cute animals", cuteAnimals, "Animal types", "rating"), "text/html");
    

    and if it is not at the end of a cell, the display function is another option. For example to display the chart and the cuteAnimals afterwards:

    Figure figure = VerticalBarPlot.create("Cute animals", cuteAnimals, "Animal types", "rating");
    display(figure);
    
    cuteAnimals
    

太棒了!感谢你在这方面的所有工作,SpencerPark。这正是我一直在寻找的。 - Garret Wilson

0
尝试使用命令提示符并使用pip install Tablesaw,然后使用其他建议。

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