我相信你们中的许多人都经历过,当您尝试使用 Java 或 Scala 进行机器学习时,没有像 Python 的 Matplotlib 那样很酷的绘图工具。你想知道你是否可以用 Java 绘制 Matplotlib 图表..?

Matplotlib4j是一个为您提供强大功能的库!

GitHub 徽标sh0nk/matplotlib4j

Matplotlib for java:一个用于java、scala和kotlin的简单图形库,带有强大的python matplotlib

  • 使用方法

  • 绘制图形

*散点图

*等高线图

*直方图

  • 将图像保存到文件

  • 使用 pyenv、pyenv-virtualenv 切换 Python

  • 斯卡拉

  • 额外

使用方法

添加库

从这里我将介绍 Java 示例。当然,也可以从 Scala 和 Kotlin 等其他 JVM 语言中使用。稍后将描述这些示例。

首先,将 Matplotlib4j 添加到要使用 Matplotlib 的 Java 项目中。

对于 Maven,添加以下依赖项。

<dependency>
    <groupId>com.github.sh0nk</groupId>
    <artifactId>matplotlib4j</artifactId>
    <version>0.5.0</version>
</dependency>

进入全屏模式 退出全屏模式

同样,对于 Gradle:

compile 'com.github.sh0nk:matplotlib4j:0.5.0'

进入全屏模式 退出全屏模式

就这样。让我们开始画画吧!

绘制图形

用法与 Matplotlib 的 API 类似,所以我们可以直观地编写。首先创建一个Plot对象,在其上调用pyplot方法添加任意图,最后调用show()方法;由于它是一个 Builder 模式,我们将使用 IDE 完成在其后面添加选项。

散点图

作为起点,让我们绘制一个散点图。

List<Double> x = NumpyUtils.linspace(-3, 3, 100);
List<Double> y = x.stream().map(xi -> Math.sin(xi) + Math.random()).collect(Collectors.toList());

Plot plt = Plot.create();
plt.plot().add(x, y, "o").label("sin");
plt.legend().loc("upper right");
plt.title("scatter");
plt.show();

进入全屏模式 退出全屏模式

使用上面的 Java 代码,我们可以绘制如下图。

[scatter.png](https://res.cloudinary.com/practicaldev/image/fetch/s--pkA3E6z2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://qiita-image -store.s3.amazonaws.com/0/29632/f961339a-c074-6d25-ba70-73763dc5a3fe.png)

一些 Numpy 方法,例如linspacemeshgrid,已准备为NumpyUtils类以帮助绘制图形。第一个块生成用于绘图的 x 和 y 数据。这里我们给 sin 曲线一个随机值。之后,我们创建一个绘图对象,将生成的 x 和 y 数据添加到plot()方法中,最后调用show()来绘制图形。

这几乎等同于下面的 Python 实现(几乎,因为 numpy 的数据生成部分是严格不同的)。方法调用类似,如果您是 Pythonista,则可以轻松使用。

import matplotlib.pyplot as plt
import numpy as np

x = np.linspace(-3, 3, 100)
y = np.sin(x) + np.random.rand(100)

plt.plot(x, y, "o", label="sin")
plt.legend(loc="upper right")
plt.title("scatter")
plt.show()

进入全屏模式 退出全屏模式

等高线图

接下来,让我们绘制等高线图(等高线)。

List<Double> x = NumpyUtils.linspace(-1, 1, 100);
List<Double> y = NumpyUtils.linspace(-1, 1, 100);
NumpyUtils.Grid<Double> grid = NumpyUtils.meshgrid(x, y);

List<List<Double>> zCalced = grid.calcZ((xi, yj) -> Math.sqrt(xi * xi + yj * yj));

Plot plt = Plot.create();
ContourBuilder contour = plt.contour().add(x, y, zCalced);
plt.clabel(contour)
    .inline(true)
    .fontsize(10);
plt.title("contour");
plt.show();

进入全屏模式 退出全屏模式

[contour.png](https://res.cloudinary.com/practicaldev/image/fetch/s--XCQaJMsH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://qiita-image -store.s3.amazonaws.com/0/29632/6a445c15-fa6c-51c9-5604-1e954df6b1db.png)

直方图

可以用相同的方式绘制直方图。

Random rand = new Random();
List<Double> x1 = IntStream.range(0, 1000).mapToObj(i -> rand.nextGaussian())
        .collect(Collectors.toList());
List<Double> x2 = IntStream.range(0, 1000).mapToObj(i -> 4.0 + rand.nextGaussian())
        .collect(Collectors.toList());

Plot plt = Plot.create();
plt.hist()
    .add(x1).add(x2)
    .bins(20)
    .stacked(true)
    .color("#66DD66", "#6688FF");
plt.xlim(-6, 10);
plt.title("histogram");
plt.show();

进入全屏模式 退出全屏模式

[histogram.png](https://res.cloudinary.com/practicaldev/image/fetch/s--2zx9pWzt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://qiita-image -store.s3.amazonaws.com/0/29632/9fae2fb5-4f5a-36e6-545d-8117342262ea.png)

将图像保存到文件

Matplotlib4j 还支持保存到文件。将图像保存到文件对于没有 GUI 的用例会很方便,例如在服务器上对机器学习进行批处理。

与原始 Matplotlib 类似,通过使用.savefig()方法而不是.show()方法,将图像保存到文件中而不会弹出绘图窗口。唯一的区别是需要在.savefig()之后调用plt.executeSilently(),这是一个终止过程所必需的,因为 savefig 命令也可以是方法链的一部分。

Random rand = new Random();
List<Double> x = IntStream.range(0, 1000).mapToObj(i -> rand.nextGaussian())
        .collect(Collectors.toList());

Plot plt = Plot.create();
plt.hist().add(x).orientation(HistBuilder.Orientation.horizontal);
plt.ylim(-5, 5);
plt.title("histogram");
plt.savefig("/tmp/histogram.png").dpi(200);

// Necessary to output the file
plt.executeSilently();

进入全屏模式 退出全屏模式

这将输出如下图所示的图像。

[histogram.png](https://res.cloudinary.com/practicaldev/image/fetch/s--0ZN6p3VO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://qiita-image -store.s3.amazonaws.com/0/29632/f6c824dd-6f0f-e709-9f13-5b223b63b02b.png)

使用 pyenv、pyenv-virtualenv 切换 Python

要使用 Matplotlib4j,需要在 Python 环境下安装 Matplotlib;默认情况下,Matplotlib4j 将使用您环境路径中的 Python,但在许多情况下,您可能没有在系统默认 Python 中安装 Matplotlib。

在这种情况下,您可以使用 pyenv 或 pyenv-virtualenv 切换到安装了 Matplotlib 的 Python 环境,例如 Anaconda。

要根据Pyenv环境使用Python,在创建Plot对象时指定PythonConfig如下。

Plot plot = Plot.create(PythonConfig.pyenvConfig("Arbitrary pyenv name"));

进入全屏模式 退出全屏模式

同样,您可以指定 pyenv-virtualenv 的环境名称。

Plot plot = Plot.create(PythonConfig.pyenvVirtualenvConfig("Arbitrary pyenv name", "Arbitrary virtualenv name"));

进入全屏模式 退出全屏模式

斯卡拉

从 Scala 中使用时,上述散点图示例可以写成如下,只需注意 Boxing/Unboxing numbers 和 List 类的区别。

import scala.collection.JavaConverters._

val x = NumpyUtils.linspace(-3, 3, 100).asScala.toList
val y = x.map(xi => Math.sin(xi) + Math.random()).map(Double.box)

val plt = Plot.create()
plt.plot().add(x.asJava, y.asJava, "o")
plt.title("scatter")
plt.show()

进入全屏模式 退出全屏模式

需要更多详细信息?

Tutorial页面中,您可以逐步找到更多 Java、Scala 和 Kotlin 的案例。

额外

一切是如何开始的

我最近开始阅读一本深度学习的书,并决定尝试在我最近经常接触的 Scala 中实现它,因为用 Python 复制书中的代码并不有趣。我很高兴能够在 Scala 中以函数式的方式编写它,但是当我使用最速下降法进行反向传播时,我遇到了损失根本没有下降的情况,我想,“怎么了? "

当然,解决这个问题的常见做法是加厚测试,但我想通过显示书中的图表来快速了解发生了什么。但是发现 Scala 中没有好的绘图工具......但是,从头开始在 Scala 中实现绘图工具太难了......所以我决定使用熟悉的 Python 库 Matplotlib 作为创建图书馆。

设计

Matplotlib4j 以一种无需使用 JNI 或 Jython 即可生成 Python 代码的方式调用 Matplotlib。最初,我想使用Jython来实现它,但它只支持最高 2.7 的 Python 版本,并且由于不支持 numpy,依赖它的 Matplotlib 也不起作用,所以我决定放弃这个小路。

世界上有个库允许您从 Java 代码中使用 CPython,而这个库是候选者,因为我们可以同时使用 Python3 和 numpy。但是,我们必须安装一个单独的依赖于环境的库才能使用 JNI,而且我们还必须在 Python 端从 pip 安装该库,这对于像绘制图形这样简单的事情来说工作量太大了。所以最后我决定完全独立于这些库来实现它。

当然,由于它是通过文件执行的,所以我必须在如何传递变量和使用返回值方面做一些技巧。幸运的是,由于目的只是绘制图形,基本功能可以通过单向输出到文件来满足,我认为性能在可以接受的范围内,但有一些延迟。

GitHub 徽标sh0nk/matplotlib4j

Matplotlib for java:一个用于java、scala和kotlin的简单图形库,具有强大的python matplotlib

matplotlib4j

Maven 中心[构建状态](https://travis-ci. org/sh0nk/matplotlib4j)许可证:麻省理工学院

一个最简单的接口库,使您的 java 项目能够使用 matplotlib。

当然,它可以导入到 scala 项目中,如下所示。 API 的设计类似于原始的 matplotlib。

教程

现在教程正在准备演练功能如果您只想略过 Matplotlib4j 的概念,请跳过该部分并转到下一部分:如何使用

如何使用

这是一个例子。在MainTest.java上查找更多示例

绘图 plt \u003d Plot.create();

plt.plot()

.add(Arrays.asList(1.3, 2))

.label("标签")

.linestyle("--");

plt.xlabel("xlabel");

plt.ylabel("ylabel");

plt.text(0.5, 0.2, "文本");

plt.title("标题!");

plt.legend();

plt.show();

进入全屏模式 退出全屏模式

绘制轮廓的另一个示例。

...

在 GitHub 上查看

Logo

华为、百度、京东云现已入驻,来创建你的专属开发者社区吧!

更多推荐