ctioga2 0.9 → 0.10

Sign up to get free protection for your applications and to get access to all the features.
Files changed (41) hide show
  1. data/Changelog +27 -0
  2. data/bin/ct2-make-movie +92 -45
  3. data/lib/ctioga2/commands/doc/html.rb +1 -1
  4. data/lib/ctioga2/commands/doc/introspection.rb +52 -0
  5. data/lib/ctioga2/commands/doc/markup.rb +4 -0
  6. data/lib/ctioga2/commands/general-commands.rb +19 -0
  7. data/lib/ctioga2/commands/general-functions.rb +8 -1
  8. data/lib/ctioga2/commands/general-types.rb +14 -3
  9. data/lib/ctioga2/commands/parsers/file.rb +20 -3
  10. data/lib/ctioga2/data/backends/backends/math.rb +1 -1
  11. data/lib/ctioga2/data/backends/backends/text.rb +3 -3
  12. data/lib/ctioga2/data/point.rb +1 -1
  13. data/lib/ctioga2/graphics/elements.rb +1 -0
  14. data/lib/ctioga2/graphics/elements/curve2d.rb +5 -0
  15. data/lib/ctioga2/graphics/elements/primitive.rb +16 -14
  16. data/lib/ctioga2/graphics/elements/style-lists.rb +353 -0
  17. data/lib/ctioga2/graphics/elements/subplot.rb +17 -2
  18. data/lib/ctioga2/graphics/elements/tangent.rb +16 -17
  19. data/lib/ctioga2/graphics/styles.rb +1 -0
  20. data/lib/ctioga2/graphics/styles/axes.rb +63 -0
  21. data/lib/ctioga2/graphics/styles/base.rb +13 -0
  22. data/lib/ctioga2/graphics/styles/colorbrewer.rb +316 -0
  23. data/lib/ctioga2/graphics/styles/colormap.rb +47 -7
  24. data/lib/ctioga2/graphics/styles/image.rb +83 -0
  25. data/lib/ctioga2/graphics/styles/plot.rb +43 -7
  26. data/lib/ctioga2/graphics/styles/sets.rb +47 -5
  27. data/lib/ctioga2/graphics/styles/sheet.rb +18 -3
  28. data/lib/ctioga2/graphics/styles/texts.rb +49 -8
  29. data/lib/ctioga2/graphics/subplot-commands.rb +13 -13
  30. data/lib/ctioga2/graphics/types.rb +42 -10
  31. data/lib/ctioga2/graphics/types/boundaries.rb +3 -2
  32. data/lib/ctioga2/graphics/types/boxes.rb +13 -0
  33. data/lib/ctioga2/graphics/types/dimensions.rb +4 -1
  34. data/lib/ctioga2/graphics/types/location.rb +13 -2
  35. data/lib/ctioga2/graphics/types/point.rb +86 -0
  36. data/lib/ctioga2/metabuilder/types/styles.rb +2 -2
  37. data/lib/ctioga2/plotmaker.rb +3 -0
  38. data/lib/ctioga2/ruby.rb +49 -0
  39. data/lib/ctioga2/utils.rb +34 -0
  40. data/lib/ctioga2/version.rb +2 -2
  41. metadata +8 -4
@@ -49,17 +49,23 @@ module CTioga2
49
49
  # @todo These are currently not implemented.
50
50
  attr_accessor :below, :above
51
51
 
52
- # Whether the map follows RGB (true) or HLS (false). On by
53
- # default.
52
+ # Whether the map is interpolated in the RGB (true) or HLS
53
+ # (false) color space. On by default.
54
54
  #
55
55
  # It does not change anything with respect to how the colors
56
56
  # are interpreted: whatever happens, the values are RGB.
57
57
  attr_accessor :rgb
58
58
 
59
+ # Whether or not the map should be considered symmetric around
60
+ # a given value.
61
+ attr_accessor :symmetry_center
62
+
59
63
  def initialize(values = [], colors = [])
60
64
  @values = values.dup
61
65
  @colors = colors.dup
62
66
 
67
+ @symmetry_center = nil
68
+
63
69
  @rgb = true
64
70
  end
65
71
 
@@ -77,12 +83,33 @@ module CTioga2
77
83
  def self.from_text(str)
78
84
  str = str.dup
79
85
  hls = false
80
- re = /natural:?/i # Not too bad ?
86
+ re = /(natural|hls|wheel):?/i # Not too bad ?
81
87
  if str =~ re
82
88
  str.sub!(re,'')
