passagemath-plot 10.6.31rc3__cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
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.
Potentially problematic release.
This version of passagemath-plot might be problematic. Click here for more details.
- passagemath_plot-10.6.31rc3.dist-info/METADATA +172 -0
- passagemath_plot-10.6.31rc3.dist-info/RECORD +82 -0
- passagemath_plot-10.6.31rc3.dist-info/WHEEL +6 -0
- passagemath_plot-10.6.31rc3.dist-info/top_level.txt +2 -0
- passagemath_plot.libs/libgfortran-83c28eba.so.5.0.0 +0 -0
- passagemath_plot.libs/libgsl-cda90e79.so.28.0.0 +0 -0
- passagemath_plot.libs/libopenblasp-r0-6dcb67f9.3.29.so +0 -0
- passagemath_plot.libs/libquadmath-2284e583.so.0.0.0 +0 -0
- sage/all__sagemath_plot.py +15 -0
- sage/ext_data/threejs/animation.css +195 -0
- sage/ext_data/threejs/animation.html +85 -0
- sage/ext_data/threejs/animation.js +273 -0
- sage/ext_data/threejs/fat_lines.js +48 -0
- sage/ext_data/threejs/threejs-version.txt +1 -0
- sage/ext_data/threejs/threejs_template.html +597 -0
- sage/interfaces/all__sagemath_plot.py +1 -0
- sage/interfaces/gnuplot.py +196 -0
- sage/interfaces/jmoldata.py +208 -0
- sage/interfaces/povray.py +56 -0
- sage/plot/all.py +42 -0
- sage/plot/animate.py +1796 -0
- sage/plot/arc.py +504 -0
- sage/plot/arrow.py +671 -0
- sage/plot/bar_chart.py +205 -0
- sage/plot/bezier_path.py +400 -0
- sage/plot/circle.py +435 -0
- sage/plot/colors.py +1606 -0
- sage/plot/complex_plot.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/plot/complex_plot.pyx +1446 -0
- sage/plot/contour_plot.py +1792 -0
- sage/plot/density_plot.py +318 -0
- sage/plot/disk.py +373 -0
- sage/plot/ellipse.py +375 -0
- sage/plot/graphics.py +3580 -0
- sage/plot/histogram.py +354 -0
- sage/plot/hyperbolic_arc.py +404 -0
- sage/plot/hyperbolic_polygon.py +416 -0
- sage/plot/hyperbolic_regular_polygon.py +296 -0
- sage/plot/line.py +626 -0
- sage/plot/matrix_plot.py +629 -0
- sage/plot/misc.py +509 -0
- sage/plot/multigraphics.py +1294 -0
- sage/plot/plot.py +4183 -0
- sage/plot/plot3d/all.py +23 -0
- sage/plot/plot3d/base.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/plot/plot3d/base.pxd +12 -0
- sage/plot/plot3d/base.pyx +3378 -0
- sage/plot/plot3d/implicit_plot3d.py +659 -0
- sage/plot/plot3d/implicit_surface.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/plot/plot3d/implicit_surface.pyx +1453 -0
- sage/plot/plot3d/index_face_set.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/plot/plot3d/index_face_set.pxd +32 -0
- sage/plot/plot3d/index_face_set.pyx +1873 -0
- sage/plot/plot3d/introduction.py +131 -0
- sage/plot/plot3d/list_plot3d.py +649 -0
- sage/plot/plot3d/parametric_plot3d.py +1130 -0
- sage/plot/plot3d/parametric_surface.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/plot/plot3d/parametric_surface.pxd +12 -0
- sage/plot/plot3d/parametric_surface.pyx +893 -0
- sage/plot/plot3d/platonic.py +601 -0
- sage/plot/plot3d/plot3d.py +1442 -0
- sage/plot/plot3d/plot_field3d.py +162 -0
- sage/plot/plot3d/point_c.pxi +148 -0
- sage/plot/plot3d/revolution_plot3d.py +309 -0
- sage/plot/plot3d/shapes.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/plot/plot3d/shapes.pxd +22 -0
- sage/plot/plot3d/shapes.pyx +1382 -0
- sage/plot/plot3d/shapes2.py +1512 -0
- sage/plot/plot3d/tachyon.py +1779 -0
- sage/plot/plot3d/texture.py +453 -0
- sage/plot/plot3d/transform.cpython-314-x86_64-linux-gnu.so +0 -0
- sage/plot/plot3d/transform.pxd +21 -0
- sage/plot/plot3d/transform.pyx +268 -0
- sage/plot/plot3d/tri_plot.py +589 -0
- sage/plot/plot_field.py +362 -0
- sage/plot/point.py +624 -0
- sage/plot/polygon.py +562 -0
- sage/plot/primitive.py +249 -0
- sage/plot/scatter_plot.py +199 -0
- sage/plot/step.py +85 -0
- sage/plot/streamline_plot.py +328 -0
- sage/plot/text.py +432 -0
|
@@ -0,0 +1,649 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-plot
|
|
2
|
+
"""
|
|
3
|
+
List plots
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from sage.structure.element import Matrix
|
|
7
|
+
from sage.matrix.constructor import matrix
|
|
8
|
+
from sage.rings.real_double import RDF
|
|
9
|
+
from sage.misc.superseded import deprecation
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def list_plot3d(v, interpolation_type='default', point_list=None, **kwds):
|
|
13
|
+
r"""
|
|
14
|
+
A 3-dimensional plot of a surface defined by the list `v`
|
|
15
|
+
of points in 3-dimensional space.
|
|
16
|
+
|
|
17
|
+
INPUT:
|
|
18
|
+
|
|
19
|
+
- ``v`` -- something that defines a set of points in 3 space:
|
|
20
|
+
|
|
21
|
+
- a matrix
|
|
22
|
+
|
|
23
|
+
- a list of 3-tuples
|
|
24
|
+
|
|
25
|
+
- a list of lists (all of the same length) -- this is treated the same as
|
|
26
|
+
a matrix
|
|
27
|
+
|
|
28
|
+
OPTIONAL KEYWORDS:
|
|
29
|
+
|
|
30
|
+
- ``interpolation_type`` -- 'linear', 'clough' (CloughTocher2D), 'spline'
|
|
31
|
+
|
|
32
|
+
'linear' will perform linear interpolation
|
|
33
|
+
|
|
34
|
+
The option 'clough' will interpolate by using a piecewise cubic
|
|
35
|
+
interpolating Bezier polynomial on each triangle, using a
|
|
36
|
+
Clough-Tocher scheme. The interpolant is guaranteed to be
|
|
37
|
+
continuously differentiable. The gradients of the interpolant
|
|
38
|
+
are chosen so that the curvature of the interpolating surface is
|
|
39
|
+
approximately minimized.
|
|
40
|
+
|
|
41
|
+
The option 'spline' interpolates using a bivariate B-spline.
|
|
42
|
+
|
|
43
|
+
When v is a matrix the default is to use linear interpolation, when
|
|
44
|
+
v is a list of points the default is 'clough'.
|
|
45
|
+
|
|
46
|
+
- ``degree`` -- integer between 1 and 5, controls the degree of spline
|
|
47
|
+
used for spline interpolation. For data that is highly oscillatory
|
|
48
|
+
use higher values
|
|
49
|
+
|
|
50
|
+
- ``point_list`` -- if ``point_list=True`` is passed, then if the array
|
|
51
|
+
is a list of lists of length three, it will be treated as an
|
|
52
|
+
array of points rather than a 3xn array.
|
|
53
|
+
|
|
54
|
+
- ``num_points`` -- number of points to sample interpolating
|
|
55
|
+
function in each direction, when ``interpolation_type`` is not
|
|
56
|
+
``default``. By default for an `n\times n` array this is `n`.
|
|
57
|
+
|
|
58
|
+
- ``**kwds`` -- all other arguments are passed to the surface function
|
|
59
|
+
|
|
60
|
+
OUTPUT: a 3d plot
|
|
61
|
+
|
|
62
|
+
EXAMPLES:
|
|
63
|
+
|
|
64
|
+
We plot a matrix that illustrates summation modulo `n`::
|
|
65
|
+
|
|
66
|
+
sage: n = 5
|
|
67
|
+
sage: list_plot3d(matrix(RDF, n, [(i+j)%n for i in [1..n] for j in [1..n]]))
|
|
68
|
+
Graphics3d Object
|
|
69
|
+
|
|
70
|
+
.. PLOT::
|
|
71
|
+
|
|
72
|
+
sphinx_plot(list_plot3d(matrix(RDF, 5, [(i+j)%5 for i in range(1,6) for j in range(1,6)])))
|
|
73
|
+
|
|
74
|
+
We plot a matrix of values of ``sin``::
|
|
75
|
+
|
|
76
|
+
sage: from math import pi
|
|
77
|
+
sage: m = matrix(RDF, 6, [sin(i^2 + j^2)
|
|
78
|
+
....: for i in [0,pi/5,..,pi] for j in [0,pi/5,..,pi]])
|
|
79
|
+
sage: list_plot3d(m, color='yellow', frame_aspect_ratio=[1, 1, 1/3])
|
|
80
|
+
Graphics3d Object
|
|
81
|
+
|
|
82
|
+
.. PLOT::
|
|
83
|
+
|
|
84
|
+
pi = float(pi)
|
|
85
|
+
import numpy as np
|
|
86
|
+
m = matrix(RDF, 6, [sin(i**2 + j**2) for i in np.linspace(0,pi,6) for j in np.linspace(0,pi,6)])
|
|
87
|
+
sphinx_plot(list_plot3d(m, color='yellow', frame_aspect_ratio=[1, 1, 1/3]))
|
|
88
|
+
|
|
89
|
+
Though it does not change the shape of the graph, increasing
|
|
90
|
+
``num_points`` can increase the clarity of the graph::
|
|
91
|
+
|
|
92
|
+
sage: list_plot3d(m, color='yellow', num_points=40,
|
|
93
|
+
....: frame_aspect_ratio=[1, 1, 1/3])
|
|
94
|
+
Graphics3d Object
|
|
95
|
+
|
|
96
|
+
.. PLOT::
|
|
97
|
+
|
|
98
|
+
pi = float(pi)
|
|
99
|
+
import numpy as np
|
|
100
|
+
m = matrix(RDF, 6, [sin(i**2 + j**2) for i in np.linspace(0,pi,6) for j in np.linspace(0,pi,6)])
|
|
101
|
+
sphinx_plot(list_plot3d(m, color='yellow', frame_aspect_ratio=[1, 1, 1/3], num_points=40))
|
|
102
|
+
|
|
103
|
+
We can change the interpolation type::
|
|
104
|
+
|
|
105
|
+
sage: import warnings
|
|
106
|
+
sage: warnings.simplefilter('ignore', UserWarning)
|
|
107
|
+
sage: list_plot3d(m, color='yellow', interpolation_type='clough',
|
|
108
|
+
....: frame_aspect_ratio=[1, 1, 1/3])
|
|
109
|
+
Graphics3d Object
|
|
110
|
+
|
|
111
|
+
.. PLOT::
|
|
112
|
+
|
|
113
|
+
import warnings
|
|
114
|
+
warnings.simplefilter('ignore', UserWarning)
|
|
115
|
+
import numpy as np
|
|
116
|
+
pi = float(pi)
|
|
117
|
+
m = matrix(RDF, 6, [sin(i**2 + j**2) for i in np.linspace(0,pi,6) for j in np.linspace(0,pi,6)])
|
|
118
|
+
sphinx_plot(list_plot3d(m, color='yellow', interpolation_type='clough', frame_aspect_ratio=[1, 1, 1/3]))
|
|
119
|
+
|
|
120
|
+
We can make this look better by increasing the number of samples::
|
|
121
|
+
|
|
122
|
+
sage: list_plot3d(m, color='yellow', interpolation_type='clough',
|
|
123
|
+
....: frame_aspect_ratio=[1, 1, 1/3], num_points=40)
|
|
124
|
+
Graphics3d Object
|
|
125
|
+
|
|
126
|
+
.. PLOT::
|
|
127
|
+
|
|
128
|
+
import numpy as np
|
|
129
|
+
pi = float(pi)
|
|
130
|
+
m = matrix(RDF, 6, [sin(i**2 + j**2) for i in np.linspace(0,pi,6) for j in np.linspace(0,pi,6)])
|
|
131
|
+
sphinx_plot(list_plot3d(m, color='yellow', interpolation_type='clough', frame_aspect_ratio=[1, 1, 1/3], num_points=40))
|
|
132
|
+
|
|
133
|
+
Let us try a spline::
|
|
134
|
+
|
|
135
|
+
sage: list_plot3d(m, color='yellow', interpolation_type='spline',
|
|
136
|
+
....: frame_aspect_ratio=[1, 1, 1/3])
|
|
137
|
+
Graphics3d Object
|
|
138
|
+
|
|
139
|
+
.. PLOT::
|
|
140
|
+
|
|
141
|
+
import numpy as np
|
|
142
|
+
pi = float(pi)
|
|
143
|
+
m = matrix(RDF, 6, [sin(i**2 + j**2) for i in np.linspace(0,pi,6) for j in np.linspace(0,pi,6)])
|
|
144
|
+
sphinx_plot(list_plot3d(m, color='yellow', interpolation_type='spline', frame_aspect_ratio=[1, 1, 1/3]))
|
|
145
|
+
|
|
146
|
+
That spline does not capture the oscillation very well; let's try a
|
|
147
|
+
higher degree spline::
|
|
148
|
+
|
|
149
|
+
sage: list_plot3d(m, color='yellow', interpolation_type='spline', degree=5,
|
|
150
|
+
....: frame_aspect_ratio=[1, 1, 1/3])
|
|
151
|
+
Graphics3d Object
|
|
152
|
+
|
|
153
|
+
.. PLOT::
|
|
154
|
+
|
|
155
|
+
import numpy as np
|
|
156
|
+
pi = float(pi)
|
|
157
|
+
m = matrix(RDF, 6, [sin(i**2 + j**2) for i in np.linspace(0,pi,6) for j in np.linspace(0,pi,6)])
|
|
158
|
+
sphinx_plot(list_plot3d(m, color='yellow', interpolation_type='spline', degree=5, frame_aspect_ratio=[1, 1, 1/3]))
|
|
159
|
+
|
|
160
|
+
We plot a list of lists::
|
|
161
|
+
|
|
162
|
+
sage: show(list_plot3d([[1, 1, 1, 1], [1, 2, 1, 2], [1, 1, 3, 1], [1, 2, 1, 4]]))
|
|
163
|
+
|
|
164
|
+
.. PLOT::
|
|
165
|
+
|
|
166
|
+
sphinx_plot(list_plot3d([[1, 1, 1, 1], [1, 2, 1, 2], [1, 1, 3, 1], [1, 2, 1, 4]]))
|
|
167
|
+
|
|
168
|
+
We plot a list of points. As a first example we can extract the
|
|
169
|
+
(x,y,z) coordinates from the above example and make a list plot
|
|
170
|
+
out of it. By default we do linear interpolation::
|
|
171
|
+
|
|
172
|
+
sage: l = []
|
|
173
|
+
sage: for i in range(6):
|
|
174
|
+
....: for j in range(6):
|
|
175
|
+
....: l.append((float(i*pi/5), float(j*pi/5), m[i, j]))
|
|
176
|
+
sage: list_plot3d(l, color='red')
|
|
177
|
+
Graphics3d Object
|
|
178
|
+
|
|
179
|
+
.. PLOT::
|
|
180
|
+
|
|
181
|
+
l = []
|
|
182
|
+
import numpy as np
|
|
183
|
+
pi = float(pi)
|
|
184
|
+
m = matrix(RDF, 6, [sin(i**2 + j**2) for i in np.linspace(0,pi,6) for j in np.linspace(0,pi,6)])
|
|
185
|
+
for i in range(6):
|
|
186
|
+
for j in range(6):
|
|
187
|
+
l.append((float(i*pi/5), float(j*pi/5), m[i, j]))
|
|
188
|
+
sphinx_plot(list_plot3d(l, color='red'))
|
|
189
|
+
|
|
190
|
+
Note that the points do not have to be regularly sampled. For example::
|
|
191
|
+
|
|
192
|
+
sage: l = []
|
|
193
|
+
sage: for i in range(-5, 5):
|
|
194
|
+
....: for j in range(-5, 5):
|
|
195
|
+
....: l.append((normalvariate(0, 1),
|
|
196
|
+
....: normalvariate(0, 1),
|
|
197
|
+
....: normalvariate(0, 1)))
|
|
198
|
+
sage: L = list_plot3d(l, interpolation_type='clough',
|
|
199
|
+
....: color='orange', num_points=100)
|
|
200
|
+
sage: L
|
|
201
|
+
Graphics3d Object
|
|
202
|
+
|
|
203
|
+
.. PLOT::
|
|
204
|
+
|
|
205
|
+
l = []
|
|
206
|
+
import numpy as np
|
|
207
|
+
pi = float(pi)
|
|
208
|
+
m = matrix(RDF, 6, [sin(i**2 + j**2) for i in np.linspace(0,pi,6) for j in np.linspace(0,pi,6)])
|
|
209
|
+
for i in range(-5, 5):
|
|
210
|
+
for j in range(-5, 5):
|
|
211
|
+
l.append((normalvariate(0, 1), normalvariate(0, 1), normalvariate(0, 1)))
|
|
212
|
+
L = list_plot3d(l, interpolation_type='clough', color='orange', num_points=100)
|
|
213
|
+
sphinx_plot(L)
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
Check that no NaNs are produced (see :issue:`13135`)::
|
|
217
|
+
|
|
218
|
+
sage: any(math.isnan(c) for v in L.vertices() for c in v)
|
|
219
|
+
False
|
|
220
|
+
|
|
221
|
+
TESTS:
|
|
222
|
+
|
|
223
|
+
We plot 0, 1, and 2 points::
|
|
224
|
+
|
|
225
|
+
sage: list_plot3d([])
|
|
226
|
+
Graphics3d Object
|
|
227
|
+
|
|
228
|
+
sage: list_plot3d([(2, 3, 4)])
|
|
229
|
+
Graphics3d Object
|
|
230
|
+
|
|
231
|
+
sage: list_plot3d([(0, 0, 1), (2, 3, 4)])
|
|
232
|
+
Graphics3d Object
|
|
233
|
+
|
|
234
|
+
However, if two points are given with the same x,y coordinates but
|
|
235
|
+
different z coordinates, an exception will be raised::
|
|
236
|
+
|
|
237
|
+
sage: pts = [(-4/5, -2/5, -2/5), (-4/5, -2/5, 2/5), (-4/5, 2/5, -2/5), (-4/5, 2/5, 2/5), (-2/5, -4/5, -2/5), (-2/5, -4/5, 2/5), (-2/5, -2/5, -4/5), (-2/5, -2/5, 4/5), (-2/5, 2/5, -4/5), (-2/5, 2/5, 4/5), (-2/5, 4/5, -2/5), (-2/5, 4/5, 2/5), (2/5, -4/5, -2/5), (2/5, -4/5, 2/5), (2/5, -2/5, -4/5), (2/5, -2/5, 4/5), (2/5, 2/5, -4/5), (2/5, 2/5, 4/5), (2/5, 4/5, -2/5), (2/5, 4/5, 2/5), (4/5, -2/5, -2/5), (4/5, -2/5, 2/5), (4/5, 2/5, -2/5), (4/5, 2/5, 2/5)]
|
|
238
|
+
sage: show(list_plot3d(pts, interpolation_type='clough'))
|
|
239
|
+
Traceback (most recent call last):
|
|
240
|
+
...
|
|
241
|
+
ValueError: points with same x,y coordinates and different
|
|
242
|
+
z coordinates were given. Interpolation cannot handle this.
|
|
243
|
+
|
|
244
|
+
Additionally we need at least 3 points to do the interpolation::
|
|
245
|
+
|
|
246
|
+
sage: mat = matrix(RDF, 1, 2, [3.2, 1.550])
|
|
247
|
+
sage: show(list_plot3d(mat, interpolation_type='clough'))
|
|
248
|
+
Traceback (most recent call last):
|
|
249
|
+
...
|
|
250
|
+
ValueError: we need at least 3 points to perform the interpolation
|
|
251
|
+
|
|
252
|
+
TESTS::
|
|
253
|
+
|
|
254
|
+
sage: P = list_plot3d([(0, 0, 1), (2, 3, 4)], texture='tomato')
|
|
255
|
+
doctest:warning...:
|
|
256
|
+
DeprecationWarning: please use 'color' instead of 'texture'
|
|
257
|
+
See https://github.com/sagemath/sage/issues/27084 for details.
|
|
258
|
+
"""
|
|
259
|
+
import numpy
|
|
260
|
+
if 'texture' in kwds:
|
|
261
|
+
deprecation(27084, "please use 'color' instead of 'texture'")
|
|
262
|
+
txtr = kwds.pop('texture')
|
|
263
|
+
if txtr == "automatic":
|
|
264
|
+
txtr = "lightblue"
|
|
265
|
+
kwds['color'] = txtr
|
|
266
|
+
if isinstance(v, Matrix):
|
|
267
|
+
if (interpolation_type == 'default' or
|
|
268
|
+
interpolation_type == 'linear' and 'num_points' not in kwds):
|
|
269
|
+
return list_plot3d_matrix(v, **kwds)
|
|
270
|
+
else:
|
|
271
|
+
data = [(i, j, v[i, j])
|
|
272
|
+
for i in range(v.nrows())
|
|
273
|
+
for j in range(v.ncols())]
|
|
274
|
+
return list_plot3d_tuples(data, interpolation_type, **kwds)
|
|
275
|
+
|
|
276
|
+
if isinstance(v, numpy.ndarray):
|
|
277
|
+
return list_plot3d(matrix(v), interpolation_type, **kwds)
|
|
278
|
+
|
|
279
|
+
if isinstance(v, list):
|
|
280
|
+
if not v:
|
|
281
|
+
# return empty 3d graphic
|
|
282
|
+
from .base import Graphics3d
|
|
283
|
+
return Graphics3d()
|
|
284
|
+
elif len(v) == 1:
|
|
285
|
+
# return a point
|
|
286
|
+
from .shapes2 import point3d
|
|
287
|
+
return point3d(v[0], **kwds)
|
|
288
|
+
elif len(v) == 2:
|
|
289
|
+
# return a line
|
|
290
|
+
from .shapes2 import line3d
|
|
291
|
+
return line3d(v, **kwds)
|
|
292
|
+
elif isinstance(v[0], tuple) or point_list and len(v[0]) == 3:
|
|
293
|
+
return list_plot3d_tuples(v, interpolation_type, **kwds)
|
|
294
|
+
else:
|
|
295
|
+
return list_plot3d_array_of_arrays(v, interpolation_type, **kwds)
|
|
296
|
+
raise TypeError("v must be a matrix or list")
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
def list_plot3d_matrix(m, **kwds):
|
|
300
|
+
"""
|
|
301
|
+
A 3-dimensional plot of a surface defined by a matrix ``M``
|
|
302
|
+
defining points in 3-dimensional space.
|
|
303
|
+
|
|
304
|
+
See :func:`list_plot3d` for full details.
|
|
305
|
+
|
|
306
|
+
INPUT:
|
|
307
|
+
|
|
308
|
+
- ``M`` -- a matrix
|
|
309
|
+
|
|
310
|
+
OPTIONAL KEYWORDS:
|
|
311
|
+
|
|
312
|
+
- ``**kwds`` -- all other arguments are passed to the surface function
|
|
313
|
+
|
|
314
|
+
OUTPUT: a 3d plot
|
|
315
|
+
|
|
316
|
+
EXAMPLES:
|
|
317
|
+
|
|
318
|
+
We plot a matrix that illustrates summation modulo `n`::
|
|
319
|
+
|
|
320
|
+
sage: n = 5
|
|
321
|
+
sage: list_plot3d(matrix(RDF, n, [(i+j) % n # indirect doctest
|
|
322
|
+
....: for i in [1..n] for j in [1..n]]))
|
|
323
|
+
Graphics3d Object
|
|
324
|
+
|
|
325
|
+
.. PLOT::
|
|
326
|
+
|
|
327
|
+
sphinx_plot(list_plot3d(matrix(RDF, 5, [(i+j)%5 for i in range(1,6) for j in range(1,6)])))
|
|
328
|
+
|
|
329
|
+
The interpolation type for matrices is 'linear'; for other types
|
|
330
|
+
use other :func:`list_plot3d` input types.
|
|
331
|
+
|
|
332
|
+
We plot a matrix of values of `sin`::
|
|
333
|
+
|
|
334
|
+
sage: from math import pi
|
|
335
|
+
sage: m = matrix(RDF, 6, [sin(i^2 + j^2)
|
|
336
|
+
....: for i in [0,pi/5,..,pi] for j in [0,pi/5,..,pi]])
|
|
337
|
+
sage: list_plot3d(m, color='yellow', frame_aspect_ratio=[1, 1, 1/3]) # indirect doctest
|
|
338
|
+
Graphics3d Object
|
|
339
|
+
|
|
340
|
+
.. PLOT::
|
|
341
|
+
|
|
342
|
+
import numpy as np
|
|
343
|
+
pi = float(pi)
|
|
344
|
+
m = matrix(RDF, 6, [sin(i**2 + j**2) for i in np.linspace(0,pi,6) for j in np.linspace(0,pi,6)])
|
|
345
|
+
sphinx_plot(list_plot3d(m, color='yellow', frame_aspect_ratio=[1, 1, 1/3]))
|
|
346
|
+
|
|
347
|
+
::
|
|
348
|
+
sage: list_plot3d(m, color='yellow', interpolation_type='linear') # indirect doctest
|
|
349
|
+
Graphics3d Object
|
|
350
|
+
|
|
351
|
+
.. PLOT::
|
|
352
|
+
|
|
353
|
+
import numpy as np
|
|
354
|
+
pi = float(pi)
|
|
355
|
+
m = matrix(RDF, 6, [sin(i**2 + j**2) for i in np.linspace(0,pi,6) for j in np.linspace(0,pi,6)])
|
|
356
|
+
sphinx_plot(list_plot3d(m, color='yellow', interpolation_type='linear'))
|
|
357
|
+
|
|
358
|
+
Here is a colored example, using a colormap and a coloring function
|
|
359
|
+
which must take values in (0, 1)::
|
|
360
|
+
|
|
361
|
+
sage: cm = colormaps.rainbow
|
|
362
|
+
sage: n = 20
|
|
363
|
+
sage: cf = lambda x, y: ((2*(x-y)/n)**2) % 1
|
|
364
|
+
sage: list_plot3d(matrix(RDF, n, [cos(pi*(i+j)/n) for i in [1..n]
|
|
365
|
+
....: for j in [1..n]]), color=(cf,cm))
|
|
366
|
+
Graphics3d Object
|
|
367
|
+
|
|
368
|
+
.. PLOT::
|
|
369
|
+
|
|
370
|
+
cm = colormaps.rainbow
|
|
371
|
+
cf = lambda x, y: ((2*(x-y)/20)**2) % 1
|
|
372
|
+
expl = list_plot3d(matrix(RDF,20,20,[cos(pi*(i+j)/20) for i in range(1,21) for j in range(1,21)]),color=(cf,cm))
|
|
373
|
+
sphinx_plot(expl)
|
|
374
|
+
"""
|
|
375
|
+
from .parametric_surface import ParametricSurface
|
|
376
|
+
|
|
377
|
+
def f(i, j):
|
|
378
|
+
return (i, j, float(m[int(i), int(j)]))
|
|
379
|
+
G = ParametricSurface(f, (list(range(m.nrows())), list(range(m.ncols()))),
|
|
380
|
+
**kwds)
|
|
381
|
+
G._set_extra_kwds(kwds)
|
|
382
|
+
return G
|
|
383
|
+
|
|
384
|
+
|
|
385
|
+
def list_plot3d_array_of_arrays(v, interpolation_type, **kwds):
|
|
386
|
+
"""
|
|
387
|
+
A 3-dimensional plot of a surface defined by a list of lists ``v``
|
|
388
|
+
defining points in 3-dimensional space.
|
|
389
|
+
|
|
390
|
+
This is done by making the list of lists into a matrix and passing
|
|
391
|
+
back to :func:`list_plot3d`. See :func:`list_plot3d` for full
|
|
392
|
+
details.
|
|
393
|
+
|
|
394
|
+
INPUT:
|
|
395
|
+
|
|
396
|
+
- ``v`` -- list of lists, all the same length
|
|
397
|
+
- ``interpolation_type`` -- (default: ``'linear'``)
|
|
398
|
+
|
|
399
|
+
OPTIONAL KEYWORDS:
|
|
400
|
+
|
|
401
|
+
- ``**kwds`` -- all other arguments are passed to the surface function
|
|
402
|
+
|
|
403
|
+
OUTPUT: a 3d plot
|
|
404
|
+
|
|
405
|
+
EXAMPLES:
|
|
406
|
+
|
|
407
|
+
The resulting matrix does not have to be square::
|
|
408
|
+
|
|
409
|
+
sage: show(list_plot3d([[1, 1, 1, 1], [1, 2, 1, 2], [1, 1, 3, 1]])) # indirect doctest
|
|
410
|
+
|
|
411
|
+
.. PLOT::
|
|
412
|
+
|
|
413
|
+
sphinx_plot(list_plot3d([[1, 1, 1, 1], [1, 2, 1, 2], [1, 1, 3, 1]]))
|
|
414
|
+
|
|
415
|
+
The normal route is for the list of lists to be turned into a matrix
|
|
416
|
+
and use :func:`list_plot3d_matrix`::
|
|
417
|
+
|
|
418
|
+
sage: show(list_plot3d([[1, 1, 1, 1], [1, 2, 1, 2], [1, 1, 3, 1], [1, 2, 1, 4]]))
|
|
419
|
+
|
|
420
|
+
.. PLOT::
|
|
421
|
+
|
|
422
|
+
sphinx_plot(list_plot3d([[1, 1, 1, 1], [1, 2, 1, 2], [1, 1, 3, 1], [1, 2, 1, 4]]))
|
|
423
|
+
|
|
424
|
+
With certain extra keywords (see :func:`list_plot3d_matrix`), this function
|
|
425
|
+
will end up using :func:`list_plot3d_tuples`::
|
|
426
|
+
|
|
427
|
+
sage: show(list_plot3d([[1, 1, 1, 1], [1, 2, 1, 2], [1, 1, 3, 1], [1, 2, 1, 4]],
|
|
428
|
+
....: interpolation_type='spline'))
|
|
429
|
+
|
|
430
|
+
.. PLOT::
|
|
431
|
+
|
|
432
|
+
sphinx_plot(list_plot3d([[1, 1, 1, 1], [1, 2, 1, 2], [1, 1, 3, 1], [1, 2, 1, 4]], interpolation_type='spline'))
|
|
433
|
+
"""
|
|
434
|
+
m = matrix(RDF, len(v), len(v[0]), v)
|
|
435
|
+
G = list_plot3d(m, interpolation_type, **kwds)
|
|
436
|
+
G._set_extra_kwds(kwds)
|
|
437
|
+
return G
|
|
438
|
+
|
|
439
|
+
|
|
440
|
+
def list_plot3d_tuples(v, interpolation_type, **kwds):
|
|
441
|
+
r"""
|
|
442
|
+
A 3-dimensional plot of a surface defined by the list `v`
|
|
443
|
+
of points in 3-dimensional space.
|
|
444
|
+
|
|
445
|
+
INPUT:
|
|
446
|
+
|
|
447
|
+
- ``v`` -- something that defines a set of points in 3
|
|
448
|
+
space, for example:
|
|
449
|
+
|
|
450
|
+
- a matrix
|
|
451
|
+
|
|
452
|
+
This will be if using an ``interpolation_type`` other than
|
|
453
|
+
``'linear'``, or if using ``num_points`` with ``'linear'``;
|
|
454
|
+
otherwise see :func:`list_plot3d_matrix`.
|
|
455
|
+
|
|
456
|
+
- a list of 3-tuples
|
|
457
|
+
|
|
458
|
+
- a list of lists (all of the same length, under same conditions
|
|
459
|
+
as a matrix)
|
|
460
|
+
|
|
461
|
+
OPTIONAL KEYWORDS:
|
|
462
|
+
|
|
463
|
+
- ``interpolation_type`` -- one of ``'linear'``, ``'clough'``
|
|
464
|
+
(CloughTocher2D), ``'spline'``
|
|
465
|
+
|
|
466
|
+
``'linear'`` will perform linear interpolation
|
|
467
|
+
|
|
468
|
+
The option 'clough' will interpolate by using a piecewise cubic
|
|
469
|
+
interpolating Bezier polynomial on each triangle, using a
|
|
470
|
+
Clough-Tocher scheme. The interpolant is guaranteed to be
|
|
471
|
+
continuously differentiable.
|
|
472
|
+
|
|
473
|
+
The option ``'spline'`` interpolates using a bivariate B-spline.
|
|
474
|
+
|
|
475
|
+
When ``v`` is a matrix the default is to use linear interpolation, when
|
|
476
|
+
``v`` is a list of points the default is ``'clough'``.
|
|
477
|
+
|
|
478
|
+
- ``degree`` -- integer between 1 and 5, controls the degree of spline
|
|
479
|
+
used for spline interpolation. For data that is highly oscillatory
|
|
480
|
+
use higher values
|
|
481
|
+
|
|
482
|
+
- ``point_list`` -- if ``point_list=True`` is passed, then if the array
|
|
483
|
+
is a list of lists of length three, it will be treated as an
|
|
484
|
+
array of points rather than a `3\times n` array.
|
|
485
|
+
|
|
486
|
+
- ``num_points`` -- number of points to sample interpolating
|
|
487
|
+
function in each direction. By default for an `n\times n`
|
|
488
|
+
array this is `n`.
|
|
489
|
+
|
|
490
|
+
- ``**kwds`` -- all other arguments are passed to the
|
|
491
|
+
surface function
|
|
492
|
+
|
|
493
|
+
OUTPUT: a 3d plot
|
|
494
|
+
|
|
495
|
+
EXAMPLES:
|
|
496
|
+
|
|
497
|
+
All of these use this function; see :func:`list_plot3d` for other
|
|
498
|
+
list plots::
|
|
499
|
+
|
|
500
|
+
sage: from math import pi
|
|
501
|
+
sage: m = matrix(RDF, 6, [sin(i^2 + j^2)
|
|
502
|
+
....: for i in [0,pi/5,..,pi] for j in [0,pi/5,..,pi]])
|
|
503
|
+
sage: list_plot3d(m, color='yellow', interpolation_type='linear', # indirect doctest
|
|
504
|
+
....: num_points=5)
|
|
505
|
+
Graphics3d Object
|
|
506
|
+
|
|
507
|
+
.. PLOT::
|
|
508
|
+
|
|
509
|
+
import numpy as np
|
|
510
|
+
pi = float(pi)
|
|
511
|
+
m = matrix(RDF, 6, [sin(i**2 + j**2) for i in np.linspace(0,pi,6) for j in np.linspace(0,pi,6)])
|
|
512
|
+
sphinx_plot(list_plot3d(m, color='yellow', interpolation_type='linear', num_points=5))
|
|
513
|
+
|
|
514
|
+
::
|
|
515
|
+
|
|
516
|
+
sage: list_plot3d(m, color='yellow', interpolation_type='spline',
|
|
517
|
+
....: frame_aspect_ratio=[1, 1, 1/3])
|
|
518
|
+
Graphics3d Object
|
|
519
|
+
|
|
520
|
+
.. PLOT::
|
|
521
|
+
|
|
522
|
+
import numpy as np
|
|
523
|
+
pi = float(pi)
|
|
524
|
+
m = matrix(RDF, 6, [sin(i**2 + j**2) for i in np.linspace(0,pi,6) for j in np.linspace(0,pi,6)])
|
|
525
|
+
sphinx_plot(list_plot3d(m, color='yellow', interpolation_type='spline', frame_aspect_ratio=[1, 1, 1/3]))
|
|
526
|
+
|
|
527
|
+
::
|
|
528
|
+
|
|
529
|
+
sage: show(list_plot3d([[1, 1, 1], [1, 2, 1], [0, 1, 3], [1, 0, 4]],
|
|
530
|
+
....: point_list=True))
|
|
531
|
+
|
|
532
|
+
.. PLOT::
|
|
533
|
+
|
|
534
|
+
sphinx_plot(list_plot3d([[1, 1, 1], [1, 2, 1], [0, 1, 3], [1, 0, 4]],
|
|
535
|
+
point_list=True))
|
|
536
|
+
|
|
537
|
+
::
|
|
538
|
+
|
|
539
|
+
sage: list_plot3d([(1, 2, 3), (0, 1, 3), (2, 1, 4), (1, 0, -2)], # long time
|
|
540
|
+
....: color='yellow', num_points=50)
|
|
541
|
+
Graphics3d Object
|
|
542
|
+
|
|
543
|
+
.. PLOT::
|
|
544
|
+
|
|
545
|
+
sphinx_plot(list_plot3d([(1, 2, 3), (0, 1, 3), (2, 1, 4), (1, 0, -2)], color='yellow', num_points=50))
|
|
546
|
+
"""
|
|
547
|
+
from matplotlib import tri
|
|
548
|
+
import numpy
|
|
549
|
+
from random import random
|
|
550
|
+
from scipy import interpolate
|
|
551
|
+
from .plot3d import plot3d
|
|
552
|
+
|
|
553
|
+
if len(v) < 3:
|
|
554
|
+
raise ValueError("we need at least 3 points to perform the "
|
|
555
|
+
"interpolation")
|
|
556
|
+
|
|
557
|
+
x = [float(p[0]) for p in v]
|
|
558
|
+
y = [float(p[1]) for p in v]
|
|
559
|
+
z = [float(p[2]) for p in v]
|
|
560
|
+
|
|
561
|
+
# If the (x,y)-coordinates lie in a one-dimensional subspace, the
|
|
562
|
+
# matplotlib Delaunay code segfaults. Therefore, we compute the
|
|
563
|
+
# correlation of the x- and y-coordinates and add small random
|
|
564
|
+
# noise to avoid the problem if needed.
|
|
565
|
+
corr_matrix = numpy.corrcoef(x, y)
|
|
566
|
+
if not (-0.9 <= corr_matrix[0, 1] <= 0.9):
|
|
567
|
+
ep = .000001
|
|
568
|
+
x = [float(p[0]) + random() * ep for p in v]
|
|
569
|
+
y = [float(p[1]) + random() * ep for p in v]
|
|
570
|
+
|
|
571
|
+
# If the list of data points has two points with the exact same
|
|
572
|
+
# (x,y)-coordinate but different z-coordinates, then we sometimes
|
|
573
|
+
# get segfaults. The following block checks for this and raises
|
|
574
|
+
# an exception if this is the case.
|
|
575
|
+
# We also remove duplicate points (which matplotlib can't handle).
|
|
576
|
+
# Alternatively, the code in the if block above which adds random
|
|
577
|
+
# error could be applied to perturb the points.
|
|
578
|
+
drop_list = []
|
|
579
|
+
nb_points = len(x)
|
|
580
|
+
for i in range(nb_points):
|
|
581
|
+
for j in range(i + 1, nb_points):
|
|
582
|
+
if x[i] == x[j] and y[i] == y[j]:
|
|
583
|
+
if z[i] != z[j]:
|
|
584
|
+
raise ValueError("points with same x,y coordinates"
|
|
585
|
+
" and different z coordinates were"
|
|
586
|
+
" given. Interpolation cannot handle this.")
|
|
587
|
+
elif z[i] == z[j]:
|
|
588
|
+
drop_list.append(j)
|
|
589
|
+
x = [x[i] for i in range(nb_points) if i not in drop_list]
|
|
590
|
+
y = [y[i] for i in range(nb_points) if i not in drop_list]
|
|
591
|
+
z = [z[i] for i in range(nb_points) if i not in drop_list]
|
|
592
|
+
|
|
593
|
+
xmin = float(min(x))
|
|
594
|
+
xmax = float(max(x))
|
|
595
|
+
ymin = float(min(y))
|
|
596
|
+
ymax = float(max(y))
|
|
597
|
+
|
|
598
|
+
num_points = kwds.get('num_points', int(4 * numpy.sqrt(len(x))))
|
|
599
|
+
# arbitrary choice - assuming more or less a n x n grid of points
|
|
600
|
+
# x should have n^2 entries. We sample 4 times that many points.
|
|
601
|
+
|
|
602
|
+
if interpolation_type == 'linear':
|
|
603
|
+
T = tri.Triangulation(x, y)
|
|
604
|
+
f = tri.LinearTriInterpolator(T, z)
|
|
605
|
+
j = complex(0, 1)
|
|
606
|
+
from .parametric_surface import ParametricSurface
|
|
607
|
+
|
|
608
|
+
def g(x, y):
|
|
609
|
+
z = f(x, y)
|
|
610
|
+
return (x, y, z)
|
|
611
|
+
|
|
612
|
+
G = ParametricSurface(g, (list(numpy.r_[xmin:xmax:num_points * j]),
|
|
613
|
+
list(numpy.r_[ymin:ymax:num_points * j])),
|
|
614
|
+
**kwds)
|
|
615
|
+
G._set_extra_kwds(kwds)
|
|
616
|
+
return G
|
|
617
|
+
|
|
618
|
+
if interpolation_type == 'clough' or interpolation_type == 'default':
|
|
619
|
+
|
|
620
|
+
points = [[x[i], y[i]] for i in range(len(x))]
|
|
621
|
+
j = complex(0, 1)
|
|
622
|
+
f = interpolate.CloughTocher2DInterpolator(points, z)
|
|
623
|
+
from .parametric_surface import ParametricSurface
|
|
624
|
+
|
|
625
|
+
def g(x, y):
|
|
626
|
+
z = f([x, y]).item()
|
|
627
|
+
return (x, y, z)
|
|
628
|
+
|
|
629
|
+
G = ParametricSurface(g, (list(numpy.r_[xmin:xmax:num_points * j]),
|
|
630
|
+
list(numpy.r_[ymin:ymax:num_points * j])),
|
|
631
|
+
**kwds)
|
|
632
|
+
G._set_extra_kwds(kwds)
|
|
633
|
+
return G
|
|
634
|
+
|
|
635
|
+
if interpolation_type == 'spline':
|
|
636
|
+
kx = kwds['kx'] if 'kx' in kwds else 3
|
|
637
|
+
ky = kwds['ky'] if 'ky' in kwds else 3
|
|
638
|
+
if 'degree' in kwds:
|
|
639
|
+
kx = kwds['degree']
|
|
640
|
+
ky = kwds['degree']
|
|
641
|
+
s = kwds.get('smoothing', len(x) - numpy.sqrt(2 * len(x)))
|
|
642
|
+
s = interpolate.bisplrep(x, y, z, [1] * len(x), xmin, xmax,
|
|
643
|
+
ymin, ymax, kx=kx, ky=ky, s=s)
|
|
644
|
+
|
|
645
|
+
def f(x, y):
|
|
646
|
+
return interpolate.bisplev(x, y, s)
|
|
647
|
+
|
|
648
|
+
return plot3d(f, (xmin, xmax), (ymin, ymax),
|
|
649
|
+
plot_points=[num_points, num_points], **kwds)
|