graphkit 0.4.4 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 42653b3bfef9d5da9909f41a0e1479ac6c8fe81f
4
- data.tar.gz: 43c78a693b7d77be9e8e5dbe9faf9c4ec46aa82d
3
+ metadata.gz: 040f0f9ed1623e873447df38aa1ae23d73e16c62
4
+ data.tar.gz: cd7cbaf8050afa54a55e1cefce4e38a9db00b535
5
5
  SHA512:
6
- metadata.gz: a53fa37e5e9fe34502cb2b720dfb64bfd79e942c1d25e3b2b9f3309e49327a165e8a9109d6a284d245faabd8503a68091d3d8bea0b5fb6430d7dc8e54bd96c12
7
- data.tar.gz: ffa158ec4f3af1ed8436d25de0a6dbdb294d5e1540994af618193742c6d8b39d5981dffbb59b89e7dab8dfe34f035d37c29adffaa11714aeb21ac3cc405b31a9
6
+ metadata.gz: 4e35603a343c141f67c25368e2e028de736ff2d560cb53864373bc137bb5f547c150d13103403d108df739dff14db2280e449a1fe825c7671e9115aaf7a12c49
7
+ data.tar.gz: d1ccb0f78bbf11e7a54a7283eec2309f72124bf66f3bd550303a2a784dc93388461c5242efaa4ffdd63c45ebac53f97c98cd2d958fdaa2f32405bbea50110ce6
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.4
1
+ 0.5.0
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: graphkit 0.4.4 ruby lib
5
+ # stub: graphkit 0.5.0 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "graphkit"
9
- s.version = "0.4.4"
9
+ s.version = "0.5.0"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib"]
13
13
  s.authors = ["Edmund Highcock"]
14
- s.date = "2016-01-19"
14
+ s.date = "2016-03-08"
15
15
  s.description = "A GraphKit is a device independent intelligent data container that allows the easy sharing, combining and plotting of graphic data representations. Easily created from data, they can be output in a variety of formats using packages such as gnuplot. "
16
16
  s.email = "edmundhighcock@sourceforge.net"
