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

时间:2019-02-12 16:20:21

标签: java graph jupyter-notebook

我想使用Tablesaw内核将IJava交互式图形嵌入Jupyter Notebook。我意识到Tablesaw可能无法立即执行此操作,但是我愿意付出一些努力来实现这一目标。我是Java专家,但是我不熟悉Jupyter Notebook和IJava内核,所以我不确定从哪里开始。是否有一些用于Jupyter Notebook或IJava的API,用于嵌入对象?

首先,我安装了Anaconda,然后在Jupyter Notebook中安装了IJava内核,这没有问题。到目前为止,在Windows 10上使用OpenJDK 11都可以顺利进行!接下来,我尝试使用Tablesaw。我能够添加其Maven依赖项,加载CSV文件并创建图。很好!

然而,生成图形Tablesaw使用Plotly生成一个临时HTML文件,并调用浏览器以显示交互式图形。换句话说,图形不会出现在Jupyter Notebook中。

Tablesaw的example with embedded graphs内核使用的是BeakerX(不是IJava),如您所见(向下滚动到“线性回归玩(钱)球”),他们正在嵌入Tablesaw Plot 直接在Jupyter Notebook中。因此,我知道可以在概念上将交互式Tablesaw图嵌入Java内核的Jupyter Notebook中。

此功能是BeakerX特有的吗?我将切换到BeakerX,但是从文档中我看不到任何有关BeakerX支持Java 9+的信息。另外,IJava似乎是一种更精简的实现,直接在JShell之上构建。

我从哪里开始弄清楚如何使用IJava内核将Tablesaw Plot对象作为交互式图形嵌入Jupyter Notebook中,以及它们在BeakerX中的工作方式?

2 个答案:

答案 0 :(得分:1)

IJava内核具有display_data的2个主要功能; displayrender。两者都从base kernel插入Renderer。我们可以在表格锯中注册Figure类型的渲染函数。

  1. 通过loadFromPOM单元魔术添加tablesaw-jsplot依赖关系(以及所有必需的传递依赖关系):

    %%loadFromPOM
    <dependency>
        <groupId>tech.tablesaw</groupId>
        <artifactId>tablesaw-jsplot</artifactId>
        <version>0.30.4</version>
    </dependency>
    
  2. IJava的渲染器注册渲染功能。

    1. 我们为tech.tablesaw.plotly.components.Figure创建注册。
    2. 如果在渲染过程中未指定输出类型,则我们希望将其默认为text/html(通过preferring调用)。
    3. 如果请求html渲染,我们将构建目标<div>以及在该<div>中调用可绘制渲染的javascript。大部分逻辑是通过tableaw的asJavascript方法完成的,但可以插入Jupyter笔记本电脑的require AMD模块设置中。

    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. 然后我们可以创建一个要显示的表格(取自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. 最后,我们可以为表创建一个Figure并通过3种在IJava中显示内容的方法之一来显示它。

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

    等效于render调用,其中"text/html"是隐式的,因为我们将其设置为首选类型(在注册期间为preferring

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

    ,如果它不在单元格末尾,则display函数是另一个选项。例如,要显示图表和之后的cuteAnimals

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

答案 1 :(得分:0)

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