83
89
  hls = true
84
90
  end
85
91
 
92
+ sym = nil
93
+
94
+ re = /:(?:sym|around):(.*)$/i
95
+ if str =~ re
96
+ sym = $1.to_f
97
+ str.sub!(re,'')
98
+ end
99
+
100
+ # We first try to see if it could be a color set ?
101
+ colorsettype = Commands::CommandType.get_type('color-set')
102
+
103
+ begin
104
+ set = colorsettype.string_to_type(str)
105
+ cm = ColorMap.new([nil] * set.size, set)
106
+ cm.rgb = ! hls
107
+ cm.symmetry_center = sym
108
+ return cm
109
+ rescue Exception => e
110
+ # This is not a color set
111
+ end
112
+
86
113
  l = str.split(/::/)
87
114
 
88
115
 
@@ -141,6 +168,7 @@ module CTioga2
141
168
  cm.above = above
142
169
  cm.below = below
143
170
  cm.rgb = ! hls
171
+ cm.symmetry_center = sym
144
172
  return cm
145
173
  end
146
174
 
@@ -241,6 +269,19 @@ module CTioga2
241
269
  def z_values(zmin, zmax)
242
270
  # Real Z values.
243
271
  z_values = @values.dup
272
+
273
+ # We tweak the zmin and zmax to be symmetric around the
274
+ # symmetry_center should that be needed.
275
+ if @symmetry_center
276
+ dmin = (zmin - @symmetry_center).abs
277
+ dmax = (zmax - @symmetry_center).abs
278
+
279
+ dfin = [dmin, dmax].max
280
+ zmin = @symmetry_center - dfin
281
+ zmax = @symmetry_center + dfin
282
+
283
+ end
284
+
244
285
  z_values[0] ||= zmin
245
286
  z_values[-1] ||= zmax
246
287
 
@@ -252,10 +293,9 @@ module CTioga2
252
293
  if z_values[i]
253
294
  if last_value + 1 < i
254
295
  (last_value+1).upto(i - 1) do |j|
255
- frac = (j - last_value)/(i - last_value + 1.0)
256
- # p [last_value, j, i, frac]
257
- z_values[j] = z_values[last_value] * frac +
258
- z_values[i] * (1 - frac)
296
+ frac = (j - last_value )/(i - last_value*1.0)
297
+ z_values[j] = z_values[last_value] * (1 - frac) +
298
+ z_values[i] * frac
259
299
  end
260
300
  end
261
301
  last_value = i
@@ -0,0 +1,83 @@
1
+ # image.rb: style of images
2
+ # copyright (c) 2014 by Vincent Fourmond
3
+
4
+ # This program is free software; you can redistribute it and/or modify
5
+ # it under the terms of the GNU General Public License as published by
6
+ # the Free Software Foundation; either version 2 of the License, or
7
+ # (at your option) any later version.
8
+
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU General Public License for more details (in the COPYING file).
13
+
14
+ require 'ctioga2/utils'
15
+ require 'ctioga2/log'
16
+
17
+ # This module contains all the classes used by ctioga
18
+ module CTioga2
19
+
20
+ module Graphics
21
+
22
+ # All the styles
23
+ module Styles
24
+
25
+ AspectRatioRE = {
26
+ /ignore/i => :ignore,
27
+ /expand/i => :expand,
28
+ /contract/i => :contract,
29
+ }
30
+
31
+ AspectRatioType =
32
+ CmdType.new('aspect-ratio',
33
+ {:type => :re_list,
34
+ :list => AspectRatioRE}, <<EOD)
35
+ How the {command: draw-image} command respects the original image
36
+ aspect ratio:
37
+ * @ignore@ (the default) ignores the original aspect ratio
38
+ * @expand@ expand the original box to respect aspect ratio
39
+ * @contract@ contract the original box to respect aspect ratio
40
+ EOD
41
+
42
+
43
+
44
+ # This class represents the style for an image
45
+ class ImageStyle < BasicStyle
46
+ # The line style
47
+ typed_attribute :aspect_ratio, 'aspect-ratio'
48
+
49
+ # The line width
50
+ typed_attribute :transparency, 'float'
51
+
52
+ # Automatically rotate
53
+ typed_attribute :auto_rotate, 'boolean'
54
+
55
+ # Draws an image according to this
56
+ def draw_image(t, file, tl, br)
57
+ info = t.jpg_info(file)
58
+ if ! info
59
+ info = t.load_png(file)
60
+ end
61
+
62
+ r = Types::Rect.new(tl, br)
63
+ ul, ll, lr = r.make_corners(t, (@auto_rotate == nil ? true : @auto_rotate), @aspect_ratio || :ignore,
64
+ info['width']*1.0/info['height'])
65
+
66
+ dict = info.dup
67
+ dict.merge!('ul' => ul,
68
+ 'll' => ll,
69
+ 'lr' => lr,)
70
+
71
+ # @todo provide a way to reuse images ?
72
+ t.context do
73
+ if @transparency
74
+ t.fill_opacity = 1 - @transparency
75
+ end
76
+ t.show_image(dict)
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+
@@ -79,6 +79,11 @@ module CTioga2
79
79
  # Mode for auto-adjust
