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
sage/plot/plot_field.py
ADDED
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
# sage_setup: distribution = sagemath-plot
|
|
2
|
+
# sage.doctest: needs sage.symbolic
|
|
3
|
+
"""
|
|
4
|
+
Plotting fields
|
|
5
|
+
"""
|
|
6
|
+
# ****************************************************************************
|
|
7
|
+
# Copyright (C) 2006 Alex Clemesha <clemesha@gmail.com>,
|
|
8
|
+
# William Stein <wstein@gmail.com>,
|
|
9
|
+
# 2008 Mike Hansen <mhansen@gmail.com>,
|
|
10
|
+
#
|
|
11
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
|
12
|
+
#
|
|
13
|
+
# This code is distributed in the hope that it will be useful,
|
|
14
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
16
|
+
# General Public License for more details.
|
|
17
|
+
#
|
|
18
|
+
# The full text of the GPL is available at:
|
|
19
|
+
#
|
|
20
|
+
# https://www.gnu.org/licenses/
|
|
21
|
+
# ****************************************************************************
|
|
22
|
+
from sage.plot.primitive import GraphicPrimitive
|
|
23
|
+
from sage.misc.decorators import options
|
|
24
|
+
from sage.arith.srange import xsrange
|
|
25
|
+
|
|
26
|
+
# Below is the base class that is used to make 'field plots'.
|
|
27
|
+
# Its implementation is motivated by 'PlotField'.
|
|
28
|
+
# Currently it is used to make the functions 'plot_vector_field'
|
|
29
|
+
# and 'plot_slope_field'.
|
|
30
|
+
# TODO: use this to make these functions:
|
|
31
|
+
# 'plot_gradient_field' and 'plot_hamiltonian_field'
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class PlotField(GraphicPrimitive):
|
|
35
|
+
"""
|
|
36
|
+
Primitive class that initializes the
|
|
37
|
+
PlotField graphics type
|
|
38
|
+
"""
|
|
39
|
+
def __init__(self, xpos_array, ypos_array, xvec_array, yvec_array, options):
|
|
40
|
+
"""
|
|
41
|
+
Create the graphics primitive PlotField. This sets options
|
|
42
|
+
and the array to be plotted as attributes.
|
|
43
|
+
|
|
44
|
+
EXAMPLES::
|
|
45
|
+
|
|
46
|
+
sage: x,y = var('x,y')
|
|
47
|
+
sage: R=plot_slope_field(x + y, (x,0,1), (y,0,1), plot_points=2)
|
|
48
|
+
sage: r=R[0]
|
|
49
|
+
sage: r.options()['headaxislength']
|
|
50
|
+
0
|
|
51
|
+
sage: r.xpos_array
|
|
52
|
+
[0.0, 0.0, 1.0, 1.0]
|
|
53
|
+
sage: r.yvec_array
|
|
54
|
+
masked_array(data=[0.0, 0.70710678118..., 0.70710678118...,
|
|
55
|
+
0.89442719...],
|
|
56
|
+
mask=[False, False, False, False],
|
|
57
|
+
fill_value=1e+20)
|
|
58
|
+
|
|
59
|
+
TESTS:
|
|
60
|
+
|
|
61
|
+
We test dumping and loading a plot::
|
|
62
|
+
|
|
63
|
+
sage: x,y = var('x,y')
|
|
64
|
+
sage: P = plot_vector_field((sin(x),cos(y)), (x,-3,3), (y,-3,3))
|
|
65
|
+
sage: Q = loads(dumps(P))
|
|
66
|
+
"""
|
|
67
|
+
self.xpos_array = xpos_array
|
|
68
|
+
self.ypos_array = ypos_array
|
|
69
|
+
self.xvec_array = xvec_array
|
|
70
|
+
self.yvec_array = yvec_array
|
|
71
|
+
GraphicPrimitive.__init__(self, options)
|
|
72
|
+
|
|
73
|
+
def get_minmax_data(self):
|
|
74
|
+
"""
|
|
75
|
+
Return a dictionary with the bounding box data.
|
|
76
|
+
|
|
77
|
+
EXAMPLES::
|
|
78
|
+
|
|
79
|
+
sage: x,y = var('x,y')
|
|
80
|
+
sage: d = plot_vector_field((.01*x,x+y), (x,10,20), (y,10,20))[0].get_minmax_data()
|
|
81
|
+
sage: d['xmin']
|
|
82
|
+
10.0
|
|
83
|
+
sage: d['ymin']
|
|
84
|
+
10.0
|
|
85
|
+
"""
|
|
86
|
+
from sage.plot.plot import minmax_data
|
|
87
|
+
return minmax_data(self.xpos_array, self.ypos_array, dict=True)
|
|
88
|
+
|
|
89
|
+
def _allowed_options(self):
|
|
90
|
+
"""
|
|
91
|
+
Return a dictionary with allowed options for PlotField.
|
|
92
|
+
|
|
93
|
+
EXAMPLES::
|
|
94
|
+
|
|
95
|
+
sage: x,y = var('x,y')
|
|
96
|
+
sage: P=plot_vector_field((sin(x),cos(y)), (x,-3,3), (y,-3,3))
|
|
97
|
+
sage: d=P[0]._allowed_options()
|
|
98
|
+
sage: d['pivot']
|
|
99
|
+
'Where the arrow should be placed in relation to the point (tail, middle, tip)'
|
|
100
|
+
"""
|
|
101
|
+
return {'plot_points': 'How many points to use for plotting precision',
|
|
102
|
+
'pivot': 'Where the arrow should be placed in relation to the point (tail, middle, tip)',
|
|
103
|
+
'headwidth': 'Head width as multiple of shaft width, default is 3',
|
|
104
|
+
'headlength': 'head length as multiple of shaft width, default is 5',
|
|
105
|
+
'headaxislength': 'head length at shaft intersection, default is 4.5',
|
|
106
|
+
'zorder': 'The layer level in which to draw',
|
|
107
|
+
'color': 'The color of the arrows'}
|
|
108
|
+
|
|
109
|
+
def _repr_(self):
|
|
110
|
+
"""
|
|
111
|
+
String representation of PlotField graphics primitive.
|
|
112
|
+
|
|
113
|
+
EXAMPLES::
|
|
114
|
+
|
|
115
|
+
sage: x,y = var('x,y')
|
|
116
|
+
sage: P=plot_vector_field((sin(x),cos(y)), (x,-3,3), (y,-3,3))
|
|
117
|
+
sage: P[0]
|
|
118
|
+
PlotField defined by a 20 x 20 vector grid
|
|
119
|
+
|
|
120
|
+
TESTS:
|
|
121
|
+
|
|
122
|
+
We check that :issue:`15052` is fixed
|
|
123
|
+
(note that in general :issue:`15002` should be fixed)::
|
|
124
|
+
|
|
125
|
+
sage: x,y=var('x,y')
|
|
126
|
+
sage: P=plot_vector_field((sin(x), cos(y)), (x,-3,3), (y,-3,3), wrong_option='nonsense')
|
|
127
|
+
sage: P[0].options()['plot_points']
|
|
128
|
+
verbose 0 (...: primitive.py, options) WARNING: Ignoring option 'wrong_option'=nonsense
|
|
129
|
+
verbose 0 (...: primitive.py, options)
|
|
130
|
+
The allowed options for PlotField defined by a 20 x 20 vector grid are:
|
|
131
|
+
color The color of the arrows
|
|
132
|
+
headaxislength head length at shaft intersection, default is 4.5
|
|
133
|
+
headlength head length as multiple of shaft width, default is 5
|
|
134
|
+
headwidth Head width as multiple of shaft width, default is 3
|
|
135
|
+
pivot Where the arrow should be placed in relation to the point (tail, middle, tip)
|
|
136
|
+
plot_points How many points to use for plotting precision
|
|
137
|
+
zorder The layer level in which to draw
|
|
138
|
+
<BLANKLINE>
|
|
139
|
+
20
|
|
140
|
+
"""
|
|
141
|
+
return "PlotField defined by a {} x {} vector grid".format(
|
|
142
|
+
self._options['plot_points'], self._options['plot_points'])
|
|
143
|
+
|
|
144
|
+
def _render_on_subplot(self, subplot):
|
|
145
|
+
"""
|
|
146
|
+
TESTS::
|
|
147
|
+
|
|
148
|
+
sage: x,y = var('x,y')
|
|
149
|
+
sage: P=plot_vector_field((sin(x),cos(y)), (x,-3,3), (y,-3,3))
|
|
150
|
+
"""
|
|
151
|
+
options = self.options()
|
|
152
|
+
quiver_options = options.copy()
|
|
153
|
+
quiver_options.pop('plot_points')
|
|
154
|
+
subplot.quiver(self.xpos_array, self.ypos_array,
|
|
155
|
+
self.xvec_array, self.yvec_array,
|
|
156
|
+
angles='xy', **quiver_options)
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
@options(plot_points=20, frame=True)
|
|
160
|
+
def plot_vector_field(f_g, xrange, yrange, **options):
|
|
161
|
+
r"""
|
|
162
|
+
``plot_vector_field`` takes two functions of two variables xvar and yvar
|
|
163
|
+
(for instance, if the variables are `x` and `y`, take `(f(x,y), g(x,y))`)
|
|
164
|
+
and plots vector arrows of the function over the specified ranges, with
|
|
165
|
+
xrange being of xvar between xmin and xmax, and yrange similarly
|
|
166
|
+
(see below).
|
|
167
|
+
|
|
168
|
+
``plot_vector_field((f,g), (xvar,xmin,xmax), (yvar,ymin,ymax))``
|
|
169
|
+
|
|
170
|
+
EXAMPLES:
|
|
171
|
+
|
|
172
|
+
Plot some vector fields involving sin and cos::
|
|
173
|
+
|
|
174
|
+
sage: x,y = var('x y')
|
|
175
|
+
sage: plot_vector_field((sin(x),cos(y)), (x,-3,3), (y,-3,3))
|
|
176
|
+
Graphics object consisting of 1 graphics primitive
|
|
177
|
+
|
|
178
|
+
.. PLOT::
|
|
179
|
+
|
|
180
|
+
x, y = var('x y')
|
|
181
|
+
g = plot_vector_field((sin(x),cos(y)), (x,-3,3), (y,-3,3))
|
|
182
|
+
sphinx_plot(g)
|
|
183
|
+
|
|
184
|
+
::
|
|
185
|
+
|
|
186
|
+
sage: plot_vector_field((y,(cos(x)-2) * sin(x)), (x,-pi,pi), (y,-pi,pi))
|
|
187
|
+
Graphics object consisting of 1 graphics primitive
|
|
188
|
+
|
|
189
|
+
.. PLOT::
|
|
190
|
+
|
|
191
|
+
x, y = var('x y')
|
|
192
|
+
g = plot_vector_field((y,(cos(x)-2) * sin(x)), (x,-pi,pi), (y,-pi,pi))
|
|
193
|
+
sphinx_plot(g)
|
|
194
|
+
|
|
195
|
+
Plot a gradient field::
|
|
196
|
+
|
|
197
|
+
sage: u, v = var('u v')
|
|
198
|
+
sage: f = exp(-(u^2 + v^2))
|
|
199
|
+
sage: plot_vector_field(f.gradient(), (u,-2,2), (v,-2,2), color='blue')
|
|
200
|
+
Graphics object consisting of 1 graphics primitive
|
|
201
|
+
|
|
202
|
+
.. PLOT::
|
|
203
|
+
|
|
204
|
+
u, v = var('u v')
|
|
205
|
+
f = exp(-(u**2 + v**2))
|
|
206
|
+
g = plot_vector_field(f.gradient(), (u,-2,2), (v,-2,2), color='blue')
|
|
207
|
+
sphinx_plot(g)
|
|
208
|
+
|
|
209
|
+
Plot two orthogonal vector fields::
|
|
210
|
+
|
|
211
|
+
sage: x,y = var('x,y')
|
|
212
|
+
sage: a = plot_vector_field((x,y), (x,-3,3), (y,-3,3), color='blue')
|
|
213
|
+
sage: b = plot_vector_field((y,-x), (x,-3,3), (y,-3,3), color='red')
|
|
214
|
+
sage: show(a + b)
|
|
215
|
+
|
|
216
|
+
.. PLOT::
|
|
217
|
+
|
|
218
|
+
x,y = var('x,y')
|
|
219
|
+
a = plot_vector_field((x,y), (x,-3,3), (y,-3,3), color='blue')
|
|
220
|
+
b = plot_vector_field((y,-x), (x,-3,3), (y,-3,3), color='red')
|
|
221
|
+
sphinx_plot(a + b)
|
|
222
|
+
|
|
223
|
+
We ignore function values that are infinite or NaN::
|
|
224
|
+
|
|
225
|
+
sage: x,y = var('x,y')
|
|
226
|
+
sage: plot_vector_field((-x/sqrt(x^2+y^2),-y/sqrt(x^2+y^2)), (x,-10,10), (y,-10,10))
|
|
227
|
+
Graphics object consisting of 1 graphics primitive
|
|
228
|
+
|
|
229
|
+
.. PLOT::
|
|
230
|
+
|
|
231
|
+
x,y = var('x,y')
|
|
232
|
+
g = plot_vector_field((-x/sqrt(x**2+y**2),-y/sqrt(x**2+y**2)), (x,-10,10), (y,-10,10))
|
|
233
|
+
sphinx_plot(g)
|
|
234
|
+
|
|
235
|
+
::
|
|
236
|
+
|
|
237
|
+
sage: x,y = var('x,y')
|
|
238
|
+
sage: plot_vector_field((-x/sqrt(x+y),-y/sqrt(x+y)), (x,-10, 10), (y,-10,10))
|
|
239
|
+
Graphics object consisting of 1 graphics primitive
|
|
240
|
+
|
|
241
|
+
.. PLOT::
|
|
242
|
+
|
|
243
|
+
x,y = var('x,y')
|
|
244
|
+
g = plot_vector_field((-x/sqrt(x+y),-y/sqrt(x+y)), (x,-10,10), (y,-10,10))
|
|
245
|
+
sphinx_plot(g)
|
|
246
|
+
|
|
247
|
+
Extra options will get passed on to show(), as long as they are valid::
|
|
248
|
+
|
|
249
|
+
sage: plot_vector_field((x,y), (x,-2,2), (y,-2,2), xmax=10)
|
|
250
|
+
Graphics object consisting of 1 graphics primitive
|
|
251
|
+
sage: plot_vector_field((x,y), (x,-2,2), (y,-2,2)).show(xmax=10) # These are equivalent
|
|
252
|
+
|
|
253
|
+
.. PLOT::
|
|
254
|
+
|
|
255
|
+
x,y = var('x,y')
|
|
256
|
+
g = plot_vector_field((x,y), (x,-2,2), (y,-2,2), xmax=10)
|
|
257
|
+
sphinx_plot(g)
|
|
258
|
+
"""
|
|
259
|
+
f, g = f_g
|
|
260
|
+
from sage.plot.all import Graphics
|
|
261
|
+
from sage.plot.misc import setup_for_eval_on_grid
|
|
262
|
+
z, ranges = setup_for_eval_on_grid([f, g], [xrange, yrange],
|
|
263
|
+
options['plot_points'])
|
|
264
|
+
f, g = z
|
|
265
|
+
|
|
266
|
+
xpos_array, ypos_array, xvec_array, yvec_array = [], [], [], []
|
|
267
|
+
for x in xsrange(*ranges[0], include_endpoint=True):
|
|
268
|
+
for y in xsrange(*ranges[1], include_endpoint=True):
|
|
269
|
+
xpos_array.append(x)
|
|
270
|
+
ypos_array.append(y)
|
|
271
|
+
xvec_array.append(f(x, y))
|
|
272
|
+
yvec_array.append(g(x, y))
|
|
273
|
+
|
|
274
|
+
import numpy
|
|
275
|
+
xvec_array = numpy.ma.masked_invalid(numpy.array(xvec_array, dtype=float))
|
|
276
|
+
yvec_array = numpy.ma.masked_invalid(numpy.array(yvec_array, dtype=float))
|
|
277
|
+
g = Graphics()
|
|
278
|
+
g._set_extra_kwds(Graphics._extract_kwds_for_show(options))
|
|
279
|
+
g.add_primitive(PlotField(xpos_array, ypos_array,
|
|
280
|
+
xvec_array, yvec_array, options))
|
|
281
|
+
return g
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
def plot_slope_field(f, xrange, yrange, **kwds):
|
|
285
|
+
r"""
|
|
286
|
+
``plot_slope_field`` takes a function of two variables xvar and yvar
|
|
287
|
+
(for instance, if the variables are `x` and `y`, take `f(x,y)`), and at
|
|
288
|
+
representative points `(x_i,y_i)` between xmin, xmax, and ymin, ymax
|
|
289
|
+
respectively, plots a line with slope `f(x_i,y_i)` (see below).
|
|
290
|
+
|
|
291
|
+
``plot_slope_field(f, (xvar,xmin,xmax), (yvar,ymin,ymax))``
|
|
292
|
+
|
|
293
|
+
EXAMPLES:
|
|
294
|
+
|
|
295
|
+
A logistic function modeling population growth::
|
|
296
|
+
|
|
297
|
+
sage: x,y = var('x y')
|
|
298
|
+
sage: capacity = 3 # thousand
|
|
299
|
+
sage: growth_rate = 0.7 # population increases by 70% per unit of time
|
|
300
|
+
sage: plot_slope_field(growth_rate * (1-y/capacity) * y, (x,0,5), (y,0,capacity*2))
|
|
301
|
+
Graphics object consisting of 1 graphics primitive
|
|
302
|
+
|
|
303
|
+
.. PLOT::
|
|
304
|
+
|
|
305
|
+
x,y = var('x y')
|
|
306
|
+
capacity = 3 # thousand
|
|
307
|
+
growth_rate = 0.7 # population increases by 70% per unit of time
|
|
308
|
+
g = plot_slope_field(growth_rate * (1-y/capacity) * y, (x,0,5), (y,0,capacity*2))
|
|
309
|
+
sphinx_plot(g)
|
|
310
|
+
|
|
311
|
+
Plot a slope field involving sin and cos::
|
|
312
|
+
|
|
313
|
+
sage: x,y = var('x y')
|
|
314
|
+
sage: plot_slope_field(sin(x+y) + cos(x+y), (x,-3,3), (y,-3,3))
|
|
315
|
+
Graphics object consisting of 1 graphics primitive
|
|
316
|
+
|
|
317
|
+
.. PLOT::
|
|
318
|
+
|
|
319
|
+
x,y = var('x y')
|
|
320
|
+
g = plot_slope_field(sin(x+y)+cos(x+y), (x,-3,3), (y,-3,3))
|
|
321
|
+
sphinx_plot(g)
|
|
322
|
+
|
|
323
|
+
Plot a slope field using a lambda function::
|
|
324
|
+
|
|
325
|
+
sage: plot_slope_field(lambda x,y: x + y, (-2,2), (-2,2))
|
|
326
|
+
Graphics object consisting of 1 graphics primitive
|
|
327
|
+
|
|
328
|
+
.. PLOT::
|
|
329
|
+
|
|
330
|
+
x,y = var('x y')
|
|
331
|
+
g = plot_slope_field(lambda x,y: x + y, (-2,2), (-2,2))
|
|
332
|
+
sphinx_plot(g)
|
|
333
|
+
|
|
334
|
+
TESTS:
|
|
335
|
+
|
|
336
|
+
Verify that we're not getting warnings due to use of headless quivers
|
|
337
|
+
(:issue:`11208`)::
|
|
338
|
+
|
|
339
|
+
sage: x,y = var('x y')
|
|
340
|
+
sage: import numpy # bump warnings up to errors for testing purposes
|
|
341
|
+
sage: old_err = numpy.seterr('raise')
|
|
342
|
+
sage: plot_slope_field(sin(x+y) + cos(x+y), (x,-3,3), (y,-3,3))
|
|
343
|
+
Graphics object consisting of 1 graphics primitive
|
|
344
|
+
sage: dummy_err = numpy.seterr(**old_err)
|
|
345
|
+
"""
|
|
346
|
+
slope_options = {'headaxislength': 0,
|
|
347
|
+
'headlength': 1e-9,
|
|
348
|
+
'pivot': 'middle'}
|
|
349
|
+
slope_options.update(kwds)
|
|
350
|
+
|
|
351
|
+
from sage.misc.functional import sqrt
|
|
352
|
+
from sage.misc.sageinspect import is_function_or_cython_function
|
|
353
|
+
if is_function_or_cython_function(f):
|
|
354
|
+
def norm_inverse(x, y):
|
|
355
|
+
return 1 / sqrt(f(x, y)**2 + 1)
|
|
356
|
+
|
|
357
|
+
def f_normalized(x, y):
|
|
358
|
+
return f(x, y) * norm_inverse(x, y)
|
|
359
|
+
else:
|
|
360
|
+
norm_inverse = 1 / sqrt(f**2 + 1)
|
|
361
|
+
f_normalized = f * norm_inverse
|
|
362
|
+
return plot_vector_field((norm_inverse, f_normalized), xrange, yrange, **slope_options)
|