17
17
  s.extra_rdoc_files = [
@@ -39,7 +39,7 @@ Gem::Specification.new do |s|
39
39
  s.homepage = "http://github.com/edmundhighcock/graphkit"
40
40
  s.licenses = ["GPLv3"]
41
41
  s.required_ruby_version = Gem::Requirement.new(">= 1.9.1")
42
- s.rubygems_version = "2.2.2"
42
+ s.rubygems_version = "2.4.8"
43
43
  s.summary = "A GraphKit is a device independent intelligent data container for generating and plotting graphs."
44
44
 
45
45
  if s.respond_to? :specification_version then
@@ -1,4 +1,4 @@
1
- script_folder = File.dirname(File.expand_path(__FILE__))
1
+ # script_folder = File.dirname(File.expand_path(__FILE__))
2
2
 
3
3
  require 'pp'
4
4
  require 'rubyhacks'
@@ -40,29 +40,29 @@ end
40
40
  class SparseTensor < Hash
41
41
  class RankError < StandardError
42
42
  end
43
-
43
+
44
44
  # class Key < Array
45
45
  # def ==
46
- #
46
+ #
47
47
  # end
48
-
49
-
48
+
49
+
50
50
  attr_reader :rank, :shape
51
51
  #attr_accessor :default_val
52
-
52
+
53
53
  # Create a new tensor.
54
-
54
+
55
55
  def initialize(rank = 2)
56
56
  @rank = rank
57
57
  @shape = [0]*rank
58
58
  super()
59
59
  end
60
-
61
- # Create a new diagonal tensor from an array. E.g. if rank was 2, then
60
+
61
+ # Create a new diagonal tensor from an array. E.g. if rank was 2, then
62
62
  # tensor[0,0] = array[0]
63
63
  # tensor[1,1] = array[1]
64
64
  # Etc.
65
-
65
+
66
66
  def self.diagonal(rank, array)
67
67
  tensor = new(rank)
68
68
  for index in 0...array.size
@@ -70,11 +70,11 @@ class SparseTensor < Hash
70
70
  end
71
71
  tensor
72
72
  end
73
-
73
+
74
74
  # Access an element of the tensor. E.g. for a rank 2 tensor
75
75
  #
76
76
  # a = tensor[1,3]
77
-
77
+
78
78
  def [](*args)
79
79
  args = args[0] if args.size == 1 and not args.size == @rank and args[0].size == @rank
80
80
  # p args
@@ -91,11 +91,11 @@ class SparseTensor < Hash
91
91
  #end
92
92
 
93
93
  end
94
-
94
+
95
95
  # Set an element of the tensor. E.g. for a rank 2 tensor
96
96
  #
97
97
  # tensor[1,3] = a_variable
98
-
98
+
99
99
  def []=(*args)
100
100
  value = args.pop
101
101
  args = args[0] if args.size == 1 and args[0].size == @rank
@@ -105,18 +105,18 @@ class SparseTensor < Hash
105
105
  end
106
106
  super(args, value)
107
107
  end
108
-
108
+
109
109
  # Perform some action involving all the elements of this tensor and another.
110
- #
110
+ #
111
111
  # E.g.
112
112
  # tensor_1.scalar_binary(tensor_2) do |element_1, element_2|
113
113
  # element_1 + element_2
114
114
  # end
115
115
  #
116
116
  # will add every element of tensor_1 to every corresponding element of tensor_2.
117
-
118
-
119
-
117
+
118
+
119
+
120
120
  def scalar_binary(other, &block)
121
121
  raise ArgumentError unless other.class == self.class
122
122
  raise RankError.new("Different ranks: #@rank, #{other.rank}") unless other.rank == @rank
@@ -138,21 +138,21 @@ class SparseTensor < Hash
138
138
  def -(other)
139
139
  scalar_binary(other){|a, b| a - b}
140
140
  end
141
-
141
+
142
142
  # Find the maximum element of the tensor. See Enumerable#max.
143
-
143
+
144
144
  def max(&block)
145
145
  return self.values.max(&block)
146
146
  end
147
-
147
+
148
148
  # Find the minimum element of the tensor. See Enumerable#max.
149
-
149
+
150
150
  def min(&block)
151
151
  return self.values.min(&block)
152
152
  end
153
153
 
154
154
 
155
-
155
+
156
156
  def alter!(&block)
157
157
  self.keys.each do |k|
158
158
  self[k] = yield(self[k])
@@ -170,17 +170,17 @@ class SparseTensor < Hash
170
170
 
171
171
  end
172
172
 
173
-
174
-
173
+
174
+
175
175
 
176
176
  # To be mixed in to a Hash. Basically allows access the elements of a hash via method names rather than brackets.
177
177
 
178
178
 
179
179
  module Kit
180
-
180
+
181
181
  class IntegrityError < StandardError
182
182
  end
183
-
183
+
184
184
  def method_missing(method, *args)
185
185
  # p method, args
186
186
  m = method.to_s
@@ -193,10 +193,10 @@ module Kit
193
193
  return send(method)
194
194
  end
195
195
  end
196
-
196
+
197
197
  def check(*values, &block)
198
198
  values.each do |arr|
199
- case arr.size
199
+ case arr.size
200
200
  when 2
201
201
  expression, test_data = arr
202
202
  if block
@@ -218,11 +218,11 @@ module Kit
218
218
  end
219
219
  end
220
220
  end
221
-
222
-
223
-
224
221
 
225
-
222
+
223
+
224
+
225
+
226
226
  end
227
227
 
228
228
  # See Kit
@@ -251,26 +251,26 @@ end
251
251
  # GraphKit also allows you access any property, e.g. title, as
252
252
  #
253
253
  # graphkit.title
254
- #
255
- # graphkit.title =
254
+ #
255
+ # graphkit.title =
256
256
  #
257
257
  # as well as the hash form:
258
258
  #
259
259
  # graphkit[:title]
260
260
  # graphkit[:title] =
261
- #
261
+ #
262
262
  # GraphKits have methods which allow the graphs to be rendered using standard visualisation packages. At present only gnuplot is supported, but others are planned.
263
263
  #
264
264
  # GraphKits overload certain operators, for example <tt>+</tt>, which mean that they can be combined easily and intuitively. This makes plotting graphs from different sets of results on the same page as easy as adding 2+2!
265
- #
265
+ #
266
266
  # GraphKits define a minimum set of keys which are guaranteed to be meaningful and work on all platforms. If you stick to using just these properties, you'll be able to easily plot basic graphs. If you need more control and customisation, you need to look at the documentation both for the visualisation package (e.g. gnuplot) and the module which allows a GraphKit to interface with that package (e.g. GraphKit::Gnuplot).
267
267
  #
268
268
  # Here is the specification for the standard keys:
269
- #
269
+ #
270
270
  # * title (String): the title of the graph
271
271
  # * xlabel, ylabel, zlabel (String): axis labels
272
272
  # * xrange, yrange, zrange, frange (Array): ranges of the three dimensions and possibly the function as well.
273
- # * data (Array of GraphKit::DataKits): the lines of data to be plotted.
273
+ # * data (Array of GraphKit::DataKits): the lines of data to be plotted.
274
274
 
275
275
 
276
276
  class GraphKit < KitHash
@@ -290,7 +290,7 @@ class GraphKit < KitHash
290
290
  self[i] += other[i] if other[i]
291
291
  end
292
292
  self
293
- end
293
+ end
294
294
 
295
295
  def +(other)
296
296
  merge(other)
@@ -304,8 +304,8 @@ class GraphKit < KitHash
304
304
  end
305
305
  MultiWindow = MultiKit # Backwards compatibility
306
306
 
307
-
308
-
307
+
308
+
309
309
  include Kit
310
310
  include Log
311
311
  AXES = [:x, :y, :z, :f]
@@ -313,73 +313,73 @@ class GraphKit < KitHash
313
313
  DEFAULT_COLOURS_GNUPLOT = DEFAULT_COLOURS
314
314
  DEFAULT_COLOURS_MATHEMATICA = DEFAULT_COLOURS.inject({}) do |hash, (i, coll)|
315
315
  hash[i] = coll.sub(/#/, '').scan(/.{2}/).map{|str| (eval("0x#{str}").to_f / 255.0).round(2)}
316
- hash
316
+ hash
317
317
  end
318
318
 
319
319
  # attr_reader :gnuplot_options
320
-
320
+
321
321
  alias :hash_key :key
322
322
  undef :key
323
-
323
+
324
324
  # Greate a new graphkit. Rarely used: see GraphKit.autocreate and GraphKit.quick_create
325
-
325
+
326
326
  def initialize(naxes=0, hash = {})
327
327
  logf :initialize
328
328
  super()
329
- self[:naxes] = naxes
329
+ self[:naxes] = naxes
330
330
  self[:data] = []
331
331
  hash
332
332
  # @gnuplot_options = GnuplotOptions.new
333
333
  end
334
-
334
+
335
335
  # def gnuplot_options
336
336
  # @gnuplot_options ||= GnuplotOptions.new
337
337
  # @gnuplot_options
338
338
  # end
339
-
339
+
340
340
  # alias :gp :gnuplot_options
341
-
341
+
342
342
  class DataError < StandardError
343
343
  end
344
-
344
+
345
345
  # Create a new graphkit with one hash for every datakit (each datakit corresponds to a line or surface on the graph). Each hash should contain specifications for the axes of the graph (see AxisKit#autocreate).
346
346
  #
347
347
  # E.g.
348
348
  # kit = GraphKit.autocreate(
349
349
  # {
350
- # x: {data: [1,2,3], title 'x', units: 'm'},
350
+ # x: {data: [1,2,3], title 'x', units: 'm'},
351
351
  # y: {data: [1,4,9], title 'x^2', units: 'm^2'}
352
352
  # }
353
353
  # )
354
354
  #
355
355
  # will create a two dimensional graph that plots x^2 against x.
356
-
356
+
357
357
  def self.autocreate(*hashes)
358
358
  Log.logf :autocreate
359
359
  new(hashes[0].size).autocreate(*hashes)
360
360
  end
361
-
362
-
361
+
362
+
363
363
  def lx(*args) # :nodoc:
364
364
  log_axis(*args)
365
365
  end
366
-
366
+
367
367
  def lx=(val) # :nodoc: (deprecated)
368
368
  self.log_axis = val
369
369
  end
370
-
370
+
371
371
  # Create a new graphkit without providing any labels.
372
372
  #
373
373
  # E.g.
374
374
  # kit = GraphKit.quick_create(
375
375
  # [
376
- # [1,2,3],
376
+ # [1,2,3],
377
377
  # [1,4,9]
378
378
  # ]
379
379
  # )
380
380
  #
381
381
  # will create a two dimensional graph that plots x^2 against x.
382
-
382
+
383
383
  def self.quick_create(*datasets)
384
384
  hashes = datasets.map do |data|
385
385
  hash = {}
@@ -390,14 +390,14 @@ class GraphKit < KitHash
390
390
  end
391
391
  autocreate(*hashes)
392
392
  end
393
-
394
-
395
-
393
+
394
+
395
+
396
396
  def autocreate(*hashes) # :nodoc: (see GraphKit.autocreate)
397
397
  logf :autocreate
398
398
  hashes.each{|hash| data.push DataKit.autocreate(hash)}
399
399
  # pp data
400
- [:title, :label, :units, :range].each do |option|
400
+ [:title, :label, :units, :range].each do |option|
401
401
  data[0].axes.each do |key, axiskit|
402
402
  # next unless AXES.include? key
403
403
  self[key + option] = axiskit[option].dup if axiskit[option]
@@ -407,9 +407,9 @@ class GraphKit < KitHash
407
407
  check_integrity
408
408
  self
409
409
  end
410
-
410
+
411
411
  # Check that the graphkit conforms to specification; that the data has dimensions that make sense and that the titles and ranges have the right types.
412
-
412
+
413
413
  def check_integrity
414
414
  logf :check_integrity
415
415
  check(['data.class', Array], ['title.class', [String, NilClass]], ['has_legend.class', [Hash, NilClass]])
@@ -420,7 +420,7 @@ class GraphKit < KitHash
420
420
  # p instance_eval(prop.to_s + "[#{key.inspect}]"), 'ebb'
421
421
  check(["#{key + prop}.class", klass])
422
422
  # check(["a key from #{prop}", key, AXES + [:f]])
423
- end
423
+ end
424
424
  end
425
425
  data.each do |datakit|
426
426
  check(['class of a member of the data array', datakit.class, DataKit])
@@ -429,28 +429,28 @@ class GraphKit < KitHash
429
429
  end
430
430
  return true
431
431
  end
432
-
432
+
433
433
  # AXES.each do |axisname|
434
434
  # [:name, :label, :units, :range].each do |option|
435
435
  # define_method(axisname + option){self[option][axisname]}
436
436
  # define_method(axisname + option + '='.to_sym){|value| self[option][axisname] = value}
437
437
  # end
438
438
  # end
439
-
439
+
440
440
  @@old_gnuplot_sets = [ :dgrid3d, :title, :style, :term, :terminal, :pointsize, :log_axis, :key, :pm3d, :palette, :view, :cbrange, :contour, :nosurface, :cntrparam, :preamble, :xtics, :ytics]
441
-
442
-
441
+
442
+
443
443
  # @@gnuplot_sets.uniq!
444
-
444
+
445
445
  # Duplicate the graphkit.
446
-
446
+
447
447
  def dup
448
448
  #logf :dup
449
449
  #self.class.new(naxes, self)
450
450
  eval(inspect)
451
451
  end
452
-
453
- # Combine with another graph; titles and labels from the first graph will override the second.
452
+
453
+ # Combine with another graph; titles and labels from the first graph will override the second.
454
454
 
455
455
  def +(other)
456
456
  check(['other.naxes', other.naxes, self.naxes])
@@ -460,7 +460,7 @@ class GraphKit < KitHash
460
460
  new.data = self.data + other.data
461
461
  new
462
462
  end
463
-
463
+
464
464
  def extend_using(other, mapping = nil)
465
465
  if mapping
466
466
  mapping.each do |mine, others|
@@ -473,7 +473,7 @@ class GraphKit < KitHash
473
473
  end
474
474
  end
475
475
  end
476
-
476
+
477
477
  def each_axiskit(*axes, &block)
478
478
  axes = AXES unless axes.size > 0
479
479
  axes.each do |axis|
@@ -495,7 +495,7 @@ class GraphKit < KitHash
495
495
  shapes
496
496
 
497
497
  end
498
-
498
+
499
499
  def transpose!
500
500
  data.each do |datakit|
501
501
  datakit.transpose!
@@ -503,7 +503,7 @@ class GraphKit < KitHash
503
503
  self.xlabel, self.ylabel = ylabel, xlabel
504
504
  self.xrange, self.yrange = xrange, yrange
505
505
  end
506
-
506
+
507
507
  def convert(&block)
508
508
  #ep 'Converting graph...'
509
509
  kit = self.dup
@@ -521,7 +521,7 @@ class GraphKit < KitHash
521
521
  # E.g. convert a line of values of [x, y, z] with rank [1,1,2]
522
522
  # to a matrix of values [x, y, z] with rank [1, 1, 2]
523
523
  # convert_rank!([[1,1,1], [1,1,2]])
524
-
524
+
525
525
  def convert_rank!(from_to, options={})
526
526
  ep "Converting Rank"
527
527
  case from_to
@@ -566,21 +566,21 @@ class DataKit < KitHash
566
566
  self.axes[:y].data=ynew
567
567
  #p 'dk', self
568
568
  self
569
-
569
+
570
570
  end
571
-
571
+
572
572
  # include Kit
573
573
  include Log
574
574
  AXES = GraphKit::AXES
575
- AXES.each{|ax| define_method(ax){self.axes[ax]}}
576
- AXES.each{|ax| define_method(ax + "=".to_sym){|val| self.axes[ax] = val}}
577
-
575
+ AXES.each{|ax| define_method(ax){self.axes[ax]}}
576
+ AXES.each{|ax| define_method(ax + "=".to_sym){|val| self.axes[ax] = val}}
577
+
578
578
  # attr_accessor :labels, :ranges, :has_legend, :units, :dimensions
579
-
580
579
 
581
- def axes_array
580
+
581
+ def axes_array
582
582
  self.axes.values_at(*AXES).compact
583
- end
583
+ end
584
584
  def initialize(options = {})
585
585
  super()
586
586
  self[:axes] = {}
@@ -590,14 +590,14 @@ class DataKit < KitHash
590
590
  def self.autocreate(hash)
591
591
  new.autocreate(hash)
592
592
  end
593
-
593
+
594
594
  def autocreate(hash)
595
595
  logf :autocreate
596
596
  hash.each do |key, value|
597
597
  # puts value.inspect
598
598
  if AXES.include? key
599
599
  self[:axes][key] = AxisKit.autocreate(value)
600
- else
600
+ else
601
601
  raise ArgumentError.new("bad key value pair in autocreate: #{key.inspect}, #{value.inspect}")
602
602
  end
603
603
  # puts self[key].inspect
@@ -611,7 +611,7 @@ class DataKit < KitHash
611
611
  check_integrity
612
612
  self
613
613
  end
614
-
614
+
615
615
  def check_integrity
616
616
  logf :check_integrity
617
617
  check(['title.class', [String, NilClass]], ['with.class', [String, NilClass]], ['axes.class', Hash])
@@ -626,7 +626,7 @@ class DataKit < KitHash
626
626
  # end
627
627
  # puts 'checking f.class', f.class
628
628
  # check(['f.class', CodeRunner::FunctionKit])
629
-
629
+
630
630
  # shape = f.shape
631
631
  log 'checking ranks'
632
632
  rnks = ranks
@@ -651,17 +651,17 @@ class DataKit < KitHash
651
651
  #end
652
652
  passed = false unless axes[:f].shape == [axes[:x].shape[0], axes[:y].shape[0], axes[:z].shape[0]]
653
653
  end
654
- raise IntegrityError.new(%[The dimensions of this data do not match: \n#{axes.inject(""){|str, (axis, axiskit)| str + "#{axis}: #{axiskit.shape}\n"}}\nranks: #{rnks}]) unless passed
654
+ raise IntegrityError.new(%[The dimensions of this data do not match: \n#{axes.inject(""){|str, (axis, axiskit)| str + "#{axis}: #{axiskit.shape}\n"}}\nranks: #{rnks}]) unless passed
655
655
  # log 'finished checking ranks'
656
656
  logfc :check_integrity
657
657
  # raise IntegrityError.new("function data must be a vector, or have the correct dimensions (or shape) for the axes: function dimensions: #{shape}; axes dimesions: #{axes_shape}") unless shape.size == 1 or axes_shape == shape
658
658
  return true
659
659
  end
660
-
660
+
661
661
  #ALLOWED_RANKS = [[1], [1,1], [1,1,1], [1,1,2], [1,1,1,1], [1,1,2,2], [1,1,1,3]]
662
662
  ALLOWED_RANKS = [[1], [1,1], [1,1,1], [1,1,2], [2,2,2], [2,2,2,2], [1,1,1,1], [1,1,2,2], [1,1,1,3], [3,3,3,3]]
663
663
 
664
- def allowed_ranks
664
+ def allowed_ranks
665
665
  ALLOWED_RANKS
666
666
  end
667
667
  #def ranks_c_switch_hash
@@ -678,13 +678,13 @@ class DataKit < KitHash
678
678
  logfc :shapes
679
679
  return ans
680
680
  end
681
-
681
+
682
682
  def rank_c_switch
683
683
  #i = -1
684
684
  #puts ALLOWED_RANKS.map{|r| i+=1;"#{i} --> #{r}"}
685
685
  switch = ALLOWED_RANKS.index(ranks)
686
686
  switch
687
-
687
+
688
688
  end
689
689
  def ranks
690
690
  logf :ranks
@@ -692,14 +692,14 @@ class DataKit < KitHash
692
692
  logfc :ranks
693
693
  return ans
694
694
  end
695
-
695
+
696
696
  def extend_using(other)
697
697
  raise "A dataset can only be extended using another dataset with the same ranks: the ranks of this dataset are #{ranks} and the ranks of the other dataset are #{other.ranks}" unless ranks == other.ranks
698
698
  axes.each do |key, axiskit|
699
699
  axiskit.extend_using(other.axes[key])
700
700
  end
701
701
  end
702
-
702
+
703
703
  # def gnuplot_ranks
704
704
  # case axes.size
705
705
  # when 1,2
@@ -715,7 +715,7 @@ class DataKit < KitHash
715
715
  # end
716
716
  # end
717
717
  # end
718
- #
718
+ #
719
719
  # def gnuplot
720
720
  # # p axes.values_at(*AXES).compact.zip(gnuplot_ranks)
721
721
  # Gnuplot::DataSet.new(axes.values_at(*AXES).compact.zip(gnuplot_ranks).map{|axis, rank| axis.data_for_gnuplot(rank) }) do |ds|
@@ -734,15 +734,15 @@ class DataKit < KitHash
734
734
  # # ds.linewidth = 4
735
735
  # end
736
736
  # end
737
- #
737
+ #
738
738
  # def gnuplot_options
739
739
  # @gnuplot_options ||= GnuplotPlotOptions.new
740
740
  # @gnuplot_options
741
741
  # end
742
- #
742
+ #
743
743
  # alias :gp :gnuplot_options
744
- #
745
-
744
+ #
745
+
746
746
  AXES.each do |axisname|
747
747
  define_method(axisname + :axis){self[:axes][axisname]}
748
748
  define_method(axisname + :axis + '='.to_sym){|value| self[:axes][axisname] = value}
@@ -782,7 +782,7 @@ class DataKit < KitHash
782
782
  if axes.size == 1
783
783
  data = axes[:x].data
784
784
  i = 0
785
- loop do
785
+ loop do
786
786
  break if i > data.size - 2
787
787
  should_be = (data[i+1] + data[i-1]) / 2.0
788
788
  deviation = (should_be - data[i]).abs / data[i].abs
@@ -796,9 +796,9 @@ class DataKit < KitHash
796
796
  x_data = axes[:x].data
797
797
  data = axes[:y].data
798
798
  i = 0
799
- loop do
799
+ loop do
800
800
  jump = 1
801
- loop do
801
+ loop do
802
802
  break if i > data.size - 1 - jump
803
803
  break unless x_data[i+jump] == x_data[i-jump]
804
804
  jump += 1
@@ -816,7 +816,7 @@ class DataKit < KitHash
816
816
  end
817
817
  # p self.outliers
818
818
  end
819
-
819
+
820
820
  # def exclude_outliers
821
821
  # raise "Can only get rid of outliers for 1D or 2D data" if axes.size > 2
822
822
  # # self.outliers = []
@@ -829,25 +829,25 @@ class DataKit < KitHash
829
829
  # axes[:x].data.delete_at(index)
830
830
  # axes[:y].data.delete_at(index)
831
831
  # end
832
- #
832
+ #
833
833
  # end
834
834
  # check_integrity
835
835
  # end
836
836
 
837
-
838
-
837
+
838
+
839
839
  end
840
840
 
841
841
 
842
842
  class AxisKit < KitHash
843
-
843
+
844
844
  # include Kit
845
845
  include Log
846
846
  AXES = GraphKit::AXES
847
847
 
848
-
848
+
849
849
  # attr_accessor :labels, :ranges, :has_legend, :units, :dimensions
850
-
850
+
851
851
  def initialize(hash = {})
852
852
  super()
853
853
  self.title = ""
@@ -855,25 +855,25 @@ class AxisKit < KitHash
855
855
  self.
856
856
  absorb hash
857
857
  end
858
-
858
+
859
859
  def check_integrity
860
860
  check(['units.class', [String]], ['scaling.class', [Float, NilClass]], ['label.class', [String, NilClass]], ['title.class', [String]])
861
861
  check(['data.to_a.class', Array])
862
862
  end
863
-
863
+
864
864
  def dup
865
865
  # puts 'i was called'
866
866
  new = self.class.new(self)
867
867
  new.data = data.dup
868
868
  new
869
869
  end
870
-
870
+
871
871
  def self.autocreate(hash)
872
872
  new_kit = new(hash)
873
873
  new_kit.label = "#{new_kit.title} (#{new_kit.units})"
874
874
  new_kit
875
875
  end
876
-
876
+
877
877
  def shape
878
878
  logf :shape
879
879
  if data.methods.include? :shape
@@ -902,7 +902,7 @@ class AxisKit < KitHash
902
902
  # raise TypeError("Bad Rank")
903
903
  # end
904
904
  # end
905
-
905
+
906
906
  def extend_using(other)
907
907
  raise TypeError.new("Can only extend axes if data have the same ranks: #{shape.size}, #{other.shape.size}") unless shape.size == other.shape.size
908
908
  raise TypeError.new("Can only extend axes if data have the same class") unless data.class == other.data.class
@@ -921,7 +921,7 @@ class AxisKit < KitHash
921
921
  raise TypeError("Extending data with this rank: #{shape.size} is currently not implemented.")
922
922
  end
923
923
  end
924
-
924
+
925
925
  end
926
926
 
927
927
  end # class GraphKit
@@ -938,6 +938,6 @@ if $0 == __FILE__
938
938
 
939
939
  end
940
940
 
941
-
941
+
942
942
  # A graph kit is 'everything you need..
943
943
  #A graph kit is, in fact, a very intelligent hash
@@ -2,9 +2,8 @@ require 'matrix'
2
2
  # Methods for writing graphkits to csv (comma separated value) files
3
3
 
4
4
  class GraphKit
5
- def to_csv(options={})
5
+ def to_csv(options={})
6
6
  check_integrity
7
- ep 'to_csv'
8
7
  stringio = options[:io] || StringIO.new
9
8
  data.each do |dk|
10
9
  dk.to_csv(options)
@@ -14,7 +13,7 @@ class GraphKit
14
13
  end
15
14
 
16
15
  class DataKit
17
- class TensorArray
16
+ class TensorArray
18
17
  def initialize(arr)
19
18
  @arr=arr
20
19
  end
@@ -26,21 +25,25 @@ class GraphKit
26
25
  end
27
26
  def to_csv(options={})
28
27
  io = options[:io] || StringIO.new
29
- header = options[:header].to_s
30
- csv_file = File.open(io, 'w')
31
- if header
28
+
29
+ if options[:append]
30
+ if File.exists?(io)
31
+ options[:header] = nil
32
+ end
33
+ csv_file = File.open(io, 'a')
34
+ else
35
+ csv_file = File.open(io, 'w')
36
+ end
37
+
38
+ unless options[:header].nil?
39
+ header = options[:header].to_s
32
40
  csv_file.write(header + "\n")
33
41
  end
34
42
 
35
43
  axs = self.axes.values_at(*AXES).compact
36
- #ep 'axs', axs
37
44
  dl = axs[-1].shape.product
38
45
  dat = axs.map{|ax| ax.data}
39
46
  sh = shapes
40
- #cml_sh = sh.map do |sh1|
41
- # cml = 1
42
- # sh1.reverse.map{|dim| cml *= dim; cml}.reverse
43
- #end
44
47
  dat = dat.map do |d|
45
48
  d.kind_of?(Array) ? TensorArray.new(d) : d
46
49
  end
@@ -48,13 +51,12 @@ class GraphKit
48
51
  if self.errors
49
52
  raise "Errors can only be plotted for 1D or 2D data" unless ranks == [1] or ranks == [1,1]
50
53
  edat = self.errors.values_at(:x, :xmin, :xmax, :y, :ymin, :ymax).compact
51
- #ep 'edat', edat
52
54
  end
53
55
 
54
56
  io = ''
55
57
  case ranks
56
58
  when [1], [1,1], [1,1,1], [1,1,1,1]
57
- dl.times do |n|
59
+ dl.times do |n|
58
60
  dat.each{|d| io << d[n].to_s << ","}
59
61
  io << " " << edat.map{|e| e[n].to_s}.join(", ") if self.errors
60
62
  io << "\n"
@@ -131,7 +133,7 @@ class GraphKit
131
133
  end
132
134
 
133
135
  return stringio.string unless options[:io]
134
-
136
+
135
137
  csv_file.write(io)
136
138
  csv_file.close()
137
139
  end
@@ -7,12 +7,8 @@ rescue Bundler::BundlerError => e
7
7
  $stderr.puts "Run `bundle install` to install missing gems"
8
8
  exit e.status_code
9
9
  end
10
- require 'test/unit'
11
- require 'shoulda'
10
+ require 'minitest/autorun'
12
11
 
13
12
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
14
13
  $LOAD_PATH.unshift(File.dirname(__FILE__))
15
14
  require 'graphkit'
16
-
17
- class Test::Unit::TestCase
18
- end
@@ -1,88 +1,101 @@
1
1
  require 'helper'
2
2
 
3
- class TestGraphkit < Test::Unit::TestCase
4
-
5
- def test_basic
6
- a = GraphKit.autocreate({x: {data: [1,3,5,6], units: 'feet', title: 'Height'}})
7
- #a.gnuplot
8
- #gets
9
- a.close
10
- a = GraphKit.autocreate({x: {data: [2, 5, 11, 22], units: 'years', title: 'Age'}, y: {data: [1,3,5,6], units: 'feet', title: 'Height'}})
11
-
12
- puts a.pretty_inspect
13
-
14
- p a.title
15
- p a.label
16
- p a.chox
17
- p a.xlabel
18
- p a.yunits
19
-
20
- # a.gnuplot
21
- # gets
22
- # a.close
23
- a.data[0].with = 'lp'
24
- datakit = a.data[0].dup
25
- datakit.axes[:y].data.map!{|value| value * 0.85}
26
- datakit.title += ' of women'
27
- a.data.push datakit
28
- a.data[0].title += ' of men'
29
- pp a
30
- #a.gnuplot
31
- #gets
32
- a.close
33
- # Gnuplot.open{a.to_gnuplot}
34
-
35
- b = GraphKit.autocreate({x: {data: [2, 5, 11, 22], units: 'years', title: 'Age'}, y: {data: [1,3,5,6], units: 'feet', title: 'Height'}, z: {data: [2,4,8,12], units: 'stone', title: 'Weight'}})
36
- b.data[0].modify({with: 'lp'})
37
- pp b
38
- # d = b.data[0].f.data_for_gnuplot(2)
39
- # p d
40
- # p d[0,1]
41
- # d.delete([0,0])
42
- # p d
43
- # p d[1,1]
44
- # p d[1,2]
45
- # d = SparseTensor.new(3)
46
- # p d
47
- # p d[0,1,4]
48
- # p d[3, 4,6]
49
- #
50
- #b.gnuplot
51
- #gets
52
- b.close
53
- b.gnuplot_write('heights.ps')
54
-
55
- p b.data[0].plot_area_size
56
-
57
- c = SparseTensor.new(3)
58
- c[1,3,9]= 4
59
- c[3,3,34] = 4.346
60
- c[23, 234, 293] = 9.234
61
-
62
- p c
63
-
64
- d = SparseTensor.new(3)
65
- d[1,3,9]= 4
66
- d[3,3,34] = 4.346
67
- d[23, 234, 294] = 9.234
68
-
69
- p c + d
70
-
71
- multiplot = GraphKit::MultiWindow.new
72
- multiplot.push a
73
- multiplot.push b
74
-
75
- multiplot2 = GraphKit::MultiKit.new([GraphKit.quick_create([[0,3], [2,4]])])
76
- multiplot.merge(multiplot2)
77
-
78
- p multiplot.inspect
79
- assert_equal(GraphKit::MultiKit, eval(multiplot.inspect).class )
80
-
81
-
82
- pp multiplot
83
-
84
- #multiplot.gnuplot
85
- multiplot.gnuplot_write('multiplot.ps', multiplot: 'layout 2,2')
86
- end
3
+ class TestGraphkit < Minitest::Unit::TestCase
4
+
5
+ def setup
6
+ FileUtils.makedirs('test/test_output')
7
+ end
8
+
9
+ def teardown
10
+ FileUtils.rm_r('test/test_output')
11
+ end
12
+
13
+ def test_to_csv_single_dk
14
+ a = GraphKit.autocreate({x: {data: [1,2,3]},
15
+ y: {data: [4,5,6]}})
16
+
17
+ a.to_csv({io:'test/test_output/csv_single_dk.csv'})
18
+
19
+ f = File.read('test/test_output/csv_single_dk.csv')
20
+ assert_equal(f, "1,4,\n2,5,\n3,6,\n")
21
+ end
22
+
23
+ def test_to_csv_single_dk_with_header
24
+ a = GraphKit.autocreate({x: {data: [1,2,3]},
25
+ y: {data: [4,5,6]}})
26
+
27
+ a.to_csv({io:'test/test_output/csv_single_dk_with_header.csv',
28
+ header:'test1, test2'})
29
+
30
+ f = File.read('test/test_output/csv_single_dk_with_header.csv')
31
+ assert_equal(f, "test1, test2\n1,4,\n2,5,\n3,6,\n")
32
+ end
33
+
34
+ def test_to_csv_append
35
+ a = GraphKit.autocreate({x: {data: [1]},
36
+ y: {data: [2]}})
37
+ b = GraphKit.autocreate({x: {data: [3]},
38
+ y: {data: [4]}})
39
+
40
+ a.to_csv({io:'test/test_output/csv_append.csv'})
41
+ b.to_csv({io:'test/test_output/csv_append.csv', append:true})
42
+
43
+ f = File.read('test/test_output/csv_append.csv')
44
+ assert_equal(f, "1,2,\n3,4,\n")
45
+ end
46
+
47
+ def test_to_csv_append_with_header
48
+ a = GraphKit.autocreate({x: {data: [1]},
49
+ y: {data: [2]}})
50
+ b = GraphKit.autocreate({x: {data: [3]},
51
+ y: {data: [4]}})
52
+
53
+ a.to_csv({io:'test/test_output/csv_append_with_header.csv',
54
+ header:'test1,test2'})
55
+ b.to_csv({io:'test/test_output/csv_append_with_header.csv',
56
+ header:'test1,test2', append:true})
57
+
58
+ f = File.read('test/test_output/csv_append_with_header.csv')
59
+ assert_equal(f, "test1,test2\n1,2,\n3,4,\n")
60
+ end
61
+ def test_sparse_tensor_new
62
+ t = SparseTensor.new(3)
63
+ assert_equal(t.shape, [0,0,0])
64
+ assert_equal(t.rank, 3)
65
+ end
66
+
67
+ def test_multiplot
68
+ a = GraphKit.autocreate({x: {data: [2, 5, 11, 22],
69
+ units: 'years',
70
+ title: 'Age'},
71
+ y: {data: [1,3,5,6],
72
+ units: 'feet',
73
+ title: 'Height'}})
74
+
75
+ b = GraphKit.autocreate({x: {data: [2, 5, 11, 22],
76
+ units: 'years',
77
+ title: 'Age'},
78
+ y: {data: [1,3,5,6],
79
+ units: 'feet',
80
+ title: 'Height'},
81
+ z: {data: [2,4,8,12],
82
+ units: 'stone',
83
+ title: 'Weight'}})
84
+ b.data[0].modify({with: 'lp'})
85
+
86
+ b.close
87
+ b.gnuplot_write('test/test_output/heights.ps')
88
+
89
+ multiplot = GraphKit::MultiWindow.new
90
+ multiplot.push a
91
+ multiplot.push b
92
+
93
+ multiplot2 = GraphKit::MultiKit.new([GraphKit.quick_create([[0,3], [2,4]])])
94
+ multiplot.merge(multiplot2)
95
+
96
+ assert_equal(GraphKit::MultiKit, eval(multiplot.inspect).class )
97
+
98
+ multiplot.gnuplot_write('test/test_output/multiplot.ps', multiplot: 'layout 2,2')
99
+ end
87
100
 
88
101
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphkit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.4
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Edmund Highcock
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-19 00:00:00.000000000 Z
11
+ date: 2016-03-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rubyhacks
@@ -141,7 +141,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
141
141
  version: '0'
142
142
  requirements: []
143
143
  rubyforge_project:
144
- rubygems_version: 2.2.2
144
+ rubygems_version: 2.4.8
145
145
  signing_key:
146
146
  specification_version: 4
147
147
  summary: A GraphKit is a device independent intelligent data container for generating