80
80
  attr_accessor :text_auto_adjust
81
81
 
82
+ # If not nil, then the boundaries are computed from the real
83
+ # dimensions of the plot frame, using the given number as a
84
+ # conversion factor from the output dimensions.
85
+ attr_accessor :frame_real_size
86
+
82
87
 
83
88
  @@current_index = 0
84
89
 
@@ -108,7 +113,6 @@ module CTioga2
108
113
  StyleSheet.style_for(TextLabel, 'title',
109
114
  nil,
110
115
  Types::PlotLocation.new(:top))
111
-
112
116
  @plot_margin = nil
113
117
 
114
118
  @transforms = CoordinateTransforms.new
@@ -307,7 +311,7 @@ module CTioga2
307
311
  exts << @title.label_extension(t, 'title', @title.loc) *
308
312
  (@text_scale || 1)
309
313
  end
310
- Types::Dimension.new(:dy, exts.max)
314
+ Types::Dimension.new(:dy, exts.max || 0)
311
315
  end
312
316
 
313
317
  box = Types::MarginsBox.new(*margins)
@@ -319,6 +323,15 @@ module CTioga2
319
323
  return box
320
324
  end
321
325
 
326
+ # Clear all axes
327
+ def clear_axes()
328
+ [:left, :right, :top, :bottom].each do |loc|
329
+ style = get_axis_style(loc)
330
+ style.decoration = Tioga::FigureConstants::AXIS_HIDDEN
331
+ style.axis_label.text = false
332
+ end
333
+ end
334
+
322
335
  # Computes the margins based on the text information.
323
336
  #
324
337
  # This is very different from the one above, since this one
@@ -433,11 +446,7 @@ EOH
433
446
  ClearAxesCommand =
434
447
  Cmd.new("clear-axes",nil,"--clear-axes"
435
448
  ) do |plotmaker, opts|
436
- [:left, :right, :top, :bottom].each do |loc|
437
- style = AxisStyle.current_axis_style(plotmaker, loc)
438
- style.decoration = Tioga::FigureConstants::AXIS_HIDDEN
439
- style.axis_label.text = false
440
- end
449
+ PlotStyle.current_plot_style(plotmaker).clear_axes
441
450
  end
442
451
  ClearAxesCommand.
