Skip to content

Commit e9b8c7a

Browse files
author
Martin Gütlein
committed
adjusted new repository name, added bar plot
1 parent b4a9c35 commit e9b8c7a

File tree

6 files changed

+254
-194
lines changed

6 files changed

+254
-194
lines changed

Rakefile

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,17 @@ require 'rake'
44
begin
55
require 'jeweler'
66
Jeweler::Tasks.new do |gem|
7-
gem.name = "svg_roc_plot"
7+
gem.name = "ruby-plot"
88
gem.summary = %Q{gnuplot wrapper for ruby, especially for plotting roc curves into svg files}
99
gem.description = %Q{}
1010
gem.email = "vorgrimmlerdavid@gmx.de"
11-
gem.homepage = "http://github.com/davor/svg_roc_plot"
11+
gem.homepage = "http://github.com/davor/ruby-plot"
1212
gem.authors = ["David Vorgrimmler", "Martin Gütlein"]
1313
[].each do |dep|
1414
gem.add_dependency dep
1515
end
1616
gem.files = FileList["[A-Z]*", "{bin,generators,lib,test}/**/*"]
17-
gem.files.include %w(lib/svg_roc_plot_method.rb)
17+
gem.files.include %w(lib/ruby-plot.rb)
1818
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
1919
end
2020
Jeweler::GemcutterTasks.new
@@ -35,7 +35,7 @@ Rake::RDocTask.new do |rdoc|
3535
end
3636

3737
rdoc.rdoc_dir = 'rdoc'
38-
rdoc.title = "svg_roc_plot #{version}"
38+
rdoc.title = "ruby-plot #{version}"
3939
rdoc.rdoc_files.include('README*')
4040
rdoc.rdoc_files.include('lib/**/*.rb')
4141
end

lib/plot_bars.rb

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
2+
module RubyPlot
3+
4+
def self.plot_bars(title = '', measures = [], algorithms = [], output_file = '')
5+
Gnuplot.open do |gp|
6+
Gnuplot::Plot.new( gp ) do |plot|
7+
string = ''
8+
(1..measures.length).collect.each do |i|
9+
string += '"' + measures[i-1] + '" ' + i.to_s + ".00000 -1 "
10+
end
11+
12+
plot.terminal 'svg size 600,400 dynamic enhanced fname "Arial" fsize 8 butt' #
13+
plot.output output_file
14+
plot.bar '1.000000'
15+
plot.boxwidth '0.9 absolute'
16+
plot.style 'fill solid 1.00 border -1'
17+
plot.style 'rectangle back fc lt -3 fillstyle solid 1.00 border -1'
18+
plot.key 'outside right top vertical Right noreverse enhanced autotitles columnhead nobox'
19+
plot.style 'histogram clustered gap 1 title offset character 0, 0, 0'
20+
# plot.datafile 'missing "-"'
21+
plot.style 'data histograms'
22+
plot.xtics 'border in scale 1,0.5 nomirror offset character 0, 0, 0'
23+
#plot.xtics 'norangelimit'
24+
plot.xtics string
25+
plot.title title
26+
plot.rrange '[ * : * ] noreverse nowriteback # (currently [0.00000:10.0000])'
27+
plot.trange '[ * : * ] noreverse nowriteback # (currently [-5.00000:5.00000])'
28+
plot.urange '[ * : * ] noreverse nowriteback # (currently [-5.00000:5.00000])'
29+
plot.vrange '[ * : * ] noreverse nowriteback # (currently [-5.00000:5.00000])'
30+
# plot.ylabel 'offset character 0, 0, 0 font "" textcolor lt -1 rotate by 90'
31+
# plot.y2label 'offset character 0, 0, 0 font "" textcolor lt -1 rotate by 90'
32+
plot.yrange '[ 0.00000 : 1.00000 ] noreverse nowriteback' #
33+
plot.cblabel 'offset character 0, 0, 0 font "" textcolor lt -1 rotate by 90'
34+
plot.locale '"C"'
35+
36+
algorithms.each do |algorithm|
37+
plot.data << Gnuplot::DataSet.new([ ["A"].concat(measures), algorithm ]) do |ds|
38+
ds.using = "2:xtic(1) ti col"
39+
end
40+
end
41+
end
42+
end
43+
LOGGER.info "plotted "+output_file.to_s
44+
end
45+
46+
def self.test_plot_bars
47+
x = ['ACC', 'AUC', 'SPEC', 'SENS']
48+
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]]
49+
plot_bars('Vergleich der Algorithmen', x, data, '/tmp/hist.svg')
50+
end
51+
52+
end

lib/plot_lines.rb

Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
#!/usr/bin/ruby1.8
2+
# svg_roc_plot method - svg_roc_plot_method.rb
3+
#
4+
# Copyright 2010 vorgrimmler <dv(a_t)fdm.uni-freiburg.de>
5+
# 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.
6+
# Gnuplot is needed. Please install befor using svg_roc_plot. "sudo apt-get install gnuplot" (on debian systems).
7+
# Usage: See below.
8+
9+
module RubyPlot
10+
11+
def self.plot_lines(svg_path, title, x_lable, y_lable, names, x_values, y_values, faint=nil)
12+
13+
data = []
14+
(0..x_values.size-1).each do |i|
15+
data << y_values[i]
16+
data << x_values[i]
17+
end
18+
19+
#Main
20+
STDOUT.sync = true
21+
# -----------------------------------------------------
22+
# checking input
23+
# -----------------------------------------------------
24+
# check parameters
25+
status=false
26+
LOGGER.debug "#{names.length} algs entered"
27+
28+
#LOGGER.debug names.inspect
29+
#LOGGER.debug data.inspect
30+
31+
if names.length != data.length/2
32+
status=true
33+
end
34+
35+
if status
36+
raise "Usage: svg_roc_plot (svg_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"+
37+
" Only pairs of data are allowed but at least one.\n"+
38+
" Each data array has to provide one float/int number from 0 to 100 per entry."
39+
end
40+
41+
# gnuplot check
42+
gnuplot=`which gnuplot | grep -o gnuplot`
43+
if gnuplot == "gnuplot\n"
44+
LOGGER.debug "Gnuplot is already installed."
45+
else
46+
raise "Please install gnuplot.\n"+
47+
"sudo apt-get install gnuplot"
48+
end
49+
50+
dat_number=0
51+
52+
output_dat_arr = Array.new
53+
54+
55+
# -----------------------------------------------------
56+
# create *.dat files of imported data for gnuplot
57+
# -----------------------------------------------------
58+
# write true/false arrays to one array
59+
for i in 0..names.length-1#/2-1
60+
true_pos_arr = data[i*2]
61+
false_pos_arr = data[i*2+1]
62+
#check length of input files
63+
if true_pos_arr.length == false_pos_arr.length
64+
#LOGGER.debug "Same length!"
65+
for j in 0..true_pos_arr.length-1
66+
#check if array entries are float format and between 0.0 and 100.0
67+
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
68+
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
69+
output_dat_arr[j] = "#{true_pos_arr[j]} #{false_pos_arr[j]}"
70+
else
71+
raise "The data of #{names[i]} has not the right formatin at position #{j}\n"+
72+
"The right format is one float/int from 0 to 100 each line (e.g. '0'; '23,34'; '65.87' or '99')"
73+
end
74+
else
75+
raise "The data of #{names[i]} has not the right formatin at position #{j}+\n"
76+
"The right format is one float/int from 0 to 100 each line (e.g. '0'; '23,34'; '65.87' or '99')"
77+
end
78+
end
79+
#-----------------------------------------------------
80+
#write *.dat files
81+
#-----------------------------------------------------
82+
#write output_dat_arr content in new *.dat file
83+
File.open( "data#{i}.dat", "w" ) do |the_file|
84+
the_file.puts output_dat_arr
85+
end
86+
LOGGER.debug "data#{i}.dat created."
87+
output_dat_arr.clear
88+
89+
else
90+
raise "Data pair of #{names[i]} have no the same number of elements."
91+
end
92+
end
93+
94+
# -----------------------------------------------------
95+
# create *.plt file for gnuplot
96+
# -----------------------------------------------------
97+
#
98+
output_plt_arr = Array.new
99+
output_plt_arr.push "# Specifies encoding and output format"
100+
output_plt_arr.push "set encoding default"
101+
output_plt_arr.push "set terminal svg"
102+
output_plt_arr.push "set output '#{svg_path}'"
103+
output_plt_arr.push ""
104+
output_plt_arr.push "# Specifies the range of the axes and appearance"
105+
106+
output_plt_arr.push "set xrange [0:100]"
107+
output_plt_arr.push "set yrange [0:100]"
108+
output_plt_arr.push "set grid lw 0.5"
109+
output_plt_arr.push "set title \"#{title}\""
110+
output_plt_arr.push "set key invert reverse Left outside"
111+
output_plt_arr.push "set xlabel \"#{x_lable}\""
112+
output_plt_arr.push "set ylabel \"#{y_lable}\""
113+
output_plt_arr.push "set arrow from 0,0 to 100,100 nohead"
114+
output_plt_arr.push ""
115+
output_plt_arr.push ""
116+
output_plt_arr.push ""
117+
output_plt_arr.push ""
118+
output_plt_arr.push "# Draws the plot and specifies its appearance ..."
119+
output_plt_arr.push "plot \\"#'random_0.dat' using 1:2 title 'random' with lines lw 1, \\"
120+
i = 0
121+
for i in 0..names.length-1
122+
123+
#style = grey[i] ? "lw 1.5 lt 0" : "lw 3"
124+
style = faint!=nil && faint[i] ? "lw 2" : "lw 4"
125+
126+
if i == names.length-1
127+
output_plt_arr.push " 'data#{i}.dat' using 2:1 title '#{names[i]}' with lines #{style}"
128+
else
129+
output_plt_arr.push " 'data#{i}.dat' using 2:1 title '#{names[i]}' with lines #{style}, \\"
130+
end
131+
end
132+
output_plt_arr.push ""
133+
output_plt_arr.push ""
134+
135+
# -----------------------------------------------------
136+
# write *.plt files
137+
# -----------------------------------------------------
138+
# write output_dat_arr content in new *.dat file
139+
File.open( "config.plt", "w" ) do |the_file|
140+
the_file.puts output_plt_arr
141+
end
142+
LOGGER.debug "config.plt created, running gnuplot"
143+
144+
# start gnuplot with created *.plt file
145+
cmd = "gnuplot config.plt 2>&1"
146+
response = ""
147+
IO.popen(cmd) do |f|
148+
while line = f.gets
149+
response += line
150+
end
151+
end
152+
raise "gnuplot failes (cmd: "+cmd.to_s+", out: "+response.to_s+")" unless $?==0
153+
154+
LOGGER.debug "#{svg_path} created. "
155+
156+
# -----------------------------------------------------
157+
# remove *.plt and *.dat files
158+
# -----------------------------------------------------
159+
`rm config.plt`
160+
LOGGER.debug "config.plt removed."
161+
for i in 0..names.length-1
162+
`rm data#{i}.dat`
163+
LOGGER.debug "data#{i}.dat removed."
164+
end
165+
end
166+
167+
def self.test_plot_lines
168+
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])
169+
end
170+
171+
private
172+
# float check
173+
def self.numeric?(object)
174+
true if Float(object) rescue false
175+
end
176+
end
177+

lib/ruby-plot.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
require 'rubygems'
2+
require 'logger'
3+
require 'gnuplot'
4+
5+
unless(defined? LOGGER)
6+
LOGGER = Logger.new(STDOUT)
7+
LOGGER.datetime_format = "%Y-%m-%d %H:%M:%S "
8+
end
9+
10+
require "plot_bars.rb"
11+
require "plot_lines.rb"
12+
13+
#RubyPlot::test_plot_lines
14+
#RubyPlot::test_plot_bars

0 commit comments

Comments
 (0)