# HG changeset patch
# User William Stein <wstein@gmail.com>
# Date 1200673284 28800
# Node ID b9a91aae0cef44760155acd7580732ed07174650
# Parent ed92b4e4e4ea6f35cd7fa529c5a242df3cf4b373
trac #1833 and #1737 -- 3d plot optimizations
diff -r ed92b4e4e4ea -r b9a91aae0cef sage/plot/plot3d/all.py
a
|
b
|
|
1 | 1 | |
2 | | from plot3d import plot3d, plot3d_adaptive |
| 2 | from plot3d import plot3d |
3 | 3 | from parametric_plot3d import parametric_plot3d |
4 | 4 | from list_plot3d import list_plot3d |
5 | 5 | |
diff -r ed92b4e4e4ea -r b9a91aae0cef sage/plot/plot3d/parametric_plot3d.py
a
|
b
|
def parametric_plot3d(f, urange, vrange= |
30 | 30 | INPUT: |
31 | 31 | f -- a 3-tuple of functions or expressions |
32 | 32 | urange -- a 2-tuple (u_min, u_max) or a 3-tuple (u, u_min, u_max) |
33 | | vrange -- (optional -- only used for surfaces) a 2-tuple (u_min, u_max) |
34 | | or a 3-tuple (u, u_min, u_max) |
| 33 | vrange -- (optional -- only used for surfaces) a 2-tuple (v_min, v_max) |
| 34 | or a 3-tuple (v, v_min, v_max) |
35 | 35 | plot_points -- (default: "automatic", which is 75 for curves and |
36 | 36 | [15,15] for surfaces) initial number of sample |
37 | 37 | points in each parameter; an integer for a curve, |
… |
… |
def parametric_plot3d_curve(f, urange, p |
179 | 179 | u, vals = var_and_list_of_values(urange, plot_points) |
180 | 180 | w = [] |
181 | 181 | fail = 0 |
182 | | |
| 182 | |
| 183 | if u is None: |
| 184 | try: |
| 185 | f, u, v = adapt_if_symbolic(f) |
| 186 | except TypeError: |
| 187 | pass |
| 188 | |
183 | 189 | if u is None: |
184 | 190 | f_x, f_y, f_z = f |
185 | 191 | for t in vals: |
… |
… |
def parametric_plot3d_surface(f, urange, |
212 | 218 | u, u_vals = var_and_list_of_values(urange, int(points0)) |
213 | 219 | v, v_vals = var_and_list_of_values(vrange, int(points1)) |
214 | 220 | |
| 221 | if u is None and v is None: |
| 222 | try: |
| 223 | f, u, v = adapt_if_symbolic(f) |
| 224 | except TypeError: |
| 225 | pass |
| 226 | |
215 | 227 | if u is None: |
216 | 228 | if not v is None: |
217 | 229 | raise ValueError, "both ranges must specify a variable or neither must" |
… |
… |
def parametric_plot3d_surface(f, urange, |
233 | 245 | return (float(f_x(x,y)), float(f_y(x,y)), float(f_z(x,y))) |
234 | 246 | |
235 | 247 | return ParametricSurface(g, (u_vals, v_vals), **kwds) |
| 248 | |
| 249 | |
| 250 | |
| 251 | def adapt_if_symbolic(f): |
| 252 | """ |
| 253 | If f is symbolic find the variables u, v to substitute into f. |
| 254 | Otherwise raise a TypeError. |
| 255 | |
| 256 | This function is used internally by the plot commands for |
| 257 | efficiency reasons only. |
| 258 | """ |
| 259 | from sage.calculus.calculus import is_SymbolicExpression, SR |
| 260 | if sum([is_SymbolicExpression(a) for a in f]) > 0: |
| 261 | g = [SR(a) for a in f] |
| 262 | vars = list(set(sum([list(a.variables()) for a in g], []))) |
| 263 | vars.sort() |
| 264 | if len(vars) > 0: |
| 265 | u = vars[0] |
| 266 | if len(vars) > 1: |
| 267 | v = vars[1] |
| 268 | else: |
| 269 | v = None |
| 270 | return g, u, v |
| 271 | else: |
| 272 | g = [lambda x: float(a) for a in g] |
| 273 | return g, None, None |
| 274 | |
diff -r ed92b4e4e4ea -r b9a91aae0cef sage/plot/plot3d/plot3d.py
a
|
b
|
r""" |
1 | 1 | r""" |
2 | 2 | Plotting Functions. |
3 | 3 | |
4 | | EXAMPLES: |
| 4 | EXAMPLES: |
5 | 5 | sage: def f(x,y): |
6 | 6 | ... return math.sin(y*y+x*x)/math.sqrt(x*x+y*y+.0001) |
7 | 7 | ... |
8 | | sage: P = plot3d_adaptive(f,(-3,3),(-3,3), color=rainbow(60, 'rgbtuple'), max_bend=.1, max_depth=15) |
| 8 | sage: P = plot3d(f,(-3,3),(-3,3), adaptive=True, color=rainbow(60, 'rgbtuple'), max_bend=.1, max_depth=15) |
9 | 9 | sage: P.show() |
10 | 10 | |
11 | 11 | sage: def f(x,y): |
12 | 12 | ... return math.exp(x/5)*math.sin(y) |
13 | 13 | ... |
14 | | sage: P = plot3d_adaptive(f,(-5,5),(-5,5), color=['red','yellow']) |
| 14 | sage: P = plot3d(f,(-5,5),(-5,5), adaptive=True, color=['red','yellow']) |
15 | 15 | sage: from sage.plot.plot3d.plot3d import axes |
16 | 16 | sage: S = P + axes(6, color='black') |
17 | 17 | sage: S.show() |
… |
… |
We plot "cape man": |
26 | 26 | sage: S += sphere((.45, .1,.15),size=.1, color='white') + sphere((.51, .1,.17), size=.05, color='black') |
27 | 27 | sage: S += sphere((.5,0,-.2),size=.1, color='yellow') |
28 | 28 | sage: def f(x,y): return math.exp(x/5)*math.cos(y) |
29 | | sage: P = plot3d_adaptive(f,(-5,5),(-5,5), ['red','yellow'], max_depth=10) |
| 29 | sage: P = plot3d(f,(-5,5),(-5,5), adaptive=True, color=['red','yellow'], max_depth=10) |
30 | 30 | sage: cape_man = P.scale(.2) + S.translate(1,0,0) |
31 | | sage: cape_man |
| 31 | sage: cape_man.show(aspect_ratio=[1,1,1]) |
32 | 32 | |
33 | 33 | AUTHOR: |
34 | 34 | -- Tom Boothby: adaptive refinement triangles |
… |
… |
class TrivialTriangleFactory: |
71 | 71 | return [a,b,c] |
72 | 72 | |
73 | 73 | import parametric_plot3d |
74 | | def plot3d(f, urange, vrange, **kwds): |
| 74 | def plot3d(f, urange, vrange, adaptive=False, **kwds): |
75 | 75 | """ |
| 76 | INPUT: |
| 77 | f -- a symbolic expression or function of 2 variables |
| 78 | urange -- a 2-tuple (u_min, u_max) or a 3-tuple (u, u_min, u_max) |
| 79 | vrange -- a 2-tuple (v_min, v_max) or a 3-tuple (v, v_min, v_max) |
| 80 | adaptive -- (default: False) whether to use adaptive refinement |
| 81 | to draw the plot (slower, but may look better) |
| 82 | |
76 | 83 | EXAMPLES: |
77 | 84 | We plot a 3d function defined as a Python function: |
78 | 85 | sage: plot3d(lambda x, y: x^2 + y^2, (-2,2), (-2,2)) |
| 86 | |
| 87 | We plot the same 3d function but using adaptive refinement: |
| 88 | sage: plot3d(lambda x, y: x^2 + y^2, (-2,2), (-2,2), adaptive=True) |
| 89 | |
| 90 | Adaptive refinement but with more points: |
| 91 | sage: plot3d(lambda x, y: x^2 + y^2, (-2,2), (-2,2), adaptive=True, initial_depth=5) |
79 | 92 | |
80 | 93 | We plot some 3d symbolic functions: |
81 | 94 | sage: x, y = var('x,y') |
… |
… |
def plot3d(f, urange, vrange, **kwds): |
84 | 97 | |
85 | 98 | Two wobby translucent planes: |
86 | 99 | sage: x,y = var('x,y') |
87 | | sage: P = plot3d(x+y+sin(x*y), (x,-10,10),(y,-10,10), opacity=0.87) |
| 100 | sage: P = plot3d(x+y+sin(x*y), (x,-10,10),(y,-10,10), opacity=0.87, color='blue') |
88 | 101 | sage: Q = plot3d(x-2*y-cos(x*y),(x,-10,10),(y,-10,10),opacity=0.3,color='red') |
89 | 102 | sage: P + Q |
90 | 103 | |
… |
… |
def plot3d(f, urange, vrange, **kwds): |
95 | 108 | sage: L + P + Q |
96 | 109 | """ |
97 | 110 | if len(urange) == 2: |
98 | | w = (lambda u,v: u, lambda u,v: v, f) |
| 111 | from parametric_plot3d import adapt_if_symbolic |
| 112 | try: |
| 113 | f, u,v = adapt_if_symbolic((f,1,1)) |
| 114 | f = f[0] |
| 115 | w = (u, v, f) |
| 116 | urange = (u, urange[0], urange[1]) |
| 117 | vrange = (v, vrange[0], vrange[1]) |
| 118 | except TypeError: |
| 119 | w = (lambda u,v: u, lambda u,v: v, f) |
99 | 120 | else: |
100 | 121 | u = urange[0] |
101 | 122 | v = vrange[0] |
102 | 123 | w = (u, v, f) |
103 | | P = parametric_plot3d.parametric_plot3d(w, urange, vrange, **kwds) |
| 124 | |
| 125 | if adaptive: |
| 126 | P = plot3d_adaptive(f, urange, vrange, **kwds) |
| 127 | else: |
| 128 | P = parametric_plot3d.parametric_plot3d(w, urange, vrange, **kwds) |
104 | 129 | P.frame_aspect_ratio([1.0,1.0,0.5]) |
105 | 130 | return P |
106 | 131 | |
107 | 132 | def plot3d_adaptive(f, x_range, y_range, color="automatic", |
108 | 133 | grad_f=None, |
109 | 134 | max_bend=.5, max_depth=5, initial_depth=4, num_colors=128, **kwds): |
110 | | """ |
| 135 | r""" |
111 | 136 | Adaptive 3d plotting of a function of two variables. |
| 137 | |
| 138 | This is used internally by the plot3d command when the option |
| 139 | \code{adaptive=True} is given. |
112 | 140 | |
113 | 141 | INPUT: |
114 | 142 | f -- a symbolic function or a Python function of 3 variables. |
… |
… |
def plot3d_adaptive(f, x_range, y_range, |
123 | 151 | **kwds -- standard graphics parameters |
124 | 152 | |
125 | 153 | EXAMPLES: |
126 | | We plot sin(xy): |
| 154 | We plot $\sin(xy)$: |
| 155 | sage: from sage.plot.plot3d.plot3d import plot3d_adaptive |
127 | 156 | sage: x,y=var('x,y'); plot3d_adaptive(sin(x*y), (x,-pi,pi), (y,-pi,pi), initial_depth=5) |
128 | 157 | |
129 | 158 | """ |