我想使用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内核(不是IJava)的BeakerX,并且您可以看到(向下滚动到“使用线性回归玩(钱)球”),他们将Tablesaw Plot
直接嵌入Jupyter Notebook中。因此,我知道可以在概念上将交互式Tablesaw图嵌入到具有Java内核的Jupyter Notebook中。
此功能是BeakerX特有的吗?我将切换到BeakerX,但是从文档中我看不到任何有关BeakerX支持Java 9+的信息。另外,IJava似乎是一种更精简的实现,直接在JShell之上构建。
我从哪里开始弄清楚如何使用IJava内核将Tablesaw Plot
对象作为交互式图形嵌入Jupyter Notebook中,以及它们在BeakerX中的工作方式?
最佳答案
IJava内核具有display_data
的2个主要功能; display
和render
。两者都从base kernel挂接到Renderer
中。我们可以在tableaw中为Figure
类型注册一个渲染函数。
loadFromPOM
单元魔术添加了tableaw-jsplot依赖关系(以及所有必需的传递依赖关系):%%loadFromPOM
<dependency>
<groupId>tech.tablesaw</groupId>
<artifactId>tablesaw-jsplot</artifactId>
<version>0.30.4</version>
</dependency>
IJava
的渲染器注册一个渲染函数。tech.tablesaw.plotly.components.Figure
创建一个注册。 text/html
(通过preferring
调用)。 <div>
以及将plotly渲染调用到<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();
});
});
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
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