2015年1月18日日曜日

math/R・rJavaでのPlot画像をJavaのPanelに貼り付ける

rJavaを用いてJavaからRを動かしたPostのRSampleと入れ替えてみる.
(ファイルにPNG画像を書き出して読み込んで描画するを繰り返すので注意)
package rJava;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import org.rosuda.JRI.REXP;
import org.rosuda.JRI.Rengine;
public class RSample extends JPanel implements KeyListener, Runnable {
private final String[] _exprs = {
"a*x+b", "a*x^b", "a*b^x"
};
private final String[] _ltys = {
"dotted", "dashed", "solid"
};
private final int _INDEX_INIT = 7;
private final String _plotArgs = "xlim= xlim, ylim= ylim"
+ ", xlab= 'Xの値', ylab= 'Yの値', family= 'Osaka-Mono'";
private Rengine _engine;
private boolean _loopFlag = true;
private boolean _lockFlag = false;
private Thread _thread;
private File _file;
private int _index = 7;
private int _n = 0;
public RSample() {
setSize(480, 480);
setFocusable(true); // KeyListnerに必要な設定
addKeyListener(this);
_engine = new Rengine(new String[] {
"--no-save"
}, false, null);
init();
_file = paintIMP();
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.RED);
g.fillRect(0, 0, getWidth(), getHeight());
if (_file != null) {
try {
BufferedImage img = ImageIO.read(_file);
g.drawImage(img, 0, 0, this);
} catch (Exception e) {
e.printStackTrace();
_file.delete();
_file = null;
}
}
_lockFlag = false;
}
private void init() {
String filename = "dist.dat";
_engine.eval("data<-read.csv(\"" + filename + "\")");
_engine.eval("d1<-data[,1]");
_engine.eval("d2<-data[,2]");
_engine.eval("n<-length(d1)");
_engine.eval("xlim<-c(0,n-1)");
_engine.eval("ylim<-c(0,30)");
_engine.eval("r<-sample(c(0:n-1), n)");
_n = _engine.eval("n").asInt();
}
private File paintIMP() {
File file = null;
try {
file = File.createTempFile("plot", ".png");
} catch (IOException e) {
return null;
}
file.deleteOnExit();
_engine.eval("rv<-sort(r[0:" + _index + "])");
_engine.eval("x<-d1[rv]");
_engine.eval("y<-d2[rv]");
_engine.eval("png('" + file.getAbsolutePath() + "')");
_engine.eval("plot(x, y, " + _plotArgs + ")");
_engine.eval("grid()");
String exprary = String.format("'sample(n=%d)'", _index);
String ltyary = "'blank'";
String pchary = "1";
for (int i = 0; i < _exprs.length; i++) {
if (curve_fitting(_exprs[i], _ltys[i])) {
exprary += ", expression(" + _exprs[i] + ")";
ltyary += ", '" + _ltys[i] + "'";
pchary += ", -1";
}
}
String legend = "legend('topright'";
legend += ", c(" + exprary + ")";
legend += ", lty=c(" + ltyary + ")";
legend += ", pch=c(" + pchary + ")";
legend += ")";
_engine.eval(legend);
_engine.eval("dev.off()");
return file;
}
private boolean curve_fitting(String f, String c) {
REXP r = _engine.eval("result<-nls(y~(" + f + "), start=c(a=1, b=1))");
if (r == null)
return false;
_engine.eval("p<-result$m$getPars()");
_engine.eval("a= p[1]");
_engine.eval("b= p[2]");
_engine.eval("func= function(x) " + f);
_engine.eval("plot(func, 0, n, add=TRUE, lty='" + c + "')");
return true;
}
private void start() {
_thread = new Thread(this);
_loopFlag = true;
_index = _INDEX_INIT;
_thread.start();
}
@Override
public void run() {
try {
System.out.println("start");
while (_loopFlag) {
_lockFlag = true;
repaint();
do {
Thread.sleep(10);
} while (_lockFlag);
_file = paintIMP();
_index++;
if (_index >= _n || _index >= 400) {
_loopFlag = false;
}
}
System.out.println("end");
} catch (Exception e) {
e.printStackTrace();
_engine.end();
}
}
public static void main(String[] args) {
System.out.println("R_HOME:" + System.getenv("R_HOME"));
System.out.println("java.library.path:"
+ System.getProperty("java.library.path"));
JFrame f = new JFrame();
RSample p = new RSample();
f.getRootPane().add(p);
f.setSize(480, 500);
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
if (p._engine != null && p._engine.isAlive())
p._engine.end();
if (p._thread != null && p._thread.isAlive())
p._loopFlag = false;
System.exit(0);
}
});
f.setVisible(true);
p.repaint(10);
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == 32) {
if (!(_thread != null && _thread.isAlive()))
this.start();
}
}
}
view raw RSample.java hosted with ❤ by GitHub


結果

0 件のコメント: