Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sagelib
Path: blob/master/sage/plot/density_plot.py
4034 views
1
"""
2
Density Plots
3
"""
4
5
#*****************************************************************************
6
# Copyright (C) 2006 Alex Clemesha <[email protected]>,
7
# William Stein <[email protected]>,
8
# 2008 Mike Hansen <[email protected]>,
9
# Arnaud Bergeron <[email protected]>
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
# http://www.gnu.org/licenses/
21
#*****************************************************************************
22
from sage.plot.primitive import GraphicPrimitive
23
from sage.misc.decorators import options
24
from sage.plot.colors import get_cmap
25
from sage.misc.misc import xsrange
26
27
class DensityPlot(GraphicPrimitive):
28
"""
29
Primitive class for the density plot graphics type. See
30
``density_plot?`` for help actually doing density plots.
31
32
INPUT:
33
34
- ``xy_data_array`` - list of lists giving evaluated values of the
35
function on the grid
36
37
- ``xrange`` - tuple of 2 floats indicating range for horizontal direction
38
39
- ``yrange`` - tuple of 2 floats indicating range for vertical direction
40
41
- ``options`` - dict of valid plot options to pass to constructor
42
43
EXAMPLES:
44
45
Note this should normally be used indirectly via `density_plot``::
46
47
sage: from sage.plot.density_plot import DensityPlot
48
sage: D = DensityPlot([[1,3],[2,4]],(1,2),(2,3),options={})
49
sage: D
50
DensityPlot defined by a 2 x 2 data grid
51
sage: D.yrange
52
(2, 3)
53
sage: D.options()
54
{}
55
56
TESTS:
57
58
We test creating a density plot::
59
60
sage: x,y = var('x,y')
61
sage: density_plot(x^2-y^3+10*sin(x*y), (x, -4, 4), (y, -4, 4),plot_points=121,cmap='hsv')
62
"""
63
def __init__(self, xy_data_array, xrange, yrange, options):
64
"""
65
Initializes base class DensityPlot.
66
67
EXAMPLES::
68
69
sage: x,y = var('x,y')
70
sage: D = density_plot(x^2-y^3+10*sin(x*y), (x, -4, 4), (y, -4, 4),plot_points=121,cmap='hsv')
71
sage: D[0].xrange
72
(-4.0, 4.0)
73
sage: D[0].options()['plot_points']
74
121
75
"""
76
self.xrange = xrange
77
self.yrange = yrange
78
self.xy_data_array = xy_data_array
79
self.xy_array_row = len(xy_data_array)
80
self.xy_array_col = len(xy_data_array[0])
81
GraphicPrimitive.__init__(self, options)
82
83
def get_minmax_data(self):
84
"""
85
Returns a dictionary with the bounding box data.
86
87
EXAMPLES::
88
89
sage: x,y = var('x,y')
90
sage: f(x, y) = x^2 + y^2
91
sage: d = density_plot(f, (3, 6), (3, 6))[0].get_minmax_data()
92
sage: d['xmin']
93
3.0
94
sage: d['ymin']
95
3.0
96
"""
97
from sage.plot.plot import minmax_data
98
return minmax_data(self.xrange, self.yrange, dict=True)
99
100
def _allowed_options(self):
101
"""
102
Return the allowed options for the DensityPlot class.
103
104
TESTS::
105
106
sage: isinstance(density_plot(x, (-2,3), (1,10))[0]._allowed_options(), dict)
107
True
108
"""
109
return {'plot_points':'How many points to use for plotting precision',
110
'cmap':"""the name of a predefined colormap,
111
a list of colors or an instance of a
112
matplotlib Colormap. Type: import matplotlib.cm; matplotlib.cm.datad.keys()
113
for available colormap names.""",
114
'interpolation':'What interpolation method to use'}
115
116
def _repr_(self):
117
"""
118
String representation of DensityrPlot primitive.
119
120
EXAMPLES::
121
122
sage: x,y = var('x,y')
123
sage: D = density_plot(x^2-y^2,(x,-2,2),(y,-2,2))
124
sage: d = D[0]; d
125
DensityPlot defined by a 25 x 25 data grid
126
"""
127
return "DensityPlot defined by a %s x %s data grid"%(self.xy_array_row, self.xy_array_col)
128
129
def _render_on_subplot(self, subplot):
130
"""
131
TESTS:
132
133
A somewhat random plot, but fun to look at::
134
135
sage: x,y = var('x,y')
136
sage: density_plot(x^2-y^3+10*sin(x*y), (x, -4, 4), (y, -4, 4),plot_points=121,cmap='hsv')
137
"""
138
options = self.options()
139
cmap = get_cmap(options['cmap'])
140
141
x0,x1 = float(self.xrange[0]), float(self.xrange[1])
142
y0,y1 = float(self.yrange[0]), float(self.yrange[1])
143
144
subplot.imshow(self.xy_data_array, origin='lower', cmap=cmap, extent=(x0,x1,y0,y1), interpolation=options['interpolation'])
145
146
@options(plot_points=25, cmap='gray', interpolation='catrom')
147
def density_plot(f, xrange, yrange, **options):
148
r"""
149
``density_plot`` takes a function of two variables, `f(x,y)`
150
and plots the height of of the function over the specified
151
``xrange`` and ``yrange`` as demonstrated below.
152
153
``density_plot(f, (xmin, xmax), (ymin, ymax), ...)``
154
155
INPUT:
156
157
- ``f`` -- a function of two variables
158
159
- ``(xmin, xmax)`` -- 2-tuple, the range of ``x`` values OR 3-tuple
160
``(x,xmin,xmax)``
161
162
- ``(ymin, ymax)`` -- 2-tuple, the range of ``y`` values OR 3-tuple
163
``(y,ymin,ymax)``
164
165
The following inputs must all be passed in as named parameters:
166
167
- ``plot_points`` -- integer (default: 25); number of points to plot
168
in each direction of the grid
169
170
- ``cmap`` -- a colormap (type ``cmap_help()`` for more information).
171
172
- ``interpolation`` -- string (default: ``'catrom'``), the interpolation
173
method to use: ``'bilinear'``, ``'bicubic'``, ``'spline16'``,
174
``'spline36'``, ``'quadric'``, ``'gaussian'``, ``'sinc'``,
175
``'bessel'``, ``'mitchell'``, ``'lanczos'``, ``'catrom'``,
176
``'hermite'``, ``'hanning'``, ``'hamming'``, ``'kaiser'``
177
178
179
EXAMPLES:
180
181
Here we plot a simple function of two variables. Note that
182
since the input function is an expression, we need to explicitly
183
declare the variables in 3-tuples for the range::
184
185
sage: x,y = var('x,y')
186
sage: density_plot(sin(x)*sin(y), (x, -2, 2), (y, -2, 2))
187
188
189
Here we change the ranges and add some options; note that here
190
``f`` is callable (has variables declared), so we can use 2-tuple ranges::
191
192
sage: x,y = var('x,y')
193
sage: f(x,y) = x^2*cos(x*y)
194
sage: density_plot(f, (x,-10,5), (y, -5,5), interpolation='sinc', plot_points=100)
195
196
An even more complicated plot::
197
198
sage: x,y = var('x,y')
199
sage: density_plot(sin(x^2 + y^2)*cos(x)*sin(y), (x, -4, 4), (y, -4, 4), cmap='jet', plot_points=100)
200
201
This should show a "spotlight" right on the origin::
202
203
sage: x,y = var('x,y')
204
sage: density_plot(1/(x^10+y^10), (x, -10, 10), (y, -10, 10))
205
206
Some elliptic curves, but with symbolic endpoints. In the first
207
example, the plot is rotated 90 degrees because we switch the
208
variables `x`, `y`::
209
210
sage: density_plot(y^2 + 1 - x^3 - x, (y,-pi,pi), (x,-pi,pi))
211
212
::
213
214
sage: density_plot(y^2 + 1 - x^3 - x, (x,-pi,pi), (y,-pi,pi))
215
216
Extra options will get passed on to show(), as long as they are valid::
217
218
sage: density_plot(log(x) + log(y), (x, 1, 10), (y, 1, 10), dpi=20)
219
220
::
221
222
sage: density_plot(log(x) + log(y), (x, 1, 10), (y, 1, 10)).show(dpi=20) # These are equivalent
223
"""
224
from sage.plot.all import Graphics
225
from sage.plot.misc import setup_for_eval_on_grid
226
g, ranges = setup_for_eval_on_grid([f], [xrange, yrange], options['plot_points'])
227
g = g[0]
228
xrange,yrange=[r[:2] for r in ranges]
229
230
xy_data_array = [[g(x, y) for x in xsrange(*ranges[0], include_endpoint=True)]
231
for y in xsrange(*ranges[1], include_endpoint=True)]
232
233
g = Graphics()
234
g._set_extra_kwds(Graphics._extract_kwds_for_show(options, ignore=['xmin', 'xmax']))
235
g.add_primitive(DensityPlot(xy_data_array, xrange, yrange, options))
236
return g
237
238