Commit b744ae05 authored by Rui Vieira's avatar Rui Vieira

Fix BufferedImage on Jupyter. Release 0.0.6.

parent b3aee4d6
[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/ruivieira/java-plotlib/master?filepath=docs%2Fexamples.ipynb)
# java-plotlib
A simple Java wraper for Python's matplotlib.
See the examples [here](docs/examples.ipynb) or run the examples [online](https://mybinder.org/v2/gh/ruivieira/java-plotlib/master?filepath=docs%2Fexamples.ipynb).
\ No newline at end of file
......@@ -7,17 +7,99 @@
"outputs": [],
"source": [
"%%loadFromPOM\n",
"<repository>\n",
" <id>bintray-ruivieira-maven</id>\n",
" <url>https://dl.bintray.com/ruivieira/maven</url>\n",
"</repository>\n",
"<dependency>\n",
" <groupId>org.ruivieira</groupId>\n",
" <artifactId>java-plotlib</artifactId>\n",
" <version>0.0.1</version>\n",
" <version>0.0.6-SNAPSHOT</version>\n",
"</dependency>"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"/var/folders/nz/mwztsdq92fbdtwvw8h8nd4_00000gn/T/tmp2292523076496764867.png\n"
]
},
{
"data": {
"image/png": "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Ahjftp07d2445ZRTQr9+/Yo/FyxYUN7W5J133gkPPvhgePXVV8Pq1avDTTfdVHzvmjVrylsbdu3aVYSle3V1ddU+QACQGwWwIgXwySefDCNHjiz+fPPNN8OPf/zjMHTo0PDoo4+Wt/boiiuuCDfeeGP5cENnZ2fTDSPdq84BAoDcKIAVKYCx/P3whz9sOvaDH/wgjBs3runY4dx+++1h0qRJ5cMNrgACQP4UwIoUwHi1b/HixU3H4lvAY8eObTp2OPFzgNddd1358CEJEADkx/yuSAFsb28P5557buMxMM8880wYNmxYmDNnTmNPR0dHaGtra3y9cOHCsHTp0rBp06awbt26MGvWrNCnT5+wcuXKxp7DESAAyI/5XZECuHPnzqLAtbS0NB4Efeedd4bdu3c39sSS2Nra2vj6nnvuCWPGjCn2xyuIV155ZXjhhRcar/eGAAFAfszvihTAE0WAACA/5rcCmESAACA/5rcCmESAACA/5rcCmESAACA/5rcCmESAACA/5rcCmESAACA/5rcCmESAACA/5rcCmESAACA/5rcCmESAACA/5rcCmESAACA/5rcCmESAACA/5rcCmESAACA/5rcCmESAACA/5rcCmESAACA/5rcCmESAACA/5rcCmESAACA/5rcCmESAACA/5rcCmESAACA/5rcCmESAACA/5rcCmESAACA/5rcCmESAACA/5rcCmESAACA/5rcCmESAACA/5rcCmESAACA/5rcCmESAACA/5rcCmESAACA/5rcCmESAACA/5rcCmESAACA/5rcCmESAACA/5rcCmESAACA/5rcCmESAACA/5rcCmESAACA/5ndFCuCePXvCvHnzwvnnnx8GDRoURo8eHb7//e+Hffv2lbc2WbVqVbjkkkvCgAEDwpgxY8KSJUvKW3okQACQH/O7IgVw/vz54YwzzgjPPvts2Lp1a/jpT38aTj311HD//feXtzZs2bIlDB48ONx2221h/fr14YEHHgh9+/YNy5cvL289JAECgPyY3xUpgFOmTAk333xz07Gvfe1rYebMmU3H9jdnzpwwfvz4pmPTp08PV199ddOxnggQAOTH/K5IAYxXAEeNGhU2btxYfP3666+H4cOHh8cff7y0808uv/zyMGvWrKZjjzzySBgyZEjTsZ4IEADkx/yuSAHcu3dvmDt3bjjllFNCv379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AUwiQACQH/NbAUzy8ccfFwHq6uoqQmRZlmVZ1sm/4tyO8zvO8bpSABN0B8iyLMuyrPxWnON1pQAm2Lt3bxGe+BtE+beL1NVdLl1dPPxyrnq/nKveL+eq98u56v1yrnq/jue5inM7/u/GOV5XCuBJKgY0Bj/+Sc+cq95zrnrPueo956r3nKvec66OLwXwJCX4vedc9Z5z1XvOVe85V73nXPWec3V8KYAnKcHvPeeq95yr3nOues+56j3nqvecq+NLATxJ7dq1K3R2dhZ/0jPnqvecq95zrnrPueo956r3nKvjSwEEAKgZBRAAoGYUQACAmlEAAQBqRgEEAKgZBfAE+eUvfxmmTp0azj777OI29//8z/8sbznAqlWrwiWXXBIGDBgQxowZE5YsWVLeUklHeq7ieYr7ymvbtm3lrZWyYMGCcOmll4ZTTz01nHnmmeEf/uEfwjvvvFPedoCnn346jBs3LgwcODBMmDAhLFu2rLylco7mXMV/38qZiues6hYvXhz++q//OvzlX/5lsSZNmhSee+658rYmdcxUdKTnqq6ZKvu3f/u34v/7rFmzyi81qWuujhcF8ASJfynceeed4ZlnnulVqdmyZUsYPHhwuO2228L69evDAw88EPr27RuWL19e3lo5R3quugvgxo0bi9LXvar+n/y5+uqri4Hy1ltvhddffz1cc801oaWlJfzhD38ob21YvXp1kaN77723yNW8efNC//79w7p168pbK+VozlXcP2TIkKZMffjhh+VtlfNf//VfxaD97//+7+LfqX/9138tMhLP3cHUNVPRkZ6rumZqf6+88ko4//zzw0UXXdRjAaxzro4XBfAk0JtSM2fOnDB+/PimY9OnTy8GWZ305lx1F8AdO3aUX6qV7du3F+chXkE9lOuvvz5MmTKl6dhll10WbrnllqZjVdebcxWH9WmnnVY+XEunn356ePjhh8uHCzLVrKdzVfdMffLJJ2Hs2LHh+eefD62trT0WQLk69hTAk0BvSs3ll19+wL8cjzzySPHbY5305lx1F8BRo0aFESNGhKuuuiq89NJL5W2Vt2nTpuI89PQb8nnnnRcWLlzYdOyuu+4qfhuvk96cqzis4xWIeKVw5MiR4dprrz3klZ2q2rNnT3jyySeLj6G8/fbb5ZcLMvW53pyrumfqH//xH8Ps2bOLfz5cAZSrY08BPAn0ptTE35Li55b2F99qiN/76aefNh2vst6cq/hZrgcffDC8+uqrxdsGN910U+jXr19Ys2ZNeWtlxbe742/LX/7yl8svNYlvoTzxxBNNxxYtWhSGDx/edKzKenuuXn755fDYY4+F1157Lbz44ovF51LjL2BdXV3lrZXz5ptvhr/4i78oykq8YtXTZ6/qnqkjOVd1zlQsx/FzfP/3f/9XfH24Alj3XB0PCuBJoDelRgH8XG/O1cFcccUV4cYbbywfrqx//ud/Lq6AHm6Q+Eu19+eq7LPPPituxoqfRaq63bt3F1dJ4y9VHR0dYdiwYYe8qlX3TB3JuSqrS6b+53/+p8jDG2+80TimAP75KYAngd6UGm8Bf6435+pgbr/99uKOvDr49re/XbydFG8cOpy6v61yJOfqYKZNmxZuuOGG8uHK+/u///vwT//0T+XDhbpnqqync3UwdchU/Ds8/l0er5J2r/j1KaecUvxzfPu8TK6OPQXwJNCbUhNvAomXy/c3Y8YMN4H0Uvwc4HXXXVc+XCn79u0rCs0555xT3IXYG/GD1fFtp/1Nnjy58h+sPppzVRaHVHwkxa233lp+qfL+7u/+LrS3t5cPF+qaqUPp6VyV1SVTO3fuLD5vu/+Kj2WK79Ic6nO4cnXsKYAnSLz7KX7uI65Yav793/+9+Of33nuveD2+ddDW1tbY3/0YmDvuuCNs2LChuPRdl8fAHOm5ir8lLl26tHgbJv5lEq+c9unTJ6xcubKxp4r+5V/+pfjMUfws0f6Pldj/IwLxPMXz1S1+RjJ+PvK+++4rctXZ2VmLRysczbm6++67w4oVK8K7775bfJ40XqUZNGhQr9/ey1U8B/Hu6K1btxafb4tfxys1v/jFL4rXy+eprpmKjvRc1TVTB1N+C7h8ruqcq+NFATxBDvWw4u7fFOOf8V+I8vdMnDixuKts9OjRxR1kdXCk5+qee+4pPkcT/yIdOnRouPLKK8MLL7zQeL2qyuene+2fk3ieylcj4sNVL7jggiJX8VFDPX1ovSrK56g35yrerRjv1ozn6ayzziqeHbh27drG61V18803F5+RjP+/40Oz41ua3YUmKp+nqI6Zio70XNU1UwdTLoDlcxXVNVfHiwIIAFAzCiAAQM0ogAAANaMAAgDUjAIIAFAzCiAAQM0ogAAANaMAAgDUjAIIAFAzCiAAQM0ogAAANaMAAgDUjAIIAFAzCiAAQM0ogAAANaMAAgDUjAIIAFAzCiAAQM0ogAAANaMAAgDUjAIIAFAzCiAAQM0ogAAANaMAAgDUjAIIAFAzCiAAQM0ogAAANaMAAgDUjAIIAFAzCiAAQM0ogAAANaMAAgDUzP8DJ7ZeushEOf8AAAAASUVORK5C",
"text/plain": [
"BufferedImage@cf405b1: type = 6 ColorModel: #pixelBits = 32 numComponents = 4 color space = java.awt.color.ICC_ColorSpace@44ef666e transparency = 3 has alpha = true isAlphaPre = false ByteInterleavedRaster: width = 640 height = 480 #numDataElements 4 dataOff[0] = 3"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import org.ruivieira.plotlib.Figure;\n",
"import org.ruivieira.plotlib.plots.ScatterPlot;\n",
"import java.util.Arrays;\n",
"import java.awt.image.BufferedImage;\n",
"\n",
"\n",
"Figure figure = new Figure();\n",
"\n",
"Integer[] x = new Integer[]{1, 2, 3, 4};\n",
"Integer[] y = new Integer[]{7, 9, 5, 6};\n",
"\n",
"figure.add(new ScatterPlot<>(Arrays.asList(x), Arrays.asList(y)));\n",
"\n",
"figure.getBufferedImage();"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Figures can be composed of several plots. Here we add a line plot to connect the points."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"/var/folders/nz/mwztsdq92fbdtwvw8h8nd4_00000gn/T/tmp2597448373670459148.png\n"
]
},
{
"data": {
"image/png": "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",
"text/plain": [
"BufferedImage@7be1e20b: type = 6 ColorModel: #pixelBits = 32 numComponents = 4 color space = java.awt.color.ICC_ColorSpace@44ef666e transparency = 3 has alpha = true isAlphaPre = false ByteInterleavedRaster: width = 640 height = 480 #numDataElements 4 dataOff[0] = 3"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import org.ruivieira.plotlib.plots.LinePlot;\n",
"\n",
"Figure figure = new Figure();\n",
"\n",
"Integer[] x = new Integer[]{1, 2, 3, 4};\n",
"Integer[] y = new Integer[]{7, 9, 5, 6};\n",
"\n",
"figure.add(new ScatterPlot<>(Arrays.asList(x), Arrays.asList(y)));\n",
"figure.add(new LinePlot<>(Arrays.asList(x), Arrays.asList(y)));\n",
"\n",
"figure.getBufferedImage();"
]
},
{
"cell_type": "code",
"execution_count": null,
......@@ -38,7 +120,7 @@
"mimetype": "text/x-java-source",
"name": "Java",
"pygments_lexer": "java",
"version": "10.0.1+10-Debian-4"
"version": "11.0.2+9"
}
},
"nbformat": 4,
......
......@@ -6,7 +6,7 @@
<groupId>org.ruivieira</groupId>
<artifactId>java-plotlib</artifactId>
<version>0.0.5</version>
<version>0.0.6</version>
<build>
<plugins>
......
......@@ -6,8 +6,8 @@ import java.util.Optional;
public abstract class AbstractPlot<T, U> implements Plot {
protected final List<String> xs;
protected final List<String> ys;
protected final Converter<T> xs;
protected final Converter<U> ys;
protected Optional<String> colour = Optional.empty();
......@@ -17,8 +17,8 @@ public abstract class AbstractPlot<T, U> implements Plot {
protected final StringBuilder script = new StringBuilder();
public AbstractPlot(Collection<T> x, Collection<U> y) {
this.xs = new Converter<>(x).getConverted();
this.ys = new Converter<>(y).getConverted();
this.xs = new Converter<>(x);
this.ys = new Converter<>(y);
}
......
package org.ruivieira.plotlib;
public class Arguments {
public static String build(String key, String value) {
final StringBuilder builder = new StringBuilder();
builder.append(key).append("=").append("'").append(value).append("'");
return builder.toString();
}
}
package org.ruivieira.plotlib;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
......@@ -15,7 +16,12 @@ public class Converter<T> {
public Converter(Collection<T> data) {
this.converted = data.stream().map(String::valueOf).collect(Collectors.toList());
}
public String getConvertedList() {
final StringBuilder builder = new StringBuilder();
builder.append("[").append(String.join(",", getConverted())).append("]");
return builder.toString();
}
}
......@@ -2,8 +2,7 @@ package org.ruivieira.plotlib;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.*;
import java.nio.charset.Charset;
import java.util.Optional;
......@@ -37,25 +36,25 @@ public class Figure {
try {
File tempFile = File.createTempFile("java-plotlib-", ".py");
title.ifPresent(s -> script.append("plt.title('").append(s).append("')\n"));
script.append("\n").append("plt.savefig('").append(imageName).append("')");
script.append("\n").append("plt.savefig('").append(imageName).append("', format='png', transparent=False)");
writeStringToFile(tempFile, script.toString(), Charset.defaultCharset());
runtime.exec(python + " " + tempFile.getAbsolutePath());
Process p = runtime.exec(python + " " + tempFile.getAbsolutePath());
p.waitFor();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public BufferedImage getBufferedImage() {
BufferedImage img = null;
try {
File tempFile = File.createTempFile("java-plotlib-", ".png");
public BufferedImage getBufferedImage() throws IOException {
File tempFile = File.createTempFile("tmp", ".png");
save(tempFile.getAbsolutePath());
img = ImageIO.read(new File(tempFile.getAbsolutePath()));
} catch (IOException e) {
e.printStackTrace();
}
return img;
File savedImage = new File(tempFile.getAbsolutePath());
FileInputStream fis = new FileInputStream(savedImage);
System.out.println(savedImage);
return ImageIO.read(fis);
}
public String getPython() {
......
......@@ -2,12 +2,14 @@ package org.ruivieira.plotlib;
import org.ruivieira.plotlib.plots.ScatterPlot;
import javax.imageio.ImageIO;
import java.io.IOException;
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
public static void main(String[] args) throws IOException {
Figure figure = new Figure();
......@@ -16,7 +18,11 @@ public class Test {
figure.add(new ScatterPlot<>(Arrays.asList(x), Arrays.asList(y)));
figure.getBufferedImage();
System.out.println(figure.getBufferedImage());
String[] readers = ImageIO.getReaderFormatNames();
for (String reader : readers)
System.out.println("reader: " + reader);
}
}
package org.ruivieira.plotlib.plots;
import org.ruivieira.plotlib.AbstractPlot;
import org.ruivieira.plotlib.Arguments;
import org.ruivieira.plotlib.Plot;
import java.util.Collection;
......@@ -26,9 +27,13 @@ public class InterpolationPlot<T, U> extends AbstractPlot<T, U> implements Plot
public String render() {
script.append("from scipy.interpolate import interp1d\n");
script.append("import numpy as np\n");
script.append("_z = interp1d([").append(String.join(",", xs)).append("]");
script.append(", [").append(String.join(",", ys)).append("], kind='cubic')\n");
script.append("_x = np.linspace(").append(xs.get(0)).append(", ").append(xs.get(xs.size()-1)).append(", num=").append(this.steps).append(", endpoint=True)\n");
script.append(String.format("_z = interp1d(%s, %s, %s)\n",
xs.getConvertedList(),
ys.getConvertedList(),
Arguments.build("kind", "cubic")));
script.append("_x = np.linspace(").append(xs.getConverted().get(0)).append(", ").append(xs.getConverted().get(xs.getConverted().size()-1)).append(", num=").append(this.steps).append(", endpoint=True)\n");
script.append("plt.plot(_x, _z(_x)");
renderColour();
......
package org.ruivieira.plotlib.plots;
import org.ruivieira.plotlib.AbstractPlot;
import org.ruivieira.plotlib.Arguments;
import org.ruivieira.plotlib.Plot;
import java.util.Collection;
......@@ -27,12 +28,13 @@ public class LinePlot<T, U> extends AbstractPlot<T, U> implements Plot {
@Override
public String render() {
script.append("plt.scatter([").append(String.join(",", xs));
script.append("], [");
script.append(String.join(",", ys));
script.append("]");
marker.ifPresent(s -> script.append(", marker='").append(s).append("'"));
linestyle.ifPresent(s -> script.append(", linestyle='").append(s).append("'"));
script.append("plt.plot(")
.append(xs.getConvertedList())
.append(",")
.append(ys.getConvertedList());
marker.ifPresent(s -> script.append(", ").append(Arguments.build("marker", s)));
linestyle.ifPresent(s -> script.append(", ").append(Arguments.build("linestyle", s)));
renderColour();
renderAlpha();
......
......@@ -30,10 +30,10 @@ public class ScatterPlot<T, U> extends AbstractPlot<T, U> implements Plot {
@Override
public String render() {
script.append("plt.scatter([").append(String.join(",", xs));
script.append("], [");
script.append(String.join(",", ys));
script.append("]");
script.append("plt.scatter(").append(xs.getConvertedList())
.append(",")
.append(ys.getConvertedList());
marker.ifPresent(s -> script.append(", marker='").append(s).append("'"));
markerSize.ifPresent(s -> script.append(", s=").append(s));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment