Module: RubyPlot
- Defined in:
- lib/plot_lines.rb,
lib/plot_bars.rb,
lib/plot_points.rb
Overview
svg_roc_plot method - svg_roc_plot_method.rb
Copyright 2010 vorgrimmler <dv(a_t)fdm.uni-freiburg.de> This ruby method (svg_roc_plot) exports input data(from true-positive-rate and false-positive-rate arrays) to a *.svg file using gnuplot. Depending on the amount of input data is possible to create 1 to n curves in one plot. Gnuplot is needed. Please install befor using svg_roc_plot. “sudo apt-get install gnuplot” (on debian systems). Usage: See below.
Class Method Summary collapse
-
.accuracy_confidence_plot(path, title, x_lable, y_lable, names, x_values, y_values, reverse_y = false) ⇒ Object
y_range=nil,.
- .plot_bars(title = '', measures = [], algorithms = [], output_file = '') ⇒ Object
- .plot_lines(path, title, x_lable, y_lable, names, x_values, y_values, faint = nil, labels = nil) ⇒ Object
- .plot_points(path, title, x_lable, y_lable, names, x_values, y_values, log = true, x_range = nil, y_range = nil, quadratic_scale = true, draw_diagonale = true, line_points = false, reverse_x = false, reverse_y = false) ⇒ Object
-
.regression_point_plot(path, title, x_lable, y_lable, names, x_values, y_values, log = true) ⇒ Object
, quadratic_scale=true, line_points=false, reverse_x=false).
- .test_plot_bars ⇒ Object
- .test_plot_lines ⇒ Object
- .test_plot_points ⇒ Object
Class Method Details
.accuracy_confidence_plot(path, title, x_lable, y_lable, names, x_values, y_values, reverse_y = false) ⇒ Object
y_range=nil,
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/plot_points.rb', line 43 def self.accuracy_confidence_plot(path, title, x_lable, y_lable, names, x_values, y_values, reverse_y=false) #y_range=nil, min = Float::MAX max = -Float::MAX (0..x_values.size-1).each do |i| min = [ min, y_values[i].min ].min max = [ max, y_values[i].max ].max end border = (max-min)*0.1 min_border = min-border max_border = max+border y_range = min==max ? nil : [min_border, max_border] plot_points(path, title, x_lable, y_lable, names, x_values, y_values, false, nil, y_range, false, false, true, true, reverse_y) end |
.plot_bars(title = '', measures = [], algorithms = [], output_file = '') ⇒ Object
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/plot_bars.rb', line 4 def self.(title = '', measures = [], algorithms = [], output_file = '') #puts "'"+title+"',"+measures.inspect+","+algorithms.inspect+"," measures = measures.collect{|m| m.gsub(/_/,'-')} Gnuplot.open do |gp| Gnuplot::Plot.new( gp ) do |plot| string = '' (1..measures.length).collect.each do |i| string += '"' + measures[i-1] + '" ' + i.to_s + ".00000 -1 " end if output_file=~/(?i)svg/ plot.terminal 'svg size 800,600 dynamic enhanced fname "Arial" fsize 12 butt' elsif output_file=~/(?i)png/ plot.terminal 'png' else raise "format not supported "+path.to_s end plot.output output_file plot. '1.000000' plot.boxwidth '0.9 absolute' plot.style 'fill solid 1.00 border -1' plot.style 'rectangle back fc lt -3 fillstyle solid 1.00 border -1' #plot.key 'outside right top vertical Right noreverse enhanced autotitles columnhead nobox' #plot.key "invert reverse Left outside" plot.key "below" plot.style 'histogram clustered gap 3 title offset character 0, 0, 0' # plot.datafile 'missing "-"' plot.style 'data histograms' plot.xtics 'border in scale 1,0.5 nomirror offset character 0, 0, 0' #plot.xtics 'norangelimit' plot.xtics 'rotate' #plot.xtics string plot.title title plot.rrange '[ * : * ] noreverse nowriteback # (currently [0.00000:10.0000])' plot.trange '[ * : * ] noreverse nowriteback # (currently [-5.00000:5.00000])' plot.urange '[ * : * ] noreverse nowriteback # (currently [-5.00000:5.00000])' plot.vrange '[ * : * ] noreverse nowriteback # (currently [-5.00000:5.00000])' # plot.ylabel 'offset character 0, 0, 0 font "" textcolor lt -1 rotate by 90' # plot.y2label 'offset character 0, 0, 0 font "" textcolor lt -1 rotate by 90' plot.yrange '[ 0.00000 : 1.00000 ] noreverse nowriteback' # plot.cblabel 'offset character 0, 0, 0 font "" textcolor lt -1 rotate by 90' plot.locale '"C"' algorithms.each do |algorithm| plot.data << Gnuplot::DataSet.new([ ["A"].concat(measures), algorithm ]) do |ds| ds.using = "2:xtic(1) ti col" end end end end LOGGER.info "plotted "+output_file.to_s end |
.plot_lines(path, title, x_lable, y_lable, names, x_values, y_values, faint = nil, labels = nil) ⇒ Object
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 |
# File 'lib/plot_lines.rb', line 11 def self.plot_lines(path, title, x_lable, y_lable, names, x_values, y_values, faint=nil, labels=nil) LOGGER.debug "plot lines -- "+names.inspect LOGGER.debug "plot lines -- "+x_values.inspect LOGGER.debug "plot lines -- "+y_values.inspect LOGGER.debug "plot lines -- "+labels.inspect data = [] (0..x_values.size-1).each do |i| data << y_values[i] data << x_values[i] end #Main STDOUT.sync = true # ----------------------------------------------------- # checking input # ----------------------------------------------------- # check parameters status=false LOGGER.debug "#{names.length} algs entered" #LOGGER.debug names.inspect #LOGGER.debug data.inspect if names.length != data.length/2 status=true end if status raise "Usage: svg_roc_plot (path(?), title(string), x-lable(string), y-lable(sting), algorithms(array), true_pos_data1(array), false_pos_data1(array), ..., true_pos_data_n(array), false_pos_data_n(array))\n"+ " Only pairs of data are allowed but at least one.\n"+ " Each data array has to provide one float/int number from 0 to 100 per entry." end # gnuplot check gnuplot=`which gnuplot | grep -o gnuplot` if gnuplot == "gnuplot\n" LOGGER.debug "Gnuplot is already installed." else raise "Please install gnuplot.\n"+ "sudo apt-get install gnuplot" end dat_number=0 output_dat_arr = Array.new # ----------------------------------------------------- # create *.dat files of imported data for gnuplot # ----------------------------------------------------- # write true/false arrays to one array for i in 0..names.length-1#/2-1 true_pos_arr = data[i*2] false_pos_arr = data[i*2+1] #check length of input files if true_pos_arr.length == false_pos_arr.length #LOGGER.debug "Same length!" for j in 0..true_pos_arr.length-1 #check if array entries are float format and between 0.0 and 100.0 if numeric?(true_pos_arr[j].to_s.tr(',', '.')) && true_pos_arr[j].to_s.tr(',', '.').to_f <= 100 && true_pos_arr[j].to_s.tr(',', '.').to_f >= 0 if numeric?(false_pos_arr[j].to_s.tr(',', '.')) && false_pos_arr[j].to_s.tr(',', '.').to_f <= 100 && false_pos_arr[j].to_s.tr(',', '.').to_f >= 0 output_dat_arr[j] = "#{true_pos_arr[j]} #{false_pos_arr[j]}" else raise "The data of #{names[i]} has not the right formatin at position #{j}\n"+ "The right format is one float/int from 0 to 100 each line (e.g. '0'; '23,34'; '65.87' or '99')" end else raise "The data of #{names[i]} has not the right formatin at position #{j}+\n" "The right format is one float/int from 0 to 100 each line (e.g. '0'; '23,34'; '65.87' or '99')" end end #----------------------------------------------------- #write *.dat files #----------------------------------------------------- #write output_dat_arr content in new *.dat file File.open( "data#{i}.dat", "w" ) do |the_file| the_file.puts output_dat_arr end LOGGER.debug "data#{i}.dat created." output_dat_arr.clear else raise "Data pair of #{names[i]} have no the same number of elements." end end # ----------------------------------------------------- # create *.plt file for gnuplot # ----------------------------------------------------- # output_plt_arr = Array.new output_plt_arr.push "# Specifies encoding and output format" output_plt_arr.push "set encoding default" #output_plt_arr.push "set terminal svg" if path=~/(?i)svg/ output_plt_arr.push 'set terminal svg size 800,600 dynamic enhanced fname "Arial" fsize 12 butt' elsif path=~/(?i)png/ output_plt_arr.push 'set terminal png' else raise "format not supported "+path.to_s end output_plt_arr.push "set output '#{path}'" output_plt_arr.push "" output_plt_arr.push "# Specifies the range of the axes and appearance" # x and y have equal scale output_plt_arr.push 'set size ratio -1' output_plt_arr.push "set xrange [0:100]" output_plt_arr.push "set yrange [0:100]" output_plt_arr.push "set grid lw 0.5" output_plt_arr.push "set title \"#{title}\"" output_plt_arr.push "set key below" #output_plt_arr.push "set key invert reverse Left outside" output_plt_arr.push "set xlabel \"#{x_lable}\"" output_plt_arr.push "set ylabel \"#{y_lable}\"" output_plt_arr.push "set arrow from 0,0 to 100,100 nohead lt 0" output_plt_arr.push "" output_plt_arr.push "" output_plt_arr.push "" output_plt_arr.push "" output_plt_arr.push "# Draws the plot and specifies its appearance ..." if labels!=nil type = 1 labels.each do |label| if label!=nil l = label[0] x = label[1] y = label[2] puts l.to_s+" "+x.to_s+" "+y.to_s #output_plt_arr.push "set label \"("+x.to_s+","+y.to_s+") "+l.to_s+"\" at first 25, first 40" output_plt_arr.push "set label \""+l.to_s+"\" at first "+x.to_s+", first "+y.to_s+" front offset 1,-1 tc lt "+type.to_s output_plt_arr.push "set arrow from "+(x+3).to_s+","+(y-3).to_s+" to "+(x+1).to_s+","+(y-1).to_s+" lt "+type.to_s end type += 1 end end output_plt_arr.push "plot \\"#'random_0.dat' using 1:2 title 'random' with lines lw 1, \\" i = 0 for i in 0..names.length-1 #style = grey[i] ? "lw 1.5 lt 0" : "lw 3" style = faint!=nil && faint[i] ? "lw 2" : "lw 4" if i == names.length-1 output_plt_arr.push " 'data#{i}.dat' using 2:1 title '#{names[i]}' with lines #{style}" else output_plt_arr.push " 'data#{i}.dat' using 2:1 title '#{names[i]}' with lines #{style}, \\" end end output_plt_arr.push "" output_plt_arr.push "" # ----------------------------------------------------- # write *.plt files # ----------------------------------------------------- # write output_dat_arr content in new *.dat file File.open( "config.plt", "w" ) do |the_file| the_file.puts output_plt_arr end LOGGER.debug "config.plt created, running gnuplot" # start gnuplot with created *.plt file cmd = "gnuplot config.plt 2>&1" response = "" IO.popen(cmd) do |f| while line = f.gets response += line end end raise "gnuplot failes (cmd: "+cmd.to_s+", out: "+response.to_s+")" unless $?==0 LOGGER.debug "#{path} created. " # ----------------------------------------------------- # remove *.plt and *.dat files # ----------------------------------------------------- `rm config.plt` LOGGER.debug "config.plt removed." for i in 0..names.length-1 `rm data#{i}.dat` LOGGER.debug "data#{i}.dat removed." end end |
.plot_points(path, title, x_lable, y_lable, names, x_values, y_values, log = true, x_range = nil, y_range = nil, quadratic_scale = true, draw_diagonale = true, line_points = false, reverse_x = false, reverse_y = false) ⇒ Object
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 |
# File 'lib/plot_points.rb', line 59 def self.plot_points(path, title, x_lable, y_lable, names, x_values, y_values, log=true, x_range=nil, y_range=nil, quadratic_scale=true, draw_diagonale=true, line_points=false, reverse_x=false, reverse_y=false) LOGGER.debug "ruby-plot: names "+names.inspect LOGGER.debug "ruby-plot: x "+x_values.inspect LOGGER.debug "ruby-plot: y "+y_values.inspect LOGGER.debug "ruby-plot: y_range "+y_range.inspect data = [] (0..x_values.size-1).each do |i| data << y_values[i] data << x_values[i] end #Main STDOUT.sync = true # ----------------------------------------------------- # checking input # ----------------------------------------------------- # check parameters status=false LOGGER.debug "#{names.length} algs entered" #LOGGER.debug names.inspect #LOGGER.debug data.inspect if names.length != data.length/2 status=true end if status raise "Usage: svg_roc_plot (path(?), title(string), x-lable(string), y-lable(sting), algorithms(array), true_pos_data1(array), false_pos_data1(array), ..., true_pos_data_n(array), false_pos_data_n(array))\n"+ " Only pairs of data are allowed but at least one.\n"+ " Each data array has to provide one float/int number from 0 to 100 per entry." end # gnuplot check gnuplot=`which gnuplot | grep -o gnuplot` if gnuplot == "gnuplot\n" LOGGER.debug "Gnuplot is already installed." else raise "Please install gnuplot.\n"+ "sudo apt-get install gnuplot" end dat_number=0 output_dat_arr = Array.new # ----------------------------------------------------- # create *.dat files of imported data for gnuplot # ----------------------------------------------------- # write true/false arrays to one array for i in 0..names.length-1#/2-1 true_pos_arr = data[i*2] false_pos_arr = data[i*2+1] #check length of input files if true_pos_arr.length == false_pos_arr.length #LOGGER.debug "Same length!" for j in 0..true_pos_arr.length-1 #check if array entries are float format and between 0.0 and 100.0 #if numeric?(true_pos_arr[j].to_s.tr(',', '.')) && true_pos_arr[j].to_s.tr(',', '.').to_f <= 100 && true_pos_arr[j].to_s.tr(',', '.').to_f >= 0 # if numeric?(false_pos_arr[j].to_s.tr(',', '.')) && false_pos_arr[j].to_s.tr(',', '.').to_f <= 100 && false_pos_arr[j].to_s.tr(',', '.').to_f >= 0 output_dat_arr[j] = "#{true_pos_arr[j]} #{false_pos_arr[j]}" # else # raise "The data of #{names[i]} has not the right formatin at position #{j}\n"+ # "The right format is one float/int from 0 to 100 each line (e.g. '0'; '23,34'; '65.87' or '99')" # end #else # raise "The data of #{names[i]} has not the right formatin at position #{j}+\n" # "The right format is one float/int from 0 to 100 each line (e.g. '0'; '23,34'; '65.87' or '99')" #end end #----------------------------------------------------- #write *.dat files #----------------------------------------------------- #write output_dat_arr content in new *.dat file File.open( "data#{i}.dat", "w" ) do |the_file| the_file.puts output_dat_arr end LOGGER.debug "data#{i}.dat created." output_dat_arr.clear else raise "Data pair of #{names[i]} have no the same number of elements." end end # ----------------------------------------------------- # create *.plt file for gnuplot # ----------------------------------------------------- # output_plt_arr = Array.new output_plt_arr.push "# Specifies encoding and output format" output_plt_arr.push "set encoding default" if path=~/(?i)svg/ output_plt_arr.push 'set terminal svg size 800,600 dynamic enhanced fname "Arial" fsize 12 butt' elsif path=~/(?i)png/ output_plt_arr.push 'set terminal png' else raise "format not supported "+path.to_s end if log output_plt_arr.push 'set logscale x' output_plt_arr.push 'set logscale y' end output_plt_arr.push "set output '#{path}'" output_plt_arr.push "" output_plt_arr.push "# Specifies the range of the axes and appearance" x_range_s = x_range ? "["+x_range[0].to_s+":"+x_range[1].to_s+"]" : "[]" y_range_s = y_range ? "["+y_range[0].to_s+":"+y_range[1].to_s+"]" : "[]" reverse_x_s = reverse_x ? "reverse" : "" reverse_y_s = reverse_y ? "reverse" : "" output_plt_arr.push "set xrange "+x_range_s+" "+reverse_x_s output_plt_arr.push "set yrange "+y_range_s+" "+reverse_y_s output_plt_arr.push 'set size ratio -1' if quadratic_scale output_plt_arr.push "set arrow from "+x_range[0].to_s+","+y_range[0].to_s+" to "+x_range[1].to_s+","+y_range[1].to_s+" nohead lt 0" if draw_diagonale output_plt_arr.push "set grid lw 0.5" output_plt_arr.push "set title \"#{title}\"" output_plt_arr.push "set key below" output_plt_arr.push "set xlabel \"#{x_lable}\"" output_plt_arr.push "set ylabel \"#{y_lable}\"" output_plt_arr.push "" output_plt_arr.push "" output_plt_arr.push "" output_plt_arr.push "" output_plt_arr.push "# Draws the plot and specifies its appearance ..." output_plt_arr.push "plot \\"#'random_0.dat' using 1:2 title 'random' with lines lw 1, \\" style = "points" if line_points style = "lp" end i = 0 for i in 0..names.length-1 if i == names.length-1 output_plt_arr.push " 'data#{i}.dat' using 2:1 title '#{names[i]}' with "+style.to_s else output_plt_arr.push " 'data#{i}.dat' using 2:1 title '#{names[i]}' with "+style.to_s+", \\" end end output_plt_arr.push "" output_plt_arr.push "" #output_plt_arr << "plot f(x)" # ----------------------------------------------------- # write *.plt files # ----------------------------------------------------- # write output_dat_arr content in new *.dat file File.open( "config.plt", "w" ) do |the_file| the_file.puts output_plt_arr end LOGGER.debug "config.plt created, running gnuplot" # start gnuplot with created *.plt file cmd = "gnuplot config.plt 2>&1" response = "" IO.popen(cmd) do |f| while line = f.gets response += line end end raise "gnuplot failes (cmd: "+cmd.to_s+", out: "+response.to_s+")" unless $?==0 LOGGER.debug "#{path} created. " # ----------------------------------------------------- # remove *.plt and *.dat files # ----------------------------------------------------- `rm config.plt` LOGGER.debug "config.plt removed." for i in 0..names.length-1 `rm data#{i}.dat` LOGGER.debug "data#{i}.dat removed." end end |
.regression_point_plot(path, title, x_lable, y_lable, names, x_values, y_values, log = true) ⇒ Object
, quadratic_scale=true, line_points=false, reverse_x=false)
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/plot_points.rb', line 11 def self.regression_point_plot(path, title, x_lable, y_lable, names, x_values, y_values, log=true) #, quadratic_scale=true, line_points=false, reverse_x=false) min = Float::MAX max = -Float::MAX (0..x_values.size-1).each do |i| min = [ min, x_values[i].min, y_values[i].min ].min max = [ max, x_values[i].max, y_values[i].max ].max end if log && min<=0 LOGGER.warn "cannot use logscale for <=0 data" log = false end border = (max-min)*0.1 if log min_border = min-border/10.0 while min_border<=0 border /= 2 min_border = min-border/10.0 end max_border = max+border else min_border = min-border max_border = max+border end x_range = min==max ? nil : [min_border, max_border] y_range = min==max ? nil : [min_border, max_border] plot_points(path, title, x_lable, y_lable, names, x_values, y_values, log, x_range, y_range, true, true, false, false, false) end |
.test_plot_bars ⇒ Object
64 65 66 67 68 69 70 71 72 |
# File 'lib/plot_bars.rb', line 64 def self. x = ['ACC_with_very_long_name_consider_that', 'AUC', 'SPEC', 'SENS'] data = [['Alg1', 1.00, 1.00, 1.00, 1.00], ['Alg2', 0.75, 0.75, 0.75, 0.75], ['Alg3', 0.50, 0.50, 0.50, 0.50]] ('Vergleich der Algorithmen', x, data, '/tmp/hist.svg') x = ['ACC_with_very_long_name_consider_that', 'AUC', 'SPEC', 'SENS'] data = [['Alg1', 1.00, 1.00, 1.00, 1.00], ['Alg2', 0.75, 0.75, 0.75, 0.75], ['Alg3', 0.50, 0.50, 0.50, 0.50]] ('Vergleich der Algorithmen', x, data, '/tmp/hist.png') end |
.test_plot_lines ⇒ Object
200 201 202 203 204 |
# File 'lib/plot_lines.rb', line 200 def self.test_plot_lines #plot_lines("/tmp/result.svg" , "name of title", "x-values", "y-values", ["name", "test", "bla"], [[20,60,80], [10,25,70,95], [12,78,99]], [[15,50,90],[20,40,50,70],[34,89,89]],[true,false,true]) plot_lines("/tmp/result.png" , "name of title", "x-values", "y-values", ["name", "test", "bla"], [[20,60,80], [10,25,70,95], [12,78,99]], [[15,50,90],[20,40,50,70],[34,89,89]],[true,false,true],[nil,["confidence",25,40]]) end |
.test_plot_points ⇒ Object
249 250 251 252 253 254 255 256 257 |
# File 'lib/plot_points.rb', line 249 def self.test_plot_points regression_point_plot("/tmp/regression.png" , "name of title", "x-values", "y-values", ["this-one-has-a-very-very-very-long-name", "test" ], [[0.20,0.60,0.80,0.20,1.0,0.001], [0.10,0.25,0.70,0.95,0.2,0.3434]], [[0.15,0.50,0.90,0.2,9,0.5],[0.20,0.40,0.50,0.70,0.3,0.234589]]) accuracy_confidence_plot("/tmp/accuracy-conf.png" , "name of title", "x-values", "y-values", ["test" ], [[0.9,0.5,0.3,0.1]], [[100,90,70,30]]) end |