001 /* 002 * Copyright (C) 2008-2010 by Holger Arndt 003 * 004 * This file is part of the Universal Java Matrix Package (UJMP). 005 * See the NOTICE file distributed with this work for additional 006 * information regarding copyright ownership and licensing. 007 * 008 * UJMP is free software; you can redistribute it and/or modify 009 * it under the terms of the GNU Lesser General Public License as 010 * published by the Free Software Foundation; either version 2 011 * of the License, or (at your option) any later version. 012 * 013 * UJMP is distributed in the hope that it will be useful, 014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 016 * GNU Lesser General Public License for more details. 017 * 018 * You should have received a copy of the GNU Lesser General Public 019 * License along with UJMP; if not, write to the 020 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, 021 * Boston, MA 02110-1301 USA 022 */ 023 024 package org.ujmp.core.util; 025 026 import java.io.BufferedReader; 027 import java.io.BufferedWriter; 028 import java.io.File; 029 import java.io.InputStreamReader; 030 import java.io.OutputStreamWriter; 031 032 import org.ujmp.core.Matrix; 033 import org.ujmp.core.enums.FileFormat; 034 035 public class GnuPlot { 036 037 public static String[] SEARCH = new String[] {}; 038 039 static { 040 try { 041 SEARCH = new String[] { System.getProperty("GnuPlot"), 042 System.getProperty("user.home") + "/gnuplot/bin/gnuplot", "/usr/bin/gnuplot" }; 043 } catch (Exception e) { 044 } 045 } 046 047 private static String pathToGnuPlot = null; 048 049 private BufferedReader input = null; 050 051 private BufferedWriter output = null; 052 053 private BufferedReader error = null; 054 055 private Process gnuPlotProcess = null; 056 057 private boolean running = false; 058 059 private static GnuPlot gnuPlot = null; 060 061 private static File matrixFile = null; 062 063 public static GnuPlot getInstance() throws Exception { 064 if (gnuPlot == null) { 065 gnuPlot = getInstance(findGnuPlot()); 066 } 067 return gnuPlot; 068 } 069 070 private static String findGnuPlot() { 071 if (pathToGnuPlot == null) { 072 File file = null; 073 for (String s : SEARCH) { 074 if (s != null) { 075 file = new File(s); 076 if (file.exists()) { 077 pathToGnuPlot = file.getAbsolutePath(); 078 return pathToGnuPlot; 079 } 080 } 081 } 082 } 083 return pathToGnuPlot; 084 } 085 086 public static synchronized GnuPlot getInstance(String pathToGnuPlot) throws Exception { 087 if (gnuPlot == null) { 088 gnuPlot = new GnuPlot(pathToGnuPlot); 089 } 090 return gnuPlot; 091 } 092 093 private GnuPlot(String pathToGnuPlot) throws Exception { 094 matrixFile = new File(System.getProperty("java.io.tmpdir") + File.separator + "gnuplot.csv"); 095 matrixFile.deleteOnExit(); 096 gnuPlotProcess = Runtime.getRuntime().exec(pathToGnuPlot); 097 output = new BufferedWriter(new OutputStreamWriter(gnuPlotProcess.getOutputStream())); 098 input = new BufferedReader(new InputStreamReader(gnuPlotProcess.getInputStream())); 099 error = new BufferedReader(new InputStreamReader(gnuPlotProcess.getErrorStream())); 100 // String startMessage = getFromGnuPlot(); 101 // if (startMessage != null && startMessage.length() > 0) { 102 running = true; 103 return; 104 // } 105 // throw new Exception("could not start GnuPlot"); 106 } 107 108 private synchronized String getFromGnuPlot() throws Exception { 109 boolean endSeen = false; 110 StringBuilder sb = new StringBuilder(); 111 112 while (true) { 113 while (!input.ready()) { 114 Thread.yield(); 115 } 116 while (input.ready()) { 117 118 char c = (char) input.read(); 119 sb.append(c); 120 121 if (c == '>') { 122 if (endSeen) { 123 return sb.substring(0, sb.length() - 2); 124 } 125 endSeen = true; 126 } else { 127 endSeen = false; 128 } 129 } 130 } 131 } 132 133 public void execute(String command) throws Exception { 134 sendToGnuPlot(command); 135 // return getFromGnuPlot(); 136 } 137 138 public synchronized void shutdown() throws Exception { 139 sendToGnuPlot("exit"); 140 gnuPlotProcess.waitFor(); 141 output.close(); 142 input.close(); 143 } 144 145 private synchronized void sendToGnuPlot(String command) throws Exception { 146 if (!command.endsWith("\n")) { 147 command = command + "\n"; 148 } 149 output.write(command, 0, command.length()); 150 output.flush(); 151 } 152 153 public void setMatrix(String label, Matrix matrix) throws Exception { 154 execute(label + "=" + matrix.exportToString(FileFormat.M)); 155 } 156 157 public static boolean isAvailable() { 158 return findGnuPlot() != null; 159 } 160 161 public void plot(Matrix matrix, String... format) throws Exception { 162 matrix.exportToFile(FileFormat.CSV, matrixFile); 163 execute(getPlotCommand(matrix, true, true)); 164 } 165 166 public static String getPlotCommand(Matrix matrix, boolean withlines, boolean withpoints) { 167 String command = ""; 168 command += "set autoscale; "; 169 command += "unset log; "; 170 command += "unset label; "; 171 command += "set xtic auto; "; 172 command += "set ytic auto; "; 173 command += "set xlabel 'Column 0'; "; 174 command += "plot"; 175 for (int c = 1; c < matrix.getColumnCount(); c++) { 176 command += " \"" + matrixFile + "\" using 1:" + (c + 1) + " title 'Column " + c + "' "; 177 178 if (withlines && !withpoints) { 179 command += " with lines "; 180 } else if (withlines && withpoints) { 181 command += " with linespoints "; 182 } 183 184 if (c < matrix.getColumnCount() - 1) { 185 command += ","; 186 } 187 } 188 return command; 189 } 190 191 public void scatterPlot(Matrix matrix, String... format) throws Exception { 192 matrix.exportToFile(FileFormat.CSV, matrixFile); 193 execute(getPlotCommand(matrix, false, false)); 194 } 195 196 public static String toString(String[] strings) { 197 if (strings.length != 0) { 198 return ",'" + strings[0] + "'"; 199 } else { 200 return ""; 201 } 202 } 203 204 public void exportToPS(File file, Object... parameters) throws Exception { 205 String command = ""; 206 command += "set terminal postscript landscape;"; 207 command += "set output \"" + file + "\";"; 208 command += "replot;"; 209 if ("Linux".equals(System.getProperty("os.name"))) { 210 command += "set terminal x11;"; 211 } else { 212 command += "set terminal windows;"; 213 } 214 execute(command); 215 } 216 217 public void exportToPNG(File file, Object... parameters) throws Exception { 218 String command = ""; 219 command += "set terminal png;"; 220 command += "set output \"" + file + "\";"; 221 command += "replot;"; 222 if ("Linux".equals(System.getProperty("os.name"))) { 223 command += "set terminal x11;"; 224 } else { 225 command += "set terminal windows;"; 226 } 227 execute(command); 228 } 229 230 public void exportToFIG(File file, Object... parameters) throws Exception { 231 String command = ""; 232 command += "set terminal fig;"; 233 command += "set output \"" + file + "\";"; 234 command += "replot;"; 235 if ("Linux".equals(System.getProperty("os.name"))) { 236 command += "set terminal x11;"; 237 } else { 238 command += "set terminal windows;"; 239 } 240 execute(command); 241 } 242 243 public void exportToSVG(File file, Object... parameters) throws Exception { 244 String command = ""; 245 command += "set terminal svg;"; 246 command += "set output \"" + file + "\";"; 247 command += "replot;"; 248 if ("Linux".equals(System.getProperty("os.name"))) { 249 command += "set terminal x11;"; 250 } else { 251 command += "set terminal windows;"; 252 } 253 execute(command); 254 } 255 }