gnuplotrb 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.rdoc +66 -3
- data/Rakefile +3 -4
- data/gnuplotrb.gemspec +1 -1
- data/lib/gnuplotrb.rb +5 -0
- data/lib/gnuplotrb/animation.rb +36 -9
- data/lib/gnuplotrb/external_classes/array.rb +1 -0
- data/lib/gnuplotrb/external_classes/daru.rb +8 -0
- data/lib/gnuplotrb/external_classes/string.rb +2 -3
- data/lib/gnuplotrb/fit.rb +188 -160
- data/lib/gnuplotrb/mixins/error_handling.rb +6 -4
- data/lib/gnuplotrb/mixins/option_handling.rb +60 -34
- data/lib/gnuplotrb/mixins/plottable.rb +109 -26
- data/lib/gnuplotrb/multiplot.rb +123 -44
- data/lib/gnuplotrb/plot.rb +145 -42
- data/lib/gnuplotrb/splot.rb +8 -8
- data/lib/gnuplotrb/staff/datablock.rb +54 -12
- data/lib/gnuplotrb/staff/dataset.rb +118 -48
- data/lib/gnuplotrb/staff/settings.rb +24 -21
- data/lib/gnuplotrb/staff/terminal.rb +68 -34
- data/lib/gnuplotrb/version.rb +3 -1
- metadata +7 -6
data/lib/gnuplotrb/plot.rb
CHANGED
@@ -1,19 +1,50 @@
|
|
1
1
|
module GnuplotRB
|
2
2
|
##
|
3
|
-
#
|
4
|
-
#
|
3
|
+
# Class corresponding to simple 2D visualisation.
|
4
|
+
#
|
5
|
+
# == Notebooks
|
6
|
+
#
|
7
|
+
# * {Heatmaps}[http://nbviewer.ipython.org/github/dilcom/gnuplotrb/blob/master/notebooks/heatmaps.ipynb]
|
8
|
+
# * {Vector field}[http://nbviewer.ipython.org/github/dilcom/gnuplotrb/blob/master/notebooks/vector_field.ipynb]
|
9
|
+
# * {Math equations}[http://nbviewer.ipython.org/github/dilcom/gnuplotrb/blob/master/notebooks/math_plots.ipynb]
|
10
|
+
# * {Histogram}[http://nbviewer.ipython.org/github/dilcom/gnuplotrb/blob/master/notebooks/histogram.ipynb]
|
11
|
+
# * {Updating plots with new data}[http://nbviewer.ipython.org/github/dilcom/gnuplotrb/blob/master/notebooks/updating_data.ipynb]
|
12
|
+
#
|
13
|
+
# == Options
|
14
|
+
# All possible options are exaplained in
|
15
|
+
# {gnuplot docs}[http://www.gnuplot.info/docs_5.0/gnuplot.pdf] (pp. 105-190).
|
16
|
+
#
|
17
|
+
# Several common ones:
|
18
|
+
#
|
19
|
+
# * xrange(yrange, zrange, urange, vrange) - set range for a variable. Takes
|
20
|
+
# Range (xrange: 0..100), or String (yrange: '[0:100]').
|
21
|
+
# * title - plot's title. Takes String (title: 'Some new plot').
|
22
|
+
# * polar (parametric) - plot in polar or parametric space. Takes boolean (true).
|
23
|
+
# * style_data - set style for plotting data. Takes string, possible values: histogram,
|
24
|
+
# points, lines, linespoints, boxes etc. See gnuplot docs for more.
|
25
|
+
# * term - select terminal used by gnuplot. Examples: { term: 'png' },
|
26
|
+
# { term: ['svg', size: [600, 600]] }. Deprecated due to existance of #to_<term_name> methods.
|
27
|
+
# One can use #to_png and #to_svg(size: [600, 600]) instead of passing previous options.
|
28
|
+
# * output - select filename to output plot to. Should be used together with term. Deprecated
|
29
|
+
# due to existance of #to_<term_name> methods. One should use #to_png('file.png') instead of
|
30
|
+
# passing { term: 'png', output: 'file.png' }.
|
31
|
+
# Every option may be passed to constructor in order to create plot with it.
|
32
|
+
#
|
33
|
+
# Methods #options(several: options, ...) and bunch of #option_name(only_an: option) such as
|
34
|
+
# #xrange, #using, #polar etc create new Plot object based on existing but with a new options.
|
35
|
+
#
|
36
|
+
# Methods with the same names ending with '!' or '=' ('plot.xrange!(1..3)',
|
37
|
+
# 'plot.title = "New title"') are destructive and modify state of existing object just as
|
38
|
+
# "Array#sort!" do with Array object. See notebooks for examples.
|
5
39
|
class Plot
|
6
40
|
include Plottable
|
7
41
|
##
|
8
42
|
# Array of datasets which are plotted by this object.
|
9
43
|
attr_reader :datasets
|
10
44
|
##
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
14
|
-
# * *options* will be considered as 'settable' options of gnuplot
|
15
|
-
# ('set xrange [1:10]' for { xrange: 1..10 },
|
16
|
-
# "set title 'plot'" for { title: 'plot' } etc)
|
45
|
+
# @param *datasets [Sequence of Dataset or Array] either instances of Dataset class or
|
46
|
+
# "[data, **dataset_options]"" arrays
|
47
|
+
# @param options [Hash] see Plot top level doc for options examples
|
17
48
|
def initialize(*datasets)
|
18
49
|
# had to relace **options arg with this because in some cases
|
19
50
|
# Daru::DataFrame was mentioned as hash and added to options
|
@@ -30,14 +61,13 @@ module GnuplotRB
|
|
30
61
|
end
|
31
62
|
|
32
63
|
##
|
33
|
-
#
|
34
|
-
#
|
35
|
-
#
|
36
|
-
#
|
37
|
-
#
|
38
|
-
#
|
39
|
-
#
|
40
|
-
# Options passed here have priority over already existing.
|
64
|
+
# Output plot to term (if given) or to this plot's own terminal.
|
65
|
+
#
|
66
|
+
# @param term [Terminal] Terminal object to plot to
|
67
|
+
# @param :multiplot_part [Boolean] true if this plot is part of a multiplot. For inner use!
|
68
|
+
# @param options [Hash] see options in Plot top level doc.
|
69
|
+
# Options passed here have priority over already existing.
|
70
|
+
# @return [Plot] self
|
41
71
|
def plot(term = nil, multiplot_part: false, **options)
|
42
72
|
fail ArgumentError, 'Empty plots are not supported!' if @datasets.empty?
|
43
73
|
inner_opts = if multiplot_part
|
@@ -62,16 +92,17 @@ module GnuplotRB
|
|
62
92
|
alias_method :replot, :plot
|
63
93
|
|
64
94
|
##
|
65
|
-
# ====== Overview
|
66
95
|
# Create new Plot object where dataset at *position* will
|
67
96
|
# be replaced with the new one created from it by updating.
|
68
|
-
#
|
69
|
-
#
|
97
|
+
#
|
98
|
+
# @param position [Integer] position of dataset which you need to update
|
70
99
|
# (by default first dataset is updated)
|
71
|
-
#
|
72
|
-
#
|
73
|
-
#
|
100
|
+
# @param data [#to_gnuplot_points] data to update dataset with
|
101
|
+
# @param options [Hash] options to update dataset with, see Dataset top level doc
|
102
|
+
#
|
103
|
+
# @example
|
74
104
|
# updated_plot = plot.update_dataset(data: [x1,y1], title: 'After update')
|
105
|
+
# # plot IS NOT affected (if dataset did not store data in a file)
|
75
106
|
def update_dataset(position = 0, data: nil, **options)
|
76
107
|
old_ds = @datasets[position]
|
77
108
|
new_ds = old_ds.update(data, options)
|
@@ -79,37 +110,74 @@ module GnuplotRB
|
|
79
110
|
end
|
80
111
|
|
81
112
|
##
|
82
|
-
#
|
113
|
+
# Updates existing Plot object by replacing dataset at *position*
|
114
|
+
# with the new one created from it by updating.
|
115
|
+
#
|
116
|
+
# @param position [Integer] position of dataset which you need to update
|
117
|
+
# (by default first dataset is updated)
|
118
|
+
# @param data [#to_gnuplot_points] data to update dataset with
|
119
|
+
# @param options [Hash] options to update dataset with, see Dataset top level doc
|
120
|
+
#
|
121
|
+
# @example
|
122
|
+
# plot.update_dataset!(data: [x1,y1], title: 'After update')
|
123
|
+
# # plot IS affected anyway
|
124
|
+
def update_dataset!(position = 0, data: nil, **options)
|
125
|
+
@datasets[position].update!(data, options)
|
126
|
+
self
|
127
|
+
end
|
128
|
+
|
129
|
+
##
|
83
130
|
# Create new Plot object where dataset at *position* will
|
84
131
|
# be replaced with the given one.
|
85
|
-
#
|
86
|
-
#
|
132
|
+
#
|
133
|
+
# @param position [Integer] position of dataset which you need to replace
|
87
134
|
# (by default first dataset is replaced)
|
88
|
-
#
|
89
|
-
# give here [data, **dataset_options] array from
|
90
|
-
#
|
91
|
-
# ====== Example
|
135
|
+
# @param dataset [Dataset, Array] dataset to replace the old one. You can also
|
136
|
+
# give here "[data, **dataset_options]"" array from which Dataset may be created.
|
137
|
+
# @example
|
92
138
|
# sinx = Plot.new('sin(x)')
|
93
139
|
# cosx = sinx.replace_dataset(['cos(x)'])
|
140
|
+
# # sinx IS NOT affected
|
94
141
|
def replace_dataset(position = 0, dataset)
|
95
142
|
self.class.new(@datasets.set(position, dataset_from_any(dataset)), @options)
|
96
143
|
end
|
97
144
|
|
98
145
|
##
|
99
|
-
#
|
146
|
+
# Updates existing Plot object by replacing dataset at *position*
|
147
|
+
# with the given one.
|
148
|
+
#
|
149
|
+
# @param position [Integer] position of dataset which you need to replace
|
150
|
+
# (by default first dataset is replaced)
|
151
|
+
# @param dataset [Dataset, Array] dataset to replace the old one. You can also
|
152
|
+
# give here "[data, **dataset_options]"" array from which Dataset may be created.
|
153
|
+
# @example
|
154
|
+
# sinx = Plot.new('sin(x)')
|
155
|
+
# sinx.replace_dataset!(['cos(x)'])
|
156
|
+
# # sinx IS affected
|
157
|
+
def replace_dataset!(position = 0, dataset)
|
158
|
+
@datasets = @datasets.set(position, dataset_from_any(dataset))
|
159
|
+
self
|
160
|
+
end
|
161
|
+
|
162
|
+
alias_method :[]=, :replace_dataset!
|
163
|
+
|
164
|
+
##
|
100
165
|
# Create new Plot object where given datasets will
|
101
166
|
# be inserted into dataset list before given position
|
102
167
|
# (position = 0 by default).
|
103
|
-
#
|
104
|
-
#
|
105
|
-
#
|
106
|
-
#
|
168
|
+
#
|
169
|
+
# @param position [Integer] position of dataset BEFORE which datasets will be placed.
|
170
|
+
# 0 by default.
|
171
|
+
# @param *datasets [ Sequence of Dataset or Array] datasets to insert
|
172
|
+
# @example
|
107
173
|
# sinx = Plot.new('sin(x)')
|
108
174
|
# sinx_and_cosx_with_expx = sinx.add(['cos(x)'], ['exp(x)'])
|
109
175
|
#
|
110
176
|
# cosx_and_sinx = sinx << ['cos(x)']
|
177
|
+
# # sinx IS NOT affected in both cases
|
111
178
|
def add_datasets(*datasets)
|
112
179
|
datasets.map! { |ds| ds.is_a?(Numeric) ? ds : dataset_from_any(ds) }
|
180
|
+
# first element is position where to add datasets
|
113
181
|
datasets.unshift(0) unless datasets[0].is_a?(Numeric)
|
114
182
|
self.class.new(@datasets.insert(*datasets), @options)
|
115
183
|
end
|
@@ -118,23 +186,58 @@ module GnuplotRB
|
|
118
186
|
alias_method :<<, :add_datasets
|
119
187
|
|
120
188
|
##
|
121
|
-
#
|
189
|
+
# Updates existing Plot object by inserting given datasets
|
190
|
+
# into dataset list before given position (position = 0 by default).
|
191
|
+
#
|
192
|
+
# @param position [Integer] position of dataset BEFORE which datasets will be placed.
|
193
|
+
# 0 by default.
|
194
|
+
# @param *datasets [ Sequence of Dataset or Array] datasets to insert
|
195
|
+
# @example
|
196
|
+
# sinx = Plot.new('sin(x)')
|
197
|
+
# sinx.add!(['cos(x)'], ['exp(x)'])
|
198
|
+
# # sinx IS affected
|
199
|
+
def add_datasets!(*datasets)
|
200
|
+
datasets.map! { |ds| ds.is_a?(Numeric) ? ds : dataset_from_any(ds) }
|
201
|
+
# first element is position where to add datasets
|
202
|
+
datasets.unshift(0) unless datasets[0].is_a?(Numeric)
|
203
|
+
@datasets = @datasets.insert(*datasets)
|
204
|
+
self
|
205
|
+
end
|
206
|
+
|
207
|
+
alias_method :add_dataset!, :add_datasets!
|
208
|
+
|
209
|
+
##
|
122
210
|
# Create new Plot object where dataset at given position
|
123
211
|
# will be removed from dataset list.
|
124
|
-
#
|
125
|
-
#
|
212
|
+
#
|
213
|
+
# @param position [Integer] position of dataset that should be
|
126
214
|
# removed (by default last dataset is removed)
|
127
|
-
#
|
215
|
+
# @example
|
128
216
|
# sinx_and_cosx = Plot.new('sin(x)', 'cos(x)')
|
129
217
|
# sinx = sinx_and_cosx.remove_dataset
|
130
218
|
# cosx = sinx_and_cosx.remove_dataset(0)
|
219
|
+
# # sinx_and_cosx IS NOT affected in both cases
|
131
220
|
def remove_dataset(position = -1)
|
132
221
|
self.class.new(@datasets.delete_at(position), @options)
|
133
222
|
end
|
134
223
|
|
135
224
|
##
|
136
|
-
#
|
137
|
-
#
|
225
|
+
# Updates existing Plot object by removing dataset at given position.
|
226
|
+
#
|
227
|
+
# @param position [Integer] position of dataset that should be
|
228
|
+
# removed (by default last dataset is removed)
|
229
|
+
# @example
|
230
|
+
# sinx_and_cosx = Plot.new('sin(x)', 'cos(x)')
|
231
|
+
# sinx_and_cosx!.remove_dataset
|
232
|
+
# sinx_and_cosx!.remove_dataset
|
233
|
+
# # sinx_and_cosx IS affected and now is empty
|
234
|
+
def remove_dataset!(position = -1)
|
235
|
+
@datasets = @datasets.delete_at(position)
|
236
|
+
self
|
237
|
+
end
|
238
|
+
|
239
|
+
##
|
240
|
+
# The same as #datasets[*args]
|
138
241
|
def [](*args)
|
139
242
|
@datasets[*args]
|
140
243
|
end
|
@@ -149,11 +252,11 @@ module GnuplotRB
|
|
149
252
|
return unless data.is_a?(Daru::DataFrame) || data.is_a?(Daru::Vector)
|
150
253
|
return unless data.index.first.is_a?(DateTime)
|
151
254
|
return if using[0..1] != '1:'
|
152
|
-
@options =
|
255
|
+
@options = Hamster::Hash.new(
|
153
256
|
xdata: 'time',
|
154
257
|
timefmt: '%Y-%m-%dT%H:%M:%S',
|
155
258
|
format_x: '%d\n%b\n%Y'
|
156
|
-
)
|
259
|
+
).merge(@options)
|
157
260
|
end
|
158
261
|
|
159
262
|
##
|
data/lib/gnuplotrb/splot.rb
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
module GnuplotRB
|
2
2
|
##
|
3
|
-
#
|
4
|
-
#
|
3
|
+
# Splot class correspond to simple 3D visualisation.
|
4
|
+
# Most of Plot's docs are right for Splot too.
|
5
|
+
#
|
6
|
+
# Examples of usage are in
|
7
|
+
# {a notebook}[http://nbviewer.ipython.org/github/dilcom/gnuplotrb/blob/master/notebooks/3d_plot.ipynb]
|
5
8
|
class Splot < Plot
|
6
9
|
##
|
7
|
-
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
# * *options* will be considered as 'settable' options of gnuplot
|
11
|
-
# ('set xrange [1:10]' for { xrange: 1..10 }, "set title 'plot'"
|
12
|
-
# for { title: 'plot' } etc)
|
10
|
+
# @param *datasets [Sequence of Dataset or Array] either instances of Dataset class or
|
11
|
+
# "[data, **dataset_options]"" arrays
|
12
|
+
# @param options [Hash] see Plot top level doc for options examples
|
13
13
|
def initialize(*datasets, **options)
|
14
14
|
super
|
15
15
|
@cmd = 'splot '
|
@@ -1,15 +1,13 @@
|
|
1
1
|
module GnuplotRB
|
2
2
|
##
|
3
|
-
# === Overview
|
4
3
|
# This class corresponds to points we want to plot. It may be
|
5
4
|
# stored in temporary file (to allow fast update) or inside
|
6
5
|
# "$DATA << EOD ... EOD" construction. Datablock stores data passed
|
7
6
|
# to constructor and keeps datablock name or path to file where it is stored.
|
8
7
|
class Datablock
|
9
8
|
##
|
10
|
-
#
|
11
|
-
#
|
12
|
-
# * *stored_in_file* true here will force this datablock to store its data
|
9
|
+
# @param data [#to_gnuplot_points] anything with #to_gnuplot_points method
|
10
|
+
# @param stored_in_file [Boolean] true here will force this datablock to store its data
|
13
11
|
# in temporary file.
|
14
12
|
def initialize(data, stored_in_file = false)
|
15
13
|
@stored_in_file = stored_in_file
|
@@ -25,12 +23,32 @@ module GnuplotRB
|
|
25
23
|
end
|
26
24
|
|
27
25
|
##
|
28
|
-
# ====== Overview
|
29
26
|
# Instantiate one more Datablock with updated data
|
30
27
|
# if data stored in here-doc. Append update to file
|
31
28
|
# if data stored there.
|
32
|
-
#
|
33
|
-
#
|
29
|
+
#
|
30
|
+
# @param data [#to_gnuplot_points] anything with #to_gnuplot_points method
|
31
|
+
# @return [Datablock] self if data stored in file (see constructor)
|
32
|
+
# @return [Datablock] new datablock with updated data otherwise
|
33
|
+
#
|
34
|
+
# @example
|
35
|
+
# data = [[0, 1, 2, 3], [0, 1, 4, 9]] # y = x**2
|
36
|
+
# db = Datablock.new(data, false)
|
37
|
+
# update = [[4, 5], [16, 25]]
|
38
|
+
# updated_db = db.update(update)
|
39
|
+
# # now db and updated_db contain DIFFERENT data
|
40
|
+
# # db - points with x from 0 up to 3
|
41
|
+
# # updated_db - points with x from 0 to 5
|
42
|
+
#
|
43
|
+
# @example
|
44
|
+
# data = [[0, 1, 2, 3], [0, 1, 4, 9]] # y = x**2
|
45
|
+
# db = Datablock.new(data, true)
|
46
|
+
# update = [[4, 5], [16, 25]]
|
47
|
+
# updated_db = db.update(update)
|
48
|
+
# # now db and updated_db contain THE SAME data
|
49
|
+
# # because they linked with the same temporary file
|
50
|
+
# # db - points with x from 0 up to 5
|
51
|
+
# # updated_db - points with x from 0 to 5
|
34
52
|
def update(data)
|
35
53
|
data_str = data.to_gnuplot_points
|
36
54
|
if @stored_in_file
|
@@ -42,10 +60,35 @@ module GnuplotRB
|
|
42
60
|
end
|
43
61
|
|
44
62
|
##
|
45
|
-
#
|
46
|
-
#
|
47
|
-
#
|
48
|
-
#
|
63
|
+
# Update existing Datablock with new data.
|
64
|
+
# Destructive version of #update.
|
65
|
+
#
|
66
|
+
# @param data [#to_gnuplot_points] anything with #to_gnuplot_points method
|
67
|
+
# @return [Datablock] self
|
68
|
+
#
|
69
|
+
# @example
|
70
|
+
# data = [[0, 1, 2, 3], [0, 1, 4, 9]] # y = x**2
|
71
|
+
# db = Datablock.new(data, false)
|
72
|
+
# update = [[4, 5], [16, 25]]
|
73
|
+
# db.update!(update)
|
74
|
+
# # now db contains points with x from 0 up to 5
|
75
|
+
def update!(data)
|
76
|
+
data_str = data.to_gnuplot_points
|
77
|
+
if @stored_in_file
|
78
|
+
File.open(@file_name, 'a') { |f| f.puts "\n#{data_str}" }
|
79
|
+
else
|
80
|
+
@data = "#{@data}\n#{data_str}"
|
81
|
+
end
|
82
|
+
self
|
83
|
+
end
|
84
|
+
|
85
|
+
##
|
86
|
+
# Get quoted filename if datablock stored in file or output
|
87
|
+
# datablock to gnuplot and return its name otherwise.
|
88
|
+
#
|
89
|
+
# @param gnuplot_term [Terminal] should be given if datablock not stored in file
|
90
|
+
# @return [String] quoted filename if data stored in file (see contructor)
|
91
|
+
# @return [String] Gnuplot's datablock name otherwise
|
49
92
|
def name(gnuplot_term = nil)
|
50
93
|
if @stored_in_file
|
51
94
|
"'#{@file_name}'"
|
@@ -58,7 +101,6 @@ module GnuplotRB
|
|
58
101
|
alias_method :to_s, :name
|
59
102
|
|
60
103
|
##
|
61
|
-
# ====== Overview
|
62
104
|
# Overridden #clone. Since datablock which store data
|
63
105
|
# in temporary files should not be cloned (otherwise it will cause
|
64
106
|
# double attempt to delete file), this #clone returns self for such
|
@@ -1,9 +1,22 @@
|
|
1
1
|
module GnuplotRB
|
2
2
|
##
|
3
|
-
# === Overview
|
4
3
|
# Dataset keeps control of Datablock or String (some math functions like
|
5
4
|
# this 'x*sin(x)' or filename) and options related to original dataset
|
6
5
|
# in gnuplot (with, title, using etc).
|
6
|
+
#
|
7
|
+
# == Options
|
8
|
+
# Dataset options are explained in
|
9
|
+
# {gnuplot docs}[http://www.gnuplot.info/docs_5.0/gnuplot.pdf] (pp. 80-101).
|
10
|
+
# Several common options:
|
11
|
+
# * with - set plot style for dataset ('lines', 'points', 'impulses' etc)
|
12
|
+
# * using - choose which columns of input data gnuplot should use. Takes String
|
13
|
+
# (using: 'xtic(1):2:3'). If Daru::Dataframe passed one can use column names
|
14
|
+
# instead of numbers (using: 'index:value1:summ' - value1 and summ here are column names).
|
15
|
+
# * linewidth (lw) - integer line width
|
16
|
+
# * dashtype (dt) - takes pattern with dash style. Examples: '.. ', '-- ', '.- '.
|
17
|
+
# * pointtype (pt) - takes integer number of point type (works only when :with option is set to
|
18
|
+
# 'points'). One can call Terminal::test(term_name)
|
19
|
+
# or Terminal#test in order to see which point types are supported by terminal.
|
7
20
|
class Dataset
|
8
21
|
include Plottable
|
9
22
|
##
|
@@ -14,6 +27,8 @@ module GnuplotRB
|
|
14
27
|
# Order is significant for some options
|
15
28
|
OPTION_ORDER = %w(index using axes title)
|
16
29
|
|
30
|
+
private_constant :OPTION_ORDER
|
31
|
+
|
17
32
|
##
|
18
33
|
# Hash of init handlers for data given in
|
19
34
|
# different containers.
|
@@ -27,27 +42,25 @@ module GnuplotRB
|
|
27
42
|
) if defined? Daru
|
28
43
|
|
29
44
|
##
|
30
|
-
#
|
31
|
-
#
|
32
|
-
#
|
33
|
-
#
|
34
|
-
#
|
35
|
-
#
|
36
|
-
#
|
37
|
-
#
|
38
|
-
#
|
39
|
-
#
|
40
|
-
# ====== Examples
|
41
|
-
# Math function:
|
45
|
+
# Create new dataset out of given string with math function or filename.
|
46
|
+
# If *data* isn't a string it will create datablock to store data.
|
47
|
+
#
|
48
|
+
# @param data [String, Datablock, #to_gnuplot_points] String, Datablock or something acceptable
|
49
|
+
# by Datablock.new as data (e.g. [x,y] where x and y are arrays)
|
50
|
+
# @param options [Hash] options specific for gnuplot
|
51
|
+
# dataset (see Dataset top level doc), and some special options ('file: true' will
|
52
|
+
# make data to be stored inside temporary file)
|
53
|
+
#
|
54
|
+
# @example Math function:
|
42
55
|
# Dataset.new('x*sin(x)', with: 'lines', lw: 4)
|
43
|
-
# File with points:
|
56
|
+
# @example File with points:
|
44
57
|
# Dataset.new('points.data', with: 'lines', title: 'Points from file')
|
45
|
-
# Some data (creates datablock stored in memory):
|
58
|
+
# @example Some data (creates datablock stored in memory):
|
46
59
|
# x = (0..5000).to_a
|
47
60
|
# y = x.map {|xx| xx*xx }
|
48
61
|
# points = [x, y]
|
49
62
|
# Dataset.new(points, with: 'points', title: 'Points')
|
50
|
-
# The same data but datablock stores it in temp file:
|
63
|
+
# @example The same data but datablock stores it in temp file:
|
51
64
|
# Dataset.new(points, with: 'points', title: 'Points', file: true)
|
52
65
|
def initialize(data, **options)
|
53
66
|
# run method by name
|
@@ -55,42 +68,49 @@ module GnuplotRB
|
|
55
68
|
end
|
56
69
|
|
57
70
|
##
|
58
|
-
#
|
59
|
-
#
|
60
|
-
#
|
61
|
-
# * *terminal* - must be given if data given as Datablock and
|
71
|
+
# Convert Dataset to string containing gnuplot dataset.
|
72
|
+
#
|
73
|
+
# @param terminal [Terminal] must be given if data given as Datablock and
|
62
74
|
# it does not use temp file so data should be piped out
|
63
|
-
# to gnuplot via terminal before use
|
64
|
-
#
|
75
|
+
# to gnuplot via terminal before use
|
76
|
+
# @param :without_options [Boolean] do not add options to dataset if set
|
77
|
+
# to true. Used by Fit::fit
|
78
|
+
# @return [String] gnuplot dataset
|
79
|
+
# @example
|
65
80
|
# Dataset.new('points.data', with: 'lines', title: 'Points from file').to_s
|
66
|
-
# #=> "'points.data' with lines title 'Points
|
81
|
+
# #=> "'points.data' with lines title 'Points from file'"
|
67
82
|
# Dataset.new(points, with: 'points', title: 'Points').to_s
|
68
83
|
# #=> "$DATA1 with points title 'Points'"
|
69
|
-
def to_s(terminal = nil)
|
70
|
-
"#{@type == :datablock ? @data.name(terminal) : @data}
|
84
|
+
def to_s(terminal = nil, without_options: false)
|
85
|
+
result = "#{@type == :datablock ? @data.name(terminal) : @data} "
|
86
|
+
result += options_to_string unless without_options
|
87
|
+
result
|
71
88
|
end
|
72
89
|
|
73
90
|
##
|
74
|
-
#
|
75
|
-
#
|
76
|
-
# data is appended to existing
|
91
|
+
# Create new dataset with updated data and merged options.
|
92
|
+
#
|
93
|
+
# Given data is appended to existing.
|
77
94
|
# Data is updated only if Dataset stores it in Datablock.
|
78
95
|
# Method does nothing if no options given and data isn't stored
|
79
96
|
# in in-memory Datablock.
|
80
|
-
#
|
81
|
-
#
|
82
|
-
#
|
83
|
-
#
|
84
|
-
#
|
97
|
+
#
|
98
|
+
# @param data [#to_gnuplot_points] data to append to existing
|
99
|
+
# @param options [Hash] new options to merge with existing options
|
100
|
+
# @return self if dataset corresponds to math formula or file
|
101
|
+
# (filename or temporary file if datablock)
|
102
|
+
# @return [Dataset] new dataset if data is stored in 'in-memory' Datablock
|
103
|
+
# @example Updating dataset with Math formula or filename given:
|
85
104
|
# dataset = Dataset.new('file.data')
|
86
105
|
# dataset.update(data: 'asd')
|
87
106
|
# #=> nothing updated
|
88
107
|
# dataset.update(data: 'asd', title: 'File')
|
89
108
|
# #=> Dataset.new('file.data', title: 'File')
|
90
|
-
# Updating dataset with data stored in Datablock:
|
109
|
+
# @example Updating dataset with data stored in Datablock (in-memory):
|
91
110
|
# in_memory_points = Dataset.new(points, title: 'Old one')
|
92
111
|
# in_memory_points.update(data: some_update, title: 'Updated')
|
93
112
|
# #=> Dataset.new(points + some_update, title: 'Updated')
|
113
|
+
# @example Updating dataset with data stored in Datablock (in-file):
|
94
114
|
# temp_file_points = Dataset.new(points, title: 'Old one', file: true)
|
95
115
|
# temp_file_points.update(data: some_update)
|
96
116
|
# #=> data updated but no new dataset created
|
@@ -110,7 +130,43 @@ module GnuplotRB
|
|
110
130
|
end
|
111
131
|
|
112
132
|
##
|
113
|
-
#
|
133
|
+
# Update Dataset with new data and options.
|
134
|
+
#
|
135
|
+
# Given data is appended to existing.
|
136
|
+
# Data is updated only if Dataset stores it in Datablock.
|
137
|
+
# Method does nothing if no options given and data isn't stored
|
138
|
+
# in in-memory Datablock.
|
139
|
+
#
|
140
|
+
# @param data [#to_gnuplot_points] data to append to existing
|
141
|
+
# @param options [Hash] new options to merge with existing options
|
142
|
+
# @return self
|
143
|
+
# @example Updating dataset with Math formula or filename given:
|
144
|
+
# dataset = Dataset.new('file.data')
|
145
|
+
# dataset.update!(data: 'asd')
|
146
|
+
# #=> nothing updated
|
147
|
+
# dataset.update!(data: 'asd', title: 'File')
|
148
|
+
# dataset.title
|
149
|
+
# #=> 'File' # data isn't updated
|
150
|
+
# @example Updating dataset with data stored in Datablock (in-memory):
|
151
|
+
# in_memory_points = Dataset.new(points, title: 'Old one')
|
152
|
+
# in_memory_points.update!(data: some_update, title: 'Updated')
|
153
|
+
# in_memory_points.data
|
154
|
+
# #=> points + some_update
|
155
|
+
# in_memory_points.title
|
156
|
+
# #=> 'Updated'
|
157
|
+
# @example Updating dataset with data stored in Datablock (in-file):
|
158
|
+
# temp_file_points = Dataset.new(points, title: 'Old one', file: true)
|
159
|
+
# temp_file_points.update!(data: some_update)
|
160
|
+
# #=> data updated but no new dataset created
|
161
|
+
# temp_file_points.update!(data: some_update, title: 'Updated')
|
162
|
+
# #=> data and options updated
|
163
|
+
def update!(data = nil, **options)
|
164
|
+
@data.update!(data) if data
|
165
|
+
options!(options)
|
166
|
+
self
|
167
|
+
end
|
168
|
+
|
169
|
+
##
|
114
170
|
# Own implementation of #clone. Creates new Dataset if
|
115
171
|
# data stored in datablock and calls super otherwise.
|
116
172
|
def clone
|
@@ -122,11 +178,13 @@ module GnuplotRB
|
|
122
178
|
end
|
123
179
|
|
124
180
|
##
|
125
|
-
#
|
126
|
-
# Creates new Plot object with only one Dataset given - self.
|
181
|
+
# Create new Plot object with only one Dataset given - self.
|
127
182
|
# Calls #plot on created Plot. All arguments given to this #plot
|
128
183
|
# will be sent to Plot#plot instead.
|
129
|
-
#
|
184
|
+
# @param args sequence of arguments all of which will be passed to Plot#plot,
|
185
|
+
# see docs there
|
186
|
+
# @return [Plot] new Plot object with only one Dataset - self
|
187
|
+
# @example
|
130
188
|
# sin = Dataset.new('sin(x)')
|
131
189
|
# sin.plot(term: [qt, size: [300, 300]])
|
132
190
|
# #=> shows qt window 300x300 with sin(x)
|
@@ -139,13 +197,13 @@ module GnuplotRB
|
|
139
197
|
private
|
140
198
|
|
141
199
|
##
|
142
|
-
#
|
143
|
-
# Creates new dataset with existing options merged with
|
200
|
+
# Create new dataset with existing options merged with
|
144
201
|
# the given ones. Does nothing if no options given.
|
145
|
-
#
|
146
|
-
#
|
147
|
-
#
|
148
|
-
#
|
202
|
+
#
|
203
|
+
# @param options [Hash] new options to merge with existing options
|
204
|
+
# @return [Dataset] self if options empty
|
205
|
+
# @return [Dataset] new Dataset with updated options otherwise
|
206
|
+
# @example Updating dataset with Math formula or filename given:
|
149
207
|
# dataset = Dataset.new('file.data')
|
150
208
|
# dataset.update_options(title: 'File')
|
151
209
|
# #=> Dataset.new('file.data', title: 'File')
|
@@ -158,8 +216,8 @@ module GnuplotRB
|
|
158
216
|
end
|
159
217
|
|
160
218
|
##
|
161
|
-
# ====== Overview
|
162
219
|
# Create string from own options
|
220
|
+
# @return [String] options converted to Gnuplot format
|
163
221
|
def options_to_string
|
164
222
|
options.sort_by { |key, _| OPTION_ORDER.find_index(key.to_s) || 999 }
|
165
223
|
.map { |key, value| OptionHandling.option_to_string(key, value) }
|
@@ -167,23 +225,28 @@ module GnuplotRB
|
|
167
225
|
end
|
168
226
|
|
169
227
|
##
|
170
|
-
# Needed by OptionHandling to create new object when
|
171
|
-
# options are changed.
|
228
|
+
# Needed by OptionHandling to create new object when options are changed.
|
172
229
|
def new_with_options(options)
|
173
230
|
self.class.new(@data, options)
|
174
231
|
end
|
175
232
|
|
233
|
+
##
|
234
|
+
# Initialize Dataset from given String
|
176
235
|
def init_string(data, options)
|
177
236
|
@type, @data = File.exist?(data) ? [:datafile, "'#{data}'"] : [:math_function, data.clone]
|
178
237
|
@options = Hamster.hash(options)
|
179
238
|
end
|
180
239
|
|
240
|
+
##
|
241
|
+
# Initialize Dataset from given Datablock
|
181
242
|
def init_dblock(data, options)
|
182
243
|
@type = :datablock
|
183
244
|
@data = data.clone
|
184
245
|
@options = Hamster.hash(options)
|
185
246
|
end
|
186
247
|
|
248
|
+
##
|
249
|
+
# Create new value for 'using' option based on column count
|
187
250
|
def get_daru_columns(data, cnt)
|
188
251
|
new_opt = (2..cnt).to_a.join(':')
|
189
252
|
if data.index[0].is_a?(DateTime) || data.index[0].is_a?(Numeric)
|
@@ -193,6 +256,8 @@ module GnuplotRB
|
|
193
256
|
end
|
194
257
|
end
|
195
258
|
|
259
|
+
##
|
260
|
+
# Initialize Dataset from given Daru::DataFrame
|
196
261
|
def init_daru_frame(data, options)
|
197
262
|
options[:title] ||= data.name
|
198
263
|
if options[:using]
|
@@ -202,19 +267,24 @@ module GnuplotRB
|
|
202
267
|
"#{Regexp.last_match(1)}#{array_index + 2}#{Regexp.last_match(2)}"
|
203
268
|
end
|
204
269
|
end
|
205
|
-
options[:using].gsub!('index', '1')
|
270
|
+
options[:using].gsub!('index', '1')
|
271
|
+
options[:using].strip!
|
206
272
|
else
|
207
273
|
options[:using] = get_daru_columns(data, data.vectors.size + 1)
|
208
274
|
end
|
209
275
|
init_default(data, options)
|
210
276
|
end
|
211
277
|
|
278
|
+
##
|
279
|
+
# Initialize Dataset from given Daru::Vector
|
212
280
|
def init_daru_vector(data, options)
|
213
281
|
options[:using] ||= get_daru_columns(data, 2)
|
214
282
|
options[:title] ||= data.name
|
215
283
|
init_default(data, options)
|
216
284
|
end
|
217
285
|
|
286
|
+
##
|
287
|
+
# Initialize Dataset from given data with #to_gnuplot_points method
|
218
288
|
def init_default(data, file: false, **options)
|
219
289
|
@type = :datablock
|
220
290
|
@data = Datablock.new(data, file)
|