tioga 1.4
Sign up to get free protection for your applications and to get access to all the features.
- data/Tioga_README +372 -0
- data/lgpl.txt +504 -0
- data/split/Dtable/defs.h +33 -0
- data/split/Dtable/dtable.c +1928 -0
- data/split/Dtable/dtable_intern.h +144 -0
- data/split/Dtable/dvector.h +61 -0
- data/split/Dtable/extconf.rb +4 -0
- data/split/Dtable/include/dtable.h +35 -0
- data/split/Dtable/lib/Dtable_extras.rb +90 -0
- data/split/Dtable/namespace.h +47 -0
- data/split/Dtable/safe_double.h +104 -0
- data/split/Dtable/symbols.c +92 -0
- data/split/Dtable/symbols.h +52 -0
- data/split/Dvector/defs.h +33 -0
- data/split/Dvector/dvector.c +5486 -0
- data/split/Dvector/dvector_intern.h +142 -0
- data/split/Dvector/extconf.rb +4 -0
- data/split/Dvector/include/dvector.h +61 -0
- data/split/Dvector/lib/Dvector_extras.rb +328 -0
- data/split/Dvector/lib/Numeric_extras.rb +134 -0
- data/split/Dvector/namespace.h +47 -0
- data/split/Dvector/safe_double.h +104 -0
- data/split/Dvector/symbols.c +92 -0
- data/split/Dvector/symbols.h +52 -0
- data/split/Flate/defs.h +33 -0
- data/split/Flate/extconf.rb +19 -0
- data/split/Flate/flate.c +156 -0
- data/split/Flate/flate_intern.h +97 -0
- data/split/Flate/include/flate.h +98 -0
- data/split/Flate/namespace.h +47 -0
- data/split/Flate/safe_double.h +104 -0
- data/split/Flate/symbols.c +92 -0
- data/split/Flate/symbols.h +52 -0
- data/split/Function/defs.h +33 -0
- data/split/Function/dvector.h +61 -0
- data/split/Function/extconf.rb +4 -0
- data/split/Function/function.c +988 -0
- data/split/Function/joint_qsort.c +258 -0
- data/split/Function/lib/Function_extras.rb +44 -0
- data/split/Function/namespace.h +47 -0
- data/split/Function/safe_double.h +104 -0
- data/split/Function/symbols.c +92 -0
- data/split/Function/symbols.h +52 -0
- data/split/Tioga/axes.c +774 -0
- data/split/Tioga/defs.h +33 -0
- data/split/Tioga/dtable.h +35 -0
- data/split/Tioga/dvector.h +61 -0
- data/split/Tioga/extconf.rb +4 -0
- data/split/Tioga/figures.c +672 -0
- data/split/Tioga/figures.h +855 -0
- data/split/Tioga/flate.h +98 -0
- data/split/Tioga/init.c +524 -0
- data/split/Tioga/lib/Arcs_and_Circles.rb +64 -0
- data/split/Tioga/lib/ColorConstants.rb +274 -0
- data/split/Tioga/lib/Colorbars.rb +10 -0
- data/split/Tioga/lib/Colormaps.rb +105 -0
- data/split/Tioga/lib/Coordinate_Conversions.rb +194 -0
- data/split/Tioga/lib/Creating_Paths.rb +94 -0
- data/split/Tioga/lib/Doc.rb +91 -0
- data/split/Tioga/lib/Executive.rb +515 -0
- data/split/Tioga/lib/FigMkr.rb +2224 -0
- data/split/Tioga/lib/FigureConstants.rb +125 -0
- data/split/Tioga/lib/Figures_and_Plots.rb +268 -0
- data/split/Tioga/lib/Images.rb +278 -0
- data/split/Tioga/lib/Legends.rb +190 -0
- data/split/Tioga/lib/MarkerConstants.rb +122 -0
- data/split/Tioga/lib/Markers.rb +129 -0
- data/split/Tioga/lib/Page_Frame_Bounds.rb +567 -0
- data/split/Tioga/lib/Rectangles.rb +94 -0
- data/split/Tioga/lib/Shading.rb +100 -0
- data/split/Tioga/lib/Special_Paths.rb +307 -0
- data/split/Tioga/lib/Strokes.rb +129 -0
- data/split/Tioga/lib/TeX_Text.rb +454 -0
- data/split/Tioga/lib/TexPreamble.rb +358 -0
- data/split/Tioga/lib/Titles_and_Labels.rb +306 -0
- data/split/Tioga/lib/Transparency.rb +89 -0
- data/split/Tioga/lib/Using_Paths.rb +164 -0
- data/split/Tioga/lib/Utils.rb +74 -0
- data/split/Tioga/lib/X_and_Y_Axes.rb +749 -0
- data/split/Tioga/lib/irb_tioga.rb +122 -0
- data/split/Tioga/lib/tioga.rb +1 -0
- data/split/Tioga/lib/tioga_ui.rb +5 -0
- data/split/Tioga/lib/tioga_ui_cmds.rb +793 -0
- data/split/Tioga/makers.c +989 -0
- data/split/Tioga/mk_tioga_sty.rb +53 -0
- data/split/Tioga/namespace.h +47 -0
- data/split/Tioga/pdf_font_dicts.c +18253 -0
- data/split/Tioga/pdfcolor.c +486 -0
- data/split/Tioga/pdfcoords.c +505 -0
- data/split/Tioga/pdffile.c +342 -0
- data/split/Tioga/pdfimage.c +536 -0
- data/split/Tioga/pdfpath.c +914 -0
- data/split/Tioga/pdfs.h +229 -0
- data/split/Tioga/pdftext.c +443 -0
- data/split/Tioga/safe_double.h +104 -0
- data/split/Tioga/symbols.c +92 -0
- data/split/Tioga/symbols.h +52 -0
- data/split/Tioga/texout.c +380 -0
- data/split/defs.h +33 -0
- data/split/extconf.rb +107 -0
- data/split/mkmf2.rb +1612 -0
- data/split/namespace.h +47 -0
- data/split/safe_double.h +104 -0
- data/split/scripts/tioga +4 -0
- data/split/symbols.c +92 -0
- data/split/symbols.h +52 -0
- data/tests/dtable_test.data +6 -0
- data/tests/dvector_read_test.data +1 -0
- data/tests/dvector_test.data +101 -0
- data/tests/tc_Dtable.rb +221 -0
- data/tests/tc_Dvector.rb +791 -0
- data/tests/tc_FMkr.rb +162 -0
- data/tests/tc_Flate.rb +45 -0
- data/tests/tc_Function.rb +111 -0
- data/tests/ts_Tioga.rb +38 -0
- metadata +163 -0
@@ -0,0 +1,125 @@
|
|
1
|
+
=begin
|
2
|
+
Copyright (C) 2005 Bill Paxton
|
3
|
+
|
4
|
+
This file is part of Tioga.
|
5
|
+
|
6
|
+
Tioga is free software; you can redistribute it and/or modify
|
7
|
+
it under the terms of the GNU General Library Public License as published
|
8
|
+
by the Free Software Foundation; either version 2 of the License, or
|
9
|
+
(at your option) any later version.
|
10
|
+
|
11
|
+
Tioga is distributed in the hope that it will be useful,
|
12
|
+
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
GNU Library General Public License for more details.
|
15
|
+
|
16
|
+
You should have received a copy of the GNU Library General Public License
|
17
|
+
along with Tioga; if not, write to the Free Software
|
18
|
+
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
19
|
+
=end
|
20
|
+
|
21
|
+
# FigureConstants.rb
|
22
|
+
|
23
|
+
module Tioga
|
24
|
+
|
25
|
+
require 'Tioga/MarkerConstants.rb'
|
26
|
+
require 'Tioga/ColorConstants.rb'
|
27
|
+
|
28
|
+
# These constants are for use in making figures and plots with tioga.
|
29
|
+
#
|
30
|
+
# They cover the choices for justification, vertical alignment, frame sides,
|
31
|
+
# axis types, line types, stroke caps, stroke joins, and rendering modes.
|
32
|
+
|
33
|
+
module FigureConstants
|
34
|
+
|
35
|
+
include Math
|
36
|
+
include MarkerConstants
|
37
|
+
include ColorConstants
|
38
|
+
|
39
|
+
LEFT_JUSTIFIED = -1
|
40
|
+
CENTERED = 0
|
41
|
+
RIGHT_JUSTIFIED = 1
|
42
|
+
|
43
|
+
ALIGNED_AT_TOP = 0
|
44
|
+
ALIGNED_AT_MIDHEIGHT = 1
|
45
|
+
ALIGNED_AT_BASELINE = 2
|
46
|
+
ALIGNED_AT_BOTTOM = 3
|
47
|
+
|
48
|
+
LEFT = 0
|
49
|
+
RIGHT = 1
|
50
|
+
TOP = 2
|
51
|
+
BOTTOM = 3
|
52
|
+
|
53
|
+
AT_X_ORIGIN = 4
|
54
|
+
AT_Y_ORIGIN = 5
|
55
|
+
|
56
|
+
AXIS_HIDDEN = 0
|
57
|
+
AXIS_LINE_ONLY = 1
|
58
|
+
AXIS_WITH_MAJOR_TICKS_ONLY = 2
|
59
|
+
AXIS_WITH_TICKS_ONLY = 3
|
60
|
+
AXIS_WITH_MAJOR_TICKS_AND_NUMERIC_LABELS = 4
|
61
|
+
AXIS_WITH_TICKS_AND_NUMERIC_LABELS = 5
|
62
|
+
|
63
|
+
|
64
|
+
EDGE_HIDDEN = 0
|
65
|
+
EDGE_LINE_ONLY = 1
|
66
|
+
EDGE_WITH_MAJOR_TICKS_ONLY = 2
|
67
|
+
EDGE_WITH_TICKS = 3
|
68
|
+
|
69
|
+
|
70
|
+
Line_Type_Solid = [[], 0]
|
71
|
+
Line_Type_Dot = [[1, 2], 0]
|
72
|
+
Line_Type_Dots = Line_Type_Dot
|
73
|
+
Line_Type_Dash = [[4, 2], 0]
|
74
|
+
Line_Type_Short_Dash = Line_Type_Dash
|
75
|
+
Line_Type_Dashes = Line_Type_Dash
|
76
|
+
Line_Type_Short_Dashes = Line_Type_Dash
|
77
|
+
|
78
|
+
LINE_TYPE_SOLID = Line_Type_Solid
|
79
|
+
LINE_TYPE_DOT = Line_Type_Dot
|
80
|
+
LINE_TYPE_DOTS = Line_Type_Dots
|
81
|
+
LINE_TYPE_DASH = Line_Type_Dash
|
82
|
+
LINE_TYPE_SHORT_DASH = Line_Type_Short_Dash
|
83
|
+
LINE_TYPE_DASHES = Line_Type_Dashes
|
84
|
+
LINE_TYPE_SHORT_DASHES = Line_Type_Short_Dashes
|
85
|
+
|
86
|
+
|
87
|
+
Line_Type_Long_Dash = [[6, 2], 0]
|
88
|
+
Line_Type_Long_Dashes = Line_Type_Long_Dash
|
89
|
+
Line_Type_Dot_Dash = [[1, 2, 4, 2], 0]
|
90
|
+
Line_Type_Dot_Short_Dash = Line_Type_Dot_Dash
|
91
|
+
Line_Type_Dot_Long_Dash = [[1, 2, 6, 2], 0]
|
92
|
+
Line_Type_Short_Dash_Long_Dash = [[4, 2, 6, 2], 0]
|
93
|
+
|
94
|
+
LINE_TYPE_LONG_DASH = Line_Type_Long_Dash
|
95
|
+
LINE_TYPE_LONG_DASHES = Line_Type_Long_Dashes
|
96
|
+
LINE_TYPE_DOT_DASH = Line_Type_Dot_Dash
|
97
|
+
LINE_TYPE_DOT_SHORT_DASH = Line_Type_Dot_Short_Dash
|
98
|
+
LINE_TYPE_DOT_LONG_DASH = Line_Type_Dot_Long_Dash
|
99
|
+
LINE_TYPE_SHORT_DASH_LONG_DASH = Line_Type_Short_Dash_Long_Dash
|
100
|
+
|
101
|
+
LINE_CAP_BUTT = 0
|
102
|
+
LINE_CAP_ROUND = 1
|
103
|
+
LINE_CAP_SQUARE = 2
|
104
|
+
|
105
|
+
LINE_JOIN_MITER = 0
|
106
|
+
LINE_JOIN_ROUND = 1
|
107
|
+
LINE_JOIN_BEVEL = 2
|
108
|
+
|
109
|
+
FILL = 0
|
110
|
+
STROKE = 1
|
111
|
+
FILL_AND_STROKE = 2
|
112
|
+
DISCARD = 3
|
113
|
+
FILL_AND_CLIP = 4
|
114
|
+
STROKE_AND_CLIP = 5
|
115
|
+
FILL_STROKE_AND_CLIP = 6
|
116
|
+
CLIP = 7
|
117
|
+
|
118
|
+
DEGREES_PER_RADIAN = 180.0/PI
|
119
|
+
RADIANS_PER_DEGREE = PI/180.0
|
120
|
+
|
121
|
+
end # module FigureConstants
|
122
|
+
|
123
|
+
end # module Tioga
|
124
|
+
|
125
|
+
|
@@ -0,0 +1,268 @@
|
|
1
|
+
# Figures_and_Plots.rb
|
2
|
+
|
3
|
+
module Tioga
|
4
|
+
|
5
|
+
# These are the methods and attributes related to the "top-level" structure and layout of figures and plots.
|
6
|
+
|
7
|
+
# See also Tutorial::Figures and Tutorial::Plots.
|
8
|
+
|
9
|
+
class Figures_and_Plots < Doc < FigureMaker
|
10
|
+
|
11
|
+
# :call-seq:
|
12
|
+
# show_plot(bounds) do ... end
|
13
|
+
#
|
14
|
+
# The first action of show_plot is to call set_bounds to set up the figure coordinates for the plot.
|
15
|
+
# Then, inside a call to #context so that the current state will be restored later, it calls clip_to_frame
|
16
|
+
# followed by the block defining the plot. Finally, it calls show_plot_box to take care of the axes and labels.
|
17
|
+
def show_plot(bounds=nil,&cmd)
|
18
|
+
end
|
19
|
+
|
20
|
+
# :call-seq:
|
21
|
+
# context do ... end
|
22
|
+
#
|
23
|
+
# The context routine saves 'state', executes the given block, and then restores state.
|
24
|
+
# The state being saved and restored consists of the attributes defining the page setup
|
25
|
+
# (frame, bounds, axes), graphics (clip region, stroke and fill colors, line width and type, etc.),
|
26
|
+
# axis label settings, and legend layout settings. Some of the things it saves and restores
|
27
|
+
# are arrays (such as the optional arrays of locations for major tick marks on the axes). In these
|
28
|
+
# cases, context will save and restore the pointer to the array, but it doesn't do anything about
|
29
|
+
# the contents of the array. Similarly, for text strings such as the title, it will save and
|
30
|
+
# restore the pointer but not the contents.
|
31
|
+
#
|
32
|
+
# Among the things that it does *not* save/restore is the saved legend information (as opposed to
|
33
|
+
# the legend layout attributes which are saved). This makes it possible to gather legend information
|
34
|
+
# from a subplot while still isolating it in its own context.
|
35
|
+
#
|
36
|
+
# Routines such as show_plot, #subplot, and #subfigure make use of context to prevent side-effects
|
37
|
+
# from the execution of the code body 'leaking' out to pollute the caller's environment.
|
38
|
+
# The practical result is that in writing plotting routines, you can safely change various settings
|
39
|
+
# without needing to restore the old values when you finish. This becomes critical when you begin
|
40
|
+
# to combine several plots into a composite plot.
|
41
|
+
def context (&cmd)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Calls both rescale_text and rescale_lines with the given _factor_.
|
45
|
+
def rescale(factor)
|
46
|
+
end
|
47
|
+
|
48
|
+
=begin rdoc
|
49
|
+
:call-seq:
|
50
|
+
subfigure do ... end
|
51
|
+
subfigure(margins) do ... end
|
52
|
+
|
53
|
+
Inside a call to #context, subfigure first calls doing_subfigure, then calls set_subframe with the margins, and
|
54
|
+
finally executes the block of commands for the figure.
|
55
|
+
|
56
|
+
Example
|
57
|
+
|
58
|
+
def subfigures
|
59
|
+
t.rescale_text(0.45)
|
60
|
+
t.subfigure('right' => 0.5, 'bottom' => 0.5) {
|
61
|
+
icon }
|
62
|
+
t.subfigure('right' => 0.5, 'top' => 0.5) {
|
63
|
+
t.stroke_color = White; math_typesetting }
|
64
|
+
t.subfigure('left' => 0.5, 'bottom' => 0.5) {
|
65
|
+
transparent_squares }
|
66
|
+
t.subfigure('left' => 0.5, 'top' => 0.5) {
|
67
|
+
jpg_image_transparent }
|
68
|
+
end
|
69
|
+
|
70
|
+
http://theory.kitp.ucsb.edu/~paxton/tioga_jpegs/Subfigures.jpg
|
71
|
+
=end
|
72
|
+
def subfigure(margins=nil,&cmd)
|
73
|
+
end
|
74
|
+
|
75
|
+
=begin rdoc
|
76
|
+
:call-seq:
|
77
|
+
subplot do ... end
|
78
|
+
subplot(margins) do ... end
|
79
|
+
|
80
|
+
Inside a call to #context, subplot first calls doing_subplot, then calls set_subframe with the margins, and
|
81
|
+
finally executes the block of commands for the plot.
|
82
|
+
|
83
|
+
Examples
|
84
|
+
|
85
|
+
def two_yaxes
|
86
|
+
t.show_title('Same X, Different Y\'s'); t.no_title
|
87
|
+
t.show_xlabel('Position'); t.no_xlabel
|
88
|
+
t.subplot { t.yaxis_loc = t.ylabel_side = LEFT; t.no_right_edge; reds }
|
89
|
+
t.subplot { t.yaxis_loc = t.ylabel_side = RIGHT; t.no_left_edge; greens }
|
90
|
+
end
|
91
|
+
|
92
|
+
http://theory.kitp.ucsb.edu/~paxton/tioga_jpegs/Two_Ys.jpg
|
93
|
+
|
94
|
+
def side_by_side
|
95
|
+
t.do_box_labels('Side by Side', 'Position', nil)
|
96
|
+
t.ylabel_angle = -90
|
97
|
+
t.ylabel_shift += 1
|
98
|
+
t.subplot('right_margin' => 0.5) {
|
99
|
+
t.yaxis_loc = t.ylabel_side = LEFT; t.right_edge_type = AXIS_LINE_ONLY; blues }
|
100
|
+
t.subplot('left_margin' => 0.5) {
|
101
|
+
t.yaxis_loc = t.ylabel_side = RIGHT; t.left_edge_type = AXIS_LINE_ONLY; reds }
|
102
|
+
end
|
103
|
+
|
104
|
+
http://theory.kitp.ucsb.edu/~paxton/tioga_jpegs/Side_by_Side.jpg
|
105
|
+
|
106
|
+
def rows
|
107
|
+
t.do_box_labels('Blues, Reds, Greens', 'Position', nil)
|
108
|
+
t.rescale(0.8)
|
109
|
+
num_plots = 3
|
110
|
+
t.subplot(t.row_margins('num_rows' => num_plots, 'row' => 1)) do
|
111
|
+
t.xaxis_type = AXIS_WITH_TICKS_ONLY
|
112
|
+
blues
|
113
|
+
end
|
114
|
+
t.subplot(t.row_margins('num_rows' => num_plots, 'row' => 2)) do
|
115
|
+
t.xaxis_type = AXIS_WITH_TICKS_ONLY
|
116
|
+
t.top_edge_type = AXIS_HIDDEN
|
117
|
+
reds
|
118
|
+
end
|
119
|
+
t.subplot(t.row_margins('num_rows' => num_plots, 'row' => 3)) do
|
120
|
+
t.top_edge_type = AXIS_HIDDEN
|
121
|
+
greens
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
http://theory.kitp.ucsb.edu/~paxton/tioga_jpegs/Rows.jpg
|
126
|
+
|
127
|
+
def trio
|
128
|
+
t.rescale(0.6)
|
129
|
+
t.subplot(
|
130
|
+
'bottom_margin' => 0.55,
|
131
|
+
'left_margin' => 0.15,
|
132
|
+
'right_margin' => 0.15) { rows }
|
133
|
+
t.subplot('top_margin' => 0.55) { side_by_side }
|
134
|
+
end
|
135
|
+
|
136
|
+
http://theory.kitp.ucsb.edu/~paxton/tioga_jpegs/Trio.jpg
|
137
|
+
=end
|
138
|
+
def subplot(margins=nil,&cmd)
|
139
|
+
end
|
140
|
+
|
141
|
+
# :call-seq:
|
142
|
+
# doing_subplot
|
143
|
+
#
|
144
|
+
# Sets the in_subplot flag to +true+. Is called on entry to the #subplot routine.
|
145
|
+
# Provided as a convience for your plotting routines.
|
146
|
+
def doing_subplot
|
147
|
+
end
|
148
|
+
|
149
|
+
# :call-seq:
|
150
|
+
# doing_subfigure
|
151
|
+
#
|
152
|
+
# Sets the root_figure flag to +false+. Is called on entry to the #subfigure routine.
|
153
|
+
# Provided as a convience for your plotting routines.
|
154
|
+
def doing_subfigure
|
155
|
+
end
|
156
|
+
|
157
|
+
# :call-seq:
|
158
|
+
# show_plot_box
|
159
|
+
#
|
160
|
+
# Makes a series of calls to show the axes, edges, title, and axis labels.
|
161
|
+
# This routine is called by show_plot after the contents of the frame have been finished.
|
162
|
+
def show_plot_box
|
163
|
+
end
|
164
|
+
|
165
|
+
=begin rdoc
|
166
|
+
:call-seq:
|
167
|
+
show_plot_with_legend(dict) do ... end
|
168
|
+
show_plot_with_legend do ... end
|
169
|
+
|
170
|
+
Adjusts margins according to the entries in the _dict_ argument, executes the plot definition, then calls +show_legend+.
|
171
|
+
The dictionary entries are all optional, and default values are taken from the +legend_defaults+ dictionary. The margin
|
172
|
+
sizes are given as fractions of the current frame. The +plot_scale+ applies to the entire plot including the legend. The +legend_scale+ only applies to the legend.
|
173
|
+
|
174
|
+
Dictionary Entries
|
175
|
+
'legend_top_margin' => a_float
|
176
|
+
'legend_bottom_margin' => a_float
|
177
|
+
'legend_left_margin' => a_float
|
178
|
+
'legend_right_margin' => a_float
|
179
|
+
'plot_top_margin' => a_float
|
180
|
+
'plot_bottom_margin' => a_float
|
181
|
+
'plot_left_margin' => a_float
|
182
|
+
'plot_right_margin' => a_float
|
183
|
+
'plot_scale' => a_float
|
184
|
+
'legend_scale' => a_float
|
185
|
+
|
186
|
+
Examples
|
187
|
+
|
188
|
+
def legend_outside
|
189
|
+
read_data
|
190
|
+
show_model_number
|
191
|
+
t.show_plot_with_legend('legend_scale' => 1.3) { reds_blues }
|
192
|
+
end
|
193
|
+
|
194
|
+
def legend_inside
|
195
|
+
read_data
|
196
|
+
show_model_number
|
197
|
+
t.show_plot_with_legend(
|
198
|
+
'legend_left_margin' => 0.7,
|
199
|
+
'legend_scale' => 1.3,
|
200
|
+
'plot_right_margin' => 0) { reds_blues }
|
201
|
+
end
|
202
|
+
|
203
|
+
def legends
|
204
|
+
t.subfigure('top_margin' => 0.6) do
|
205
|
+
t.rescale(0.5)
|
206
|
+
t.subplot('right_margin' => 0.6) do
|
207
|
+
t.show_plot_with_legend(
|
208
|
+
'legend_left_margin' => 0.7,
|
209
|
+
'legend_scale' => 1.3,
|
210
|
+
'plot_right_margin' => 0) { reds_blues }
|
211
|
+
end
|
212
|
+
t.subplot('left_margin' => 0.56) do
|
213
|
+
t.show_plot_with_legend('legend_scale' => 1.3) { reds_blues }
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
http://theory.kitp.ucsb.edu/~paxton/tioga_jpegs/Legends.jpg
|
219
|
+
|
220
|
+
=end
|
221
|
+
def show_plot_with_legend(dict=nil, &cmd)
|
222
|
+
end
|
223
|
+
|
224
|
+
# :call-seq:
|
225
|
+
# show_edges
|
226
|
+
#
|
227
|
+
# Makes a series of calls to show the frame edges (show_top_edge, show_left_edge, etc.)
|
228
|
+
def show_edges
|
229
|
+
end
|
230
|
+
|
231
|
+
# :call-seq:
|
232
|
+
# root_figure
|
233
|
+
#
|
234
|
+
# Flag starts +true+ and is set to +false+ by the doing_subfigure routine which is called on entry to the #subfigure routine.
|
235
|
+
# This is simply provided as a convenience for routines that need to know whether they are being called as a subfigure or as
|
236
|
+
# a top-level figure. Same as not in_subplot.
|
237
|
+
def root_figure
|
238
|
+
end
|
239
|
+
|
240
|
+
# :call-seq:
|
241
|
+
# in_subfigure
|
242
|
+
#
|
243
|
+
# Flag starts +false+ and is set to +true+ by the doing_subfigure routine which is called on entry to the #subfigure routine.
|
244
|
+
# This is simply provided as a convenience for routines that need to know whether they are being called as a subfigure or as
|
245
|
+
# a top-level figure. Same as not root_figure.
|
246
|
+
def in_subfigure
|
247
|
+
end
|
248
|
+
|
249
|
+
# :call-seq:
|
250
|
+
# root_plot
|
251
|
+
#
|
252
|
+
# Flag starts +true+ and is set to +false+ by the doing_subplot routine which is called on entry to the #subplot routine.
|
253
|
+
# This is simply provided as a convenience for routines that need to know whether they are being called as a subplot or as
|
254
|
+
# a top-level plot. Same as not in_subplot.
|
255
|
+
def root_plot
|
256
|
+
end
|
257
|
+
|
258
|
+
# :call-seq:
|
259
|
+
# in_subplot
|
260
|
+
#
|
261
|
+
# Flag starts +false+ and is set to +true+ by the doing_subplot routine which is called on entry to the #subplot routine.
|
262
|
+
# This is simply provided as a convenience for routines that need to know whether they are being called as a subplot or as
|
263
|
+
# a top-level plot. Same as not root_plot.
|
264
|
+
def in_subplot
|
265
|
+
end
|
266
|
+
|
267
|
+
end # class
|
268
|
+
end # module Tioga
|
@@ -0,0 +1,278 @@
|
|
1
|
+
# Images.rb
|
2
|
+
|
3
|
+
module Tioga
|
4
|
+
|
5
|
+
# These are the methods for creating and using images in PDF graphics.
|
6
|
+
|
7
|
+
# See also Tutorial::SampledData.
|
8
|
+
|
9
|
+
class Images < Doc < FigureMaker
|
10
|
+
|
11
|
+
=begin rdoc
|
12
|
+
Shows the image specified by the dictionary argument _dict_. The image can be taken from a JPEG file
|
13
|
+
or it can be given as sampled data to be mapped to colors for pixels.
|
14
|
+
|
15
|
+
Some of the dictionary entries give the properties of the image itself and some deal with
|
16
|
+
the placement of the image in the figure. Conceptually the image is a rectangle with the
|
17
|
+
first row of data at the top and the last row at the bottom. The first column in each row
|
18
|
+
is at the left and the last column is at the right. This image rectangle is mapped to the
|
19
|
+
figure by giving the figure coordinate locations for the lower left, lower right, and upper
|
20
|
+
right corners of the image. This allows the image to be rotated, streched, and skewed when
|
21
|
+
it is placed -- or even reflected in either the horizontal or vertical by suitable choices
|
22
|
+
for the corner locations.
|
23
|
+
|
24
|
+
For a JPEG, you can simply give the filename for the image along with the location and the
|
25
|
+
width and height. Sampled images can be monochrome, gray scale, RGB, or CMYK according to the value of the
|
26
|
+
'color_space' entry.
|
27
|
+
|
28
|
+
The 'color_space' entry is set to 'MONO' or 'mono' for a monochrome image. The monochrome image is used as
|
29
|
+
a 'stencil mask' for painting in the current fill color. The default is to paint places corresponding
|
30
|
+
to sample values of 0 while leaving the previous contents unchanged where the sample value is 1.
|
31
|
+
If the entry 'reversed' is +true+, then this interpretation is reversed, and 1's are painted and 0's left unchanged.
|
32
|
+
The data for monochrome images is stored using a single bit per sample. The routine create_monochrome_image_data
|
33
|
+
provides an easy way to create such data from a table of arbitrary sample values.
|
34
|
+
|
35
|
+
Monochrome images can also be used as a stencil mask for other images. You can supply a dictionary
|
36
|
+
with entries for a monochrome image as the value of the 'stencil_mask' entry for another call on show_image,
|
37
|
+
and the second image will then only be painted in the places where the stencil mask image would itself
|
38
|
+
be painted. Note that in this case, the second image and the stencil mask image need not have the
|
39
|
+
same number or rows or columns: each image rectangle is mapped to the figure using the same locations
|
40
|
+
for 'll', 'lr', and 'ul' so their boundaries will coincide even if they are different resolutions.
|
41
|
+
|
42
|
+
The 'color_space' entry is set to 'GRAY', 'gray', 'GREY', or 'grey' for a grayscale image. The data for
|
43
|
+
grayscale images is stored using one byte per sample. The routine create_monochrome_image_data provides
|
44
|
+
a handy way to create such data from a table of values.
|
45
|
+
|
46
|
+
Grayscale images can also be used as a "soft mask" for other images. In this case, the grayscale samples
|
47
|
+
are interpreted as relative opacities (a stencil mask, on the other hand, is "hard" in that each sample is either totally opaque or totally transparent). To use such soft masking, create a dictionary for the grayscale
|
48
|
+
image and provide it as the 'opacity_mask' entry for the image be be masked.
|
49
|
+
|
50
|
+
The 'color_space' entry is 'RGB' or 'rgb' for an image using the red-green-blue representation. Samples
|
51
|
+
are stored as three bytes, corresponding to red, green, and blue intensities.
|
52
|
+
In 4-color printing, as in ink-jet printers, images are painted using cyan, magenta, yellow, and black inks.
|
53
|
+
The corresponding 'color_space' is 'CMYK' or 'cmyk'. For this case, samples are stored as four bytes,
|
54
|
+
corresponding to cyan, magenta, yellow, and black intensitites.
|
55
|
+
|
56
|
+
Finally, many applications use "false colored" images to represent data values. The data is stored one byte
|
57
|
+
per sample, and a color map is used to determine the RGB intensities representing different sample values.
|
58
|
+
The routine create_image_data is available to help construct such a representation from a Dtable of
|
59
|
+
double precision samples. In some situations, the data may contain "out-of-range" or "invalid" entries
|
60
|
+
that should not be displayed. This can be accomplished by using a certain byte value to represent
|
61
|
+
such cases and providing a 'value_mask' entry with the image (this is also called "color key masking").
|
62
|
+
The value mask entry is a pair, [min_mask_byte max_mask_byte], and any samples whose value falls into
|
63
|
+
this range are not painted, allowing the existing background to show through. (For the common case in
|
64
|
+
which a single byte code is being used for all "out-of-range" data, 'value_mask' can simply be set to
|
65
|
+
this byte code.) The use of a 'value_mask' is in effect a
|
66
|
+
stencil mask that is determined on-the-fly by the sample values themselves. The routine create_image_data
|
67
|
+
has options for doing value masking.
|
68
|
+
|
69
|
+
Image Interpolation: When the resolution of a source image is significantly lower than that of the output
|
70
|
+
device,
|
71
|
+
each source sample covers many device pixels. This can cause images
|
72
|
+
to appear "jaggy". These visual artifacts can
|
73
|
+
be reduced by applying an
|
74
|
+
image interpolation algorithm during rendering. Instead of painting all pixels covered
|
75
|
+
by a source sample with the same color, image interpolation attempts to produce
|
76
|
+
a smooth transition between
|
77
|
+
adjacent sample values. Image interpolation is enabled by
|
78
|
+
default in Tioga; setting the 'interpolate' entry
|
79
|
+
in the image dictionary to +false+ should disable it
|
80
|
+
(but note that some PDF viewer implementations seem to ignore this flag).
|
81
|
+
|
82
|
+
Dictionary Entries
|
83
|
+
'll' => [x, y] # location for the lower-left corner of the image
|
84
|
+
'lr' => [x, y] # location for the lower-right corner of the image
|
85
|
+
'ul' => [x, y] # location for the upper-left corner of the image
|
86
|
+
'width' => an_integer # number of columns of samples in the image
|
87
|
+
'w' # alias for 'width'
|
88
|
+
'height' => an_integer # number of rows of samples in the image
|
89
|
+
'h' # alias for 'height'
|
90
|
+
'jpg' => a_string # file containing the JPEG image
|
91
|
+
'jpeg', 'JPEG', 'JPG' # aliases for 'jpg'
|
92
|
+
'color_space' => string_or_colormap # tells how to interpret the image data
|
93
|
+
'colormap' # alias for 'color_space'
|
94
|
+
'color_map' # alias for 'color_space'
|
95
|
+
'data' => a_string # samples with 'width' columns and 'height' rows
|
96
|
+
'value_mask' => [min_mask_byte max_mask_byte] # for color key masking of image
|
97
|
+
'value_mask' => byte_code_integer # sets both min_b
|
98
|
+
'stencil_mask' => a_mono_image_dict # for stencil masking of image
|
99
|
+
'opacity_mask' => a_grayscale_image_dict # for soft masking of image
|
100
|
+
'reversed' => true_or_false # default false. for mono images only.
|
101
|
+
'interpolate' => true_or_false # default true
|
102
|
+
|
103
|
+
Examples
|
104
|
+
|
105
|
+
On the left
|
106
|
+
show_image( # Cassini image of Jupiter with Io in foreground
|
107
|
+
'jpg' => "data/cassini.jpg", 'width' => 999, 'height' => 959,
|
108
|
+
'll' => [0.01, 0.01], 'lr' => [0.99, 0.01], 'ul' => [0.01, 0.99])
|
109
|
+
In the center
|
110
|
+
show_image( # same image of Jupiter
|
111
|
+
'jpg' => "data/cassini.jpg", 'width' => 999, 'height' => 959,
|
112
|
+
'll' => [0.01, 0.01], 'lr' => [0.99, 0.01], 'ul' => [0.01, 0.99])
|
113
|
+
fill_opacity = 0.6 # images can be partially transparent too
|
114
|
+
show_image( # Lucy amazed by Io
|
115
|
+
'jpg' => "data/lucy.jpg", 'width' => 148, 'height' => 164,
|
116
|
+
'll' => [0.52, 0.97], 'lr' => [0.41, 0.52], 'ul' => [0.12, 0.97])
|
117
|
+
On the right
|
118
|
+
1) show_image of lucy
|
119
|
+
2) create_monochrome_image_data for checker board pattern
|
120
|
+
3) show_image of Jupiter using the monochrome image data as a stencil_mask
|
121
|
+
|
122
|
+
http://theory.kitp.ucsb.edu/~paxton/tioga_jpegs/Sample_Jpegs.jpg
|
123
|
+
|
124
|
+
The following is a more lengthy example showing the use of a "false colored" image to
|
125
|
+
represent a 2 dimensional table of data. In this case, the data comes from
|
126
|
+
an astrophysical "equation of state" code that gives pressure as a function
|
127
|
+
of temperature and density. The data is read from a file (using Dtable.read),
|
128
|
+
converted to image samples (by create_image_data), and displayed (by show_image)
|
129
|
+
using one of the predefined colormaps (mellow_colormap). Since there is no data
|
130
|
+
for the high-temperature and low-density corner, that area is removed by a clip path
|
131
|
+
(see the clip_press_image method below). Finally, a color bar is added showing
|
132
|
+
the values for the different colors used in the image. The top-level plot method
|
133
|
+
is 'sampled_data' which shows the image in one subplot and the colorbar in another.
|
134
|
+
|
135
|
+
def sampled_data
|
136
|
+
t.rescale(0.8)
|
137
|
+
t.subplot('right_margin' => 0.07) { eos_image }
|
138
|
+
t.subplot(
|
139
|
+
'left_margin' => 0.95,
|
140
|
+
'top_margin' => 0.05,
|
141
|
+
'bottom_margin' => 0.05) { color_bar }
|
142
|
+
end
|
143
|
+
|
144
|
+
def eos_image
|
145
|
+
t.do_box_labels('Pressure', 'Log Density', 'Log Temperature')
|
146
|
+
data = get_press_image
|
147
|
+
xs = @eos_logRHOs
|
148
|
+
ys = @eos_logTs
|
149
|
+
t.show_plot('boundaries' => [@eos_xmin, @eos_xmax, @eos_ymax, @eos_ymin]) do
|
150
|
+
t.fill_color = Wheat
|
151
|
+
t.fill_frame
|
152
|
+
clip_press_image
|
153
|
+
t.show_image(
|
154
|
+
'll' => [xs.min, ys.min],
|
155
|
+
'lr' => [xs.max, ys.min],
|
156
|
+
'ul' => [xs.min, ys.max],
|
157
|
+
'color_space' => t.mellow_colormap,
|
158
|
+
'data' => data, 'value_mask' => 255,
|
159
|
+
'w' => @eos_data_xlen, 'h' => @eos_data_ylen)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
def get_press_image
|
164
|
+
@eos_xmin = -8.5; @eos_xmax = 2.5
|
165
|
+
@eos_ymin = 5.7; @eos_ymax = 7.0
|
166
|
+
@image_zmin = 8
|
167
|
+
@image_zmax = 18
|
168
|
+
data = Dvector.read("data/density.data")
|
169
|
+
@eos_logRHOs = data[0]
|
170
|
+
@eos_data_xlen = @eos_logRHOs.size
|
171
|
+
data = Dvector.read("data/temperature.data")
|
172
|
+
@eos_logTs = data[0]
|
173
|
+
@eos_data_ylen = @eos_logTs.size
|
174
|
+
@pres_data = Dtable.new(@eos_data_xlen, @eos_data_ylen)
|
175
|
+
@pres_data.read("data/pressure.data")
|
176
|
+
@pres_data.safe_log10!
|
177
|
+
return t.create_image_data(@pres_data.rotate_ccw90,
|
178
|
+
'min_value' => @image_zmin,
|
179
|
+
'max_value' => @image_zmax,
|
180
|
+
'masking' => true)
|
181
|
+
end
|
182
|
+
|
183
|
+
def clip_press_image
|
184
|
+
t.move_to_point(t.bounds_left, t.bounds_bottom)
|
185
|
+
t.append_point_to_path(t.bounds_left, 6.355)
|
186
|
+
t.append_point_to_path(-6.05, t.bounds_top)
|
187
|
+
t.append_point_to_path(t.bounds_right, t.bounds_top)
|
188
|
+
t.append_point_to_path(t.bounds_right, t.bounds_bottom)
|
189
|
+
t.close_path
|
190
|
+
t.clip
|
191
|
+
end
|
192
|
+
|
193
|
+
def color_bar
|
194
|
+
xmin = 0; xmax = 1; xmid = 0.5
|
195
|
+
t.rescale(0.8)
|
196
|
+
t.xaxis_type = AXIS_LINE_ONLY
|
197
|
+
t.xaxis_loc = BOTTOM
|
198
|
+
t.top_edge_type = AXIS_LINE_ONLY
|
199
|
+
t.yaxis_loc = t.ylabel_side = RIGHT
|
200
|
+
t.yaxis_type = AXIS_WITH_TICKS_AND_NUMERIC_LABELS
|
201
|
+
t.left_edge_type = AXIS_WITH_TICKS_ONLY
|
202
|
+
t.ylabel_shift += 0.5
|
203
|
+
t.yaxis_major_tick_length *= 0.6
|
204
|
+
t.yaxis_minor_tick_length *= 0.5
|
205
|
+
t.do_box_labels(nil, nil, 'Log Pressure')
|
206
|
+
t.show_plot('boundaries' => [xmin, xmax, @image_zmax, @image_zmin]) do
|
207
|
+
t.axial_shading(
|
208
|
+
'start_point' => [xmid, @image_zmin],
|
209
|
+
'end_point' => [xmid, @image_zmax],
|
210
|
+
'colormap' => t.mellow_colormap
|
211
|
+
)
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
http://theory.kitp.ucsb.edu/~paxton/tioga_jpegs/Sampled_Data.jpg
|
216
|
+
|
217
|
+
=end
|
218
|
+
def show_image(dict)
|
219
|
+
end
|
220
|
+
|
221
|
+
=begin rdoc
|
222
|
+
Creates a data representation suitable for use with show_image from the values in the Dtable _data_
|
223
|
+
according to the entries in the dictionary _dict_. Only _data_ rows between 'first_row' and
|
224
|
+
'last_row' and columns between 'first_column' and 'last_column' are included.
|
225
|
+
Data values between 'min_value' and 'max_value'
|
226
|
+
are mapped linearly to numbers between 0 and 'max_code' and then rounded to the nearest integer.
|
227
|
+
Data values less than 'min_value' are mapped to the integer specied by 'if_below_range', and
|
228
|
+
values greater than 'max_value' are mapped to the integer given by 'if_above_range'.
|
229
|
+
|
230
|
+
If the flag 'masking' is +true+, then 'max_code' is set to
|
231
|
+
254 and all data values out of range are assigned the code 255. The result can then be used in a call to
|
232
|
+
show_image with 'value_mask' set to 255 to prevent out-of-range values from being displayed.
|
233
|
+
|
234
|
+
Dictionary Entries
|
235
|
+
'first_row' => an_integer # first row of data to include (default 0)
|
236
|
+
'last_row' => an_integer # last row of data to include (default -1)
|
237
|
+
'first_column' => an_integer # first column of data to include (default 0)
|
238
|
+
'last_column' => an_integer # last column of data to include (default -1)
|
239
|
+
'min_value' => a_float # lower bound on valid data
|
240
|
+
'max_value' => a_float # upper bound on valid data
|
241
|
+
'masking' => true_or_false # default false
|
242
|
+
'max_code' => an_integer # integer between 1 and 255 (default 255)
|
243
|
+
'if_below_range' => an_integer # integer between 0 and 255 (default 0)
|
244
|
+
'if_above_range' => an_integer # integer between 0 and 255 (default max_code)
|
245
|
+
|
246
|
+
Example: For an image that only shows the data values between 0 and 1 and masks out other
|
247
|
+
values, you might do this:
|
248
|
+
|
249
|
+
create_image_data(data, 'min_value' => 0, 'max_value' => 1, 'masking' => true)
|
250
|
+
|
251
|
+
=end
|
252
|
+
def create_image_data(data, dict)
|
253
|
+
end
|
254
|
+
|
255
|
+
=begin rdoc
|
256
|
+
Creates a data representation suitable for use with show_image from the values in the Dtable _data_
|
257
|
+
according to the entries in the dictionary _dict_. Only _data_ rows between 'first_row' and
|
258
|
+
'last_row' and columns between 'first_column' and 'last_column' are included.
|
259
|
+
|
260
|
+
If the 'reverse' flag is +false+, values greater than 'boundary' map to 1's and other values map to 0's.
|
261
|
+
If 'reverse' is +true+, then values greater than 'boundary' map to 0's and other values map to 1's.
|
262
|
+
|
263
|
+
Dictionary Entries
|
264
|
+
'first_row' => an_integer # first row of data to include (default 0)
|
265
|
+
'last_row' => an_integer # last row of data to include (default -1)
|
266
|
+
'first_column' => an_integer # first column of data to include (default 0)
|
267
|
+
'last_column' => an_integer # last column of data to include (default -1)
|
268
|
+
'boundary' => a_float # default 0.0
|
269
|
+
'reverse' => true_or_false # default false
|
270
|
+
|
271
|
+
=end
|
272
|
+
def create_monochrome_image_data(data, dict)
|
273
|
+
end
|
274
|
+
|
275
|
+
|
276
|
+
|
277
|
+
end # class
|
278
|
+
end # module Tioga
|