443
452
  describe("Clear all axes",
@@ -445,6 +454,33 @@ EOH
445
454
  Removes all the axes and their associated labels
446
455
  EOH
447
456
 
457
+ DrawingFrameCommand =
458
+ Cmd.new("drawing-frame",nil,"--drawing-frame", [],
459
+ { 'units' => CmdArg.new('text')
460
+ }) do |plotmaker, opts|
461
+ style = PlotStyle.current_plot_style(plotmaker)
462
+ style.clear_axes
463
+ style.padding = nil
464
+ u = opts['units'] || 'cm'
465
+ if u =~ /([\d.]+)?\s*(cm|in|bp|pt|mm)/
466
+ nb = $1 ? $1.to_f : 1.0
467
+ un = $2
468
+ style.frame_real_size = 10 * nb *
469
+ Types::Dimension::DimensionConversion.fetch(un)
470
+ else
471
+ raise 'Invalid unit'
472
+ end
473
+ end
474
+ DrawingFrameCommand.
475
+ describe("Setup a drawing frame",
476
+ <<"EOH", AxisGroup)
477
+ Setup a drawing frame, ie a frame in which the top-left point is at
478
+ 0,0, with X and Y values positive over the whole frame, and counted in
479
+ centimeters (or with the unit given using the @/units@ option, ie
480
+ @/units=mm@ expressed in millimeters or @/units=12pt@ expressed in
481
+ multiple of 12 TeX points).
482
+ EOH
483
+
448
484
 
449
485
  TicksCommand =
450
486
  Cmd.new("ticks",nil,"--ticks",
@@ -1,5 +1,5 @@
1
- # carrays.rb: 'circular arrays'
2
- # copyright (c) 2009 by Vincent Fourmond
1
+ # sets.rb: sets
2
+ # copyright (c) 2009, 2014 by Vincent Fourmond
3
3
 
4
4
  # This program is free software; you can redistribute it and/or modify
5
5
  # it under the terms of the GNU General Public License as published by
@@ -14,6 +14,8 @@
14
14
  require 'ctioga2/utils'
15
15
  require 'ctioga2/log'
16
16
 
17
+ require 'ctioga2/graphics/styles/colorbrewer'
18
+
17
19
  # This module contains all the classes used by ctioga
18
20
  module CTioga2
19
21
 
@@ -39,16 +41,56 @@ module CTioga2
39
41
  [LightPlum, PaleGreen, Gold, RedBrown, SkyBlue ],
40
42
  "gnuplot" =>
41
43
  [Red, [0,1.0,0], Blue, Magenta, Cyan, Yellow, Black, Coral, Gray],
42
-
43
44
  }
45
+
46
+ begin
47
+ t = Tioga::FigureMaker.new
48
+ lst = []
49
+ 10.times do |i|
50
+ lst << t.hls_to_rgb([36*i, 0.5, 1.0])
51
+ end
52
+ ColorSets['wheel10'] = lst
53
+
54
+ lst = []
55
+ 20.times do |i|
56
+ lst << t.hls_to_rgb([18*i, 0.5, 1.0])
57
+ end
58
+ ColorSets['wheel20'] = lst
59
+
60
+ colortype = Commands::CommandType.get_type('color')
61
+ for k,v in ColorBrewerSets
62
+ for n, a in v
63
+ if n > 4
64
+ ColorSets["cb-#{k.downcase}-#{n}"] = a.map do |c|
65
+ colortype.string_to_type(c)
66
+ end
67
+ end
68
+ end
69
+ end
70
+
71
+ end
44
72
 
45
73
  MarkerSets = {
46
74
  "default" =>
47
- [Bullet, TriangleUp, Square, Plus, Times],
75
+ [Bullet, TriangleUp, Square, Plus, Times, Diamond, TriangleDown],
48
76
  "open" =>
49
- [BulletOpen, TriangleUpOpen, SquareOpen, PlusOpen, TimesOpen],
77
+ [BulletOpen, TriangleUpOpen, SquareOpen, PlusOpen, TimesOpen,
78
+ DiamondOpen, TriangleDownOpen],
50
79
  }
51
80
 
81
+ for k, b in {
82
+ 'number1' => 171,
83
+ 'number2' => 181,
84
+ 'number3' => 191,
85
+ 'number4' => 201
86
+ }
87
+ lst = []
88
+ 1.upto(10) do |i|
89
+ lst << [14, b + i]
90
+ end
91
+ MarkerSets[k] = lst
92
+ end
93
+
52
94
  LineWidthSets = {
53
95
  'default' => [1.0]
54
96
  }
@@ -152,6 +152,15 @@ module CTioga2
152
152
  def self.current_sheet()
153
153
  return @sheet
154
154
  end
155
+
156
+
157
+ # Updates the style sheet concerning the _what_ of class _cls_
158
+ # with the given values
159
+ def self.update_style(cls, what, values)
160
+ StyleSheet.current_sheet.own_styles[cls] ||= {}
161
+ StyleSheet.current_sheet.own_styles[cls][what] ||= {}
162
+ StyleSheet.current_sheet.own_styles[cls][what].merge!(values)
163
+ end
155
164
 
156
165
  end
157
166
 
@@ -183,6 +192,7 @@ EOD
183
192
  ['marker', MarkerStringStyle, 'marker'],
184
193
  ['box', BoxStyle, 'boxes'],
185
194
  ['arrow', ArrowStyle, 'arrows'],
195
+ ['image', ImageStyle, 'image'],
186
196
  ['line', StrokeStyle, 'lines']
187
197
  ]
188
198
 
@@ -200,9 +210,7 @@ EOD
200
210
  ],
201
211
  cls.options_hash
202
212
  ) do |plotmaker, what, opts|
203
- StyleSheet.current_sheet.own_styles[cls] ||= {}
204
- StyleSheet.current_sheet.own_styles[cls][what] ||= {}
205
- StyleSheet.current_sheet.own_styles[cls][what].merge!(opts)
213
+ StyleSheet.update_style(cls, what, opts)
206
214
  end
207
215
  StyleSheetCommands[name].
208
216
  describe("Sets the default style for the given #{desc}.",
@@ -340,7 +348,14 @@ Axis styles have lots of parameters:
340
348
  * @background-lines-@ parameters define the style of background lines,
341
349
  as in {command: define-line-style}
342
350
  EOD
351
+
352
+
353
+ # Here, a few defaults styles
343
354
 
355
+ StyleSheet.update_style(TextLabel, 'title', {
356
+ 'text_width' =>
357
+ Types::Dimension.new(:frame, 1.0, :x)
358
+ })
344
359
  end
345
360
  end
346
361
  end
@@ -44,15 +44,23 @@ module CTioga2
44
44
  # The vertical alignment
45
45
  typed_attribute :alignment, 'alignment'
46
46
 
47
+ alias_for :valign, :alignment
48
+
47
49
  # The horizontal alignment
48
50
  typed_attribute :justification, 'justification'
49
51
 
52
+ alias_for :halign, :justification
53
+
50
54
  # A text width
51
- typed_attribute :text_width, "text"
55
+ typed_attribute :text_width, "dimension-or-no"
56
+
57
+ # A text alignment within the box, only useful if text_width
58
+ # is specified.
59
+ typed_attribute :text_align, 'text-align'
52
60
 
53
61
  # Draw the _text_ at the given location with the given style.
54
- # If _y_ is _nil_, then _x_or_loc_ is taken to be a location
55
- # (see FigureMaker#show_text).
62
+ # If _y_ is _nil_, or [:pos, _value_] then _x_or_loc_ is taken
63
+ # to be a location (see FigureMaker#show_text).
56
64
  def draw_text(t, text, x_or_loc, y = nil, measure = nil)
57
65
  t.context do
58
66
  dict = prepare_show_text_dict(t, text, x_or_loc, y, measure)
@@ -88,18 +96,24 @@ module CTioga2
88
96
  return dict
89
97
  end
90
98
 
99
+ def vertical?(loc)
100
+ if loc
101
+ return Types::PlotLocation.new(loc).vertical?
102
+ else
103
+ ang = angle || 0
104
+ return Math.sin(ang*3.14/180)**2 > 0.5
105
+ end
106
+ end
107
+
91
108
  protected
92
109
 
93
110
  # Prepares the dictionnary for use with show_text
94
111
  def prepare_show_text_dict(t, text, x_or_loc, y = nil, measure = nil)
95
112
  dict = self.hash_for_tioga(t)
96
- if @text_width
97
- text = "\\parbox{#{@text_width}}{#{text}}"
98
- end
99
113
 
100
- dict['text'] = text
114
+ loc = nil
101
115
 
102
- if y
116
+ if y && (! y.is_a?(Array))
103
117
  dict['at'] = [x_or_loc, y]
104
118
  else
105
119
  # Perform automatic conversion on the location
@@ -107,13 +121,40 @@ module CTioga2
107
121
  when Symbol, Types::PlotLocation
108
122
  ## @todo It won't be easy to implement shifts for this,
109
123
  ## though it may be useful eventually.
124
+ loc = x_or_loc
110
125
  x_or_loc = Types::PlotLocation.new(x_or_loc).tioga_location
111
126
  end
112
127
  dict['loc'] = x_or_loc
128
+ if y
129
+ dict['position'] = y[1]
130
+ end
113
131
  end
114
132
  if measure
115
133
  dict['measure'] = measure
116
134
  end
135
+
136
+ if @text_width
137
+ dir = (vertical?(loc) ? :y : :x)
138
+ dim = @text_width.to_bp(t, dir)
139
+ dim /= t.default_text_scale
140
+
141
+ aln = @text_align || @justification || Tioga::FigureConstants::CENTERED
142
+ cmd =
143
+ case aln
144
+ when Tioga::FigureConstants::CENTERED
145
+ '\centering{}'
146
+ when Tioga::FigureConstants::LEFT_JUSTIFIED
147
+ '\raggedright{}'
148
+ when Tioga::FigureConstants::RIGHT_JUSTIFIED
149
+ '\raggedleft{}'
150
+ else
151
+ ''
152
+ end
153
+ text = "\\parbox{#{dim}bp}{#{cmd}#{text}}"
154
+ end
155
+
156
+ dict['text'] = text
157
+
117
158
  return dict
118
159
  end
119
160
  end