passagemath-plot 10.6.31rc3__cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.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.

Files changed (81) hide show
  1. passagemath_plot-10.6.31rc3.dist-info/METADATA +172 -0
  2. passagemath_plot-10.6.31rc3.dist-info/RECORD +81 -0
  3. passagemath_plot-10.6.31rc3.dist-info/WHEEL +6 -0
  4. passagemath_plot-10.6.31rc3.dist-info/top_level.txt +2 -0
  5. passagemath_plot.libs/libgfortran-e1b7dfc8.so.5.0.0 +0 -0
  6. passagemath_plot.libs/libgsl-e3525837.so.28.0.0 +0 -0
  7. passagemath_plot.libs/libopenblasp-r0-4c5b64b1.3.29.so +0 -0
  8. sage/all__sagemath_plot.py +15 -0
  9. sage/ext_data/threejs/animation.css +195 -0
  10. sage/ext_data/threejs/animation.html +85 -0
  11. sage/ext_data/threejs/animation.js +273 -0
  12. sage/ext_data/threejs/fat_lines.js +48 -0
  13. sage/ext_data/threejs/threejs-version.txt +1 -0
  14. sage/ext_data/threejs/threejs_template.html +597 -0
  15. sage/interfaces/all__sagemath_plot.py +1 -0
  16. sage/interfaces/gnuplot.py +196 -0
  17. sage/interfaces/jmoldata.py +208 -0
  18. sage/interfaces/povray.py +56 -0
  19. sage/plot/all.py +42 -0
  20. sage/plot/animate.py +1796 -0
  21. sage/plot/arc.py +504 -0
  22. sage/plot/arrow.py +671 -0
  23. sage/plot/bar_chart.py +205 -0
  24. sage/plot/bezier_path.py +400 -0
  25. sage/plot/circle.py +435 -0
  26. sage/plot/colors.py +1606 -0
  27. sage/plot/complex_plot.cpython-314-aarch64-linux-gnu.so +0 -0
  28. sage/plot/complex_plot.pyx +1446 -0
  29. sage/plot/contour_plot.py +1792 -0
  30. sage/plot/density_plot.py +318 -0
  31. sage/plot/disk.py +373 -0
  32. sage/plot/ellipse.py +375 -0
  33. sage/plot/graphics.py +3580 -0
  34. sage/plot/histogram.py +354 -0
  35. sage/plot/hyperbolic_arc.py +404 -0
  36. sage/plot/hyperbolic_polygon.py +416 -0
  37. sage/plot/hyperbolic_regular_polygon.py +296 -0
  38. sage/plot/line.py +626 -0
  39. sage/plot/matrix_plot.py +629 -0
  40. sage/plot/misc.py +509 -0
  41. sage/plot/multigraphics.py +1294 -0
  42. sage/plot/plot.py +4183 -0
  43. sage/plot/plot3d/all.py +23 -0
  44. sage/plot/plot3d/base.cpython-314-aarch64-linux-gnu.so +0 -0
  45. sage/plot/plot3d/base.pxd +12 -0
  46. sage/plot/plot3d/base.pyx +3378 -0
  47. sage/plot/plot3d/implicit_plot3d.py +659 -0
  48. sage/plot/plot3d/implicit_surface.cpython-314-aarch64-linux-gnu.so +0 -0
  49. sage/plot/plot3d/implicit_surface.pyx +1453 -0
  50. sage/plot/plot3d/index_face_set.cpython-314-aarch64-linux-gnu.so +0 -0
  51. sage/plot/plot3d/index_face_set.pxd +32 -0
  52. sage/plot/plot3d/index_face_set.pyx +1873 -0
  53. sage/plot/plot3d/introduction.py +131 -0
  54. sage/plot/plot3d/list_plot3d.py +649 -0
  55. sage/plot/plot3d/parametric_plot3d.py +1130 -0
  56. sage/plot/plot3d/parametric_surface.cpython-314-aarch64-linux-gnu.so +0 -0
  57. sage/plot/plot3d/parametric_surface.pxd +12 -0
  58. sage/plot/plot3d/parametric_surface.pyx +893 -0
  59. sage/plot/plot3d/platonic.py +601 -0
  60. sage/plot/plot3d/plot3d.py +1442 -0
  61. sage/plot/plot3d/plot_field3d.py +162 -0
  62. sage/plot/plot3d/point_c.pxi +148 -0
  63. sage/plot/plot3d/revolution_plot3d.py +309 -0
  64. sage/plot/plot3d/shapes.cpython-314-aarch64-linux-gnu.so +0 -0
  65. sage/plot/plot3d/shapes.pxd +22 -0
  66. sage/plot/plot3d/shapes.pyx +1382 -0
  67. sage/plot/plot3d/shapes2.py +1512 -0
  68. sage/plot/plot3d/tachyon.py +1779 -0
  69. sage/plot/plot3d/texture.py +453 -0
  70. sage/plot/plot3d/transform.cpython-314-aarch64-linux-gnu.so +0 -0
  71. sage/plot/plot3d/transform.pxd +21 -0
  72. sage/plot/plot3d/transform.pyx +268 -0
  73. sage/plot/plot3d/tri_plot.py +589 -0
  74. sage/plot/plot_field.py +362 -0
  75. sage/plot/point.py +624 -0
  76. sage/plot/polygon.py +562 -0
  77. sage/plot/primitive.py +249 -0
  78. sage/plot/scatter_plot.py +199 -0
  79. sage/plot/step.py +85 -0
  80. sage/plot/streamline_plot.py +328 -0
  81. sage/plot/text.py +432 -0
@@ -0,0 +1,629 @@
1
+ # sage_setup: distribution = sagemath-plot
2
+ """
3
+ Matrix plots
4
+ """
5
+ # ****************************************************************************
6
+ # Copyright (C) 2006 Alex Clemesha <clemesha@gmail.com>,
7
+ # William Stein <wstein@gmail.com>,
8
+ # 2008 Mike Hansen <mhansen@gmail.com>,
9
+ #
10
+ # Distributed under the terms of the GNU General Public License (GPL)
11
+ #
12
+ # This code is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
+ # General Public License for more details.
16
+ #
17
+ # The full text of the GPL is available at:
18
+ #
19
+ # https://www.gnu.org/licenses/
20
+ # ****************************************************************************
21
+
22
+ from sage.plot.primitive import GraphicPrimitive
23
+ from sage.misc.decorators import options, suboptions
24
+ from sage.plot.colors import get_cmap
25
+
26
+
27
+ class MatrixPlot(GraphicPrimitive):
28
+ """
29
+ Primitive class for the matrix plot graphics type. See
30
+ ``matrix_plot?`` for help actually doing matrix plots.
31
+
32
+ INPUT:
33
+
34
+ - ``xy_data_array`` -- list of lists giving matrix values corresponding to
35
+ the grid
36
+
37
+ - ``xrange`` -- tuple of 2 floats indicating range for horizontal direction
38
+ (number of columns in the matrix). If ``None``, the defaults are used as
39
+ indicated in :func:`matrix_plot`.
40
+
41
+ - ``yrange`` -- tuple of 2 floats indicating range for vertical direction
42
+ (number of rows in the matrix). If ``None``, the defaults are used as
43
+ indicated in :func:`matrix_plot`.
44
+
45
+ - ``options`` -- dictionary of valid plot options to pass to constructor
46
+
47
+ EXAMPLES:
48
+
49
+ Note this should normally be used indirectly via :func:`matrix_plot`::
50
+
51
+ sage: from sage.plot.matrix_plot import MatrixPlot
52
+ sage: M = MatrixPlot([[1,3],[2,4]],(1,2),(2,3),options={'cmap':'winter'})
53
+ sage: M
54
+ MatrixPlot defined by a 2 x 2 data grid
55
+ sage: M.yrange
56
+ (2, 3)
57
+ sage: M.xy_data_array
58
+ [[1, 3], [2, 4]]
59
+ sage: M.options()
60
+ {'cmap': 'winter'}
61
+
62
+ Extra options will get passed on to :meth:`~Graphics.show`, as long as they are valid::
63
+
64
+ sage: matrix_plot([[1, 0], [0, 1]], fontsize=10)
65
+ Graphics object consisting of 1 graphics primitive
66
+ sage: matrix_plot([[1, 0], [0, 1]]).show(fontsize=10) # These are equivalent
67
+
68
+ TESTS:
69
+
70
+ We test creating a matrix plot::
71
+
72
+ sage: matrix_plot([[mod(i,5)^j for i in range(5)] for j in range(1,6)])
73
+ Graphics object consisting of 1 graphics primitive
74
+ """
75
+ def __init__(self, xy_data_array, xrange, yrange, options):
76
+ """
77
+ Initialize base class MatrixPlot.
78
+
79
+ EXAMPLES::
80
+
81
+ sage: M = matrix_plot([[mod(i,5)^j for i in range(5)] for j in range(1,6)], cmap='jet')
82
+ sage: M[0].get_minmax_data()
83
+ {'xmax': 4.5, 'xmin': -0.5, 'ymax': 4.5, 'ymin': -0.5}
84
+ sage: M[0].options()['cmap']
85
+ 'jet'
86
+ sage: M[0].xy_array_row
87
+ 5
88
+ """
89
+ self.xrange = xrange
90
+ self.yrange = yrange
91
+ self.xy_data_array = xy_data_array
92
+ if hasattr(xy_data_array, 'shape'):
93
+ self.xy_array_row = xy_data_array.shape[0]
94
+ self.xy_array_col = xy_data_array.shape[1]
95
+ else:
96
+ self.xy_array_row = len(xy_data_array)
97
+ self.xy_array_col = len(xy_data_array[0])
98
+ GraphicPrimitive.__init__(self, options)
99
+
100
+ def get_minmax_data(self):
101
+ """
102
+ Return a dictionary with the bounding box data.
103
+
104
+ EXAMPLES::
105
+
106
+ sage: m = matrix_plot(matrix([[1,3,5,1],[2,4,5,6],[1,3,5,7]]))[0]
107
+ sage: list(sorted(m.get_minmax_data().items()))
108
+ [('xmax', 3.5), ('xmin', -0.5), ('ymax', 2.5), ('ymin', -0.5)]
109
+
110
+ TESTS:
111
+
112
+ We verify that :issue:`27891` is fixed::
113
+
114
+ sage: p = matrix_plot(identity_matrix(5)) + point((2, 2), zorder=1)
115
+ sage: sorted(p.get_minmax_data().items())
116
+ [('xmax', 4.5), ('xmin', -0.5), ('ymax', 4.5), ('ymin', -0.5)]
117
+ """
118
+ from sage.plot.plot import minmax_data
119
+ xrange = self.xrange
120
+ yrange = self.yrange
121
+ # if xrange/yrange are not specified, add offset to the matrix so that,
122
+ # for example, the square representing the (0,0) entry is centered on
123
+ # the origin.
124
+ if not xrange:
125
+ xrange = (-.5, self.xy_array_col - .5)
126
+ if not yrange:
127
+ yrange = (-.5, self.xy_array_row - .5)
128
+ return minmax_data(xrange, yrange, dict=True)
129
+
130
+ def _allowed_options(self):
131
+ """
132
+ Return the allowed options for the MatrixPlot class.
133
+
134
+ EXAMPLES::
135
+
136
+ sage: M = matrix_plot([[sin(i*j) for i in range(5)] for j in range(5)]) # needs sage.symbolic
137
+ sage: isinstance(M[0]._allowed_options(), dict) # needs sage.symbolic
138
+ True
139
+ """
140
+ return {'cmap':"""the name of a predefined colormap,
141
+ a list of colors, or an instance of a
142
+ matplotlib Colormap. Type: import matplotlib.cm; matplotlib.cm.datad.keys()
143
+ for available colormap names.""",
144
+ 'colorbar': "Include a colorbar indicating the levels (dense matrices only)",
145
+ 'colorbar_options': "a dictionary of options for colorbars",
146
+ 'zorder':"The layer level in which to draw",
147
+ 'marker':"The marker for sparse plots",
148
+ 'markersize':"The marker size for sparse plots",
149
+ 'norm': "The normalization function",
150
+ 'vmin': "The minimum value",
151
+ 'vmax': "The maximum value",
152
+ 'flip_y': "If False, draw the matrix with the first row on the bottom of the graph",
153
+ 'subdivisions': "If True, draw subdivisions of the matrix",
154
+ 'subdivision_options': "Options (boundaries and style) of the subdivisions"}
155
+
156
+ def _repr_(self):
157
+ """
158
+ String representation of MatrixPlot primitive.
159
+
160
+ EXAMPLES::
161
+
162
+ sage: M = matrix_plot([[sin(i*j) for i in range(5)] for j in range(5)]) # needs sage.symbolic
163
+ sage: m = M[0]; m # needs sage.symbolic
164
+ MatrixPlot defined by a 5 x 5 data grid
165
+ """
166
+ return "MatrixPlot defined by a {} x {} data grid".format(self.xy_array_row, self.xy_array_col)
167
+
168
+ def _render_on_subplot(self, subplot):
169
+ """
170
+ TESTS::
171
+
172
+ sage: matrix_plot(random_matrix(RDF, 50), cmap='jet')
173
+ Graphics object consisting of 1 graphics primitive
174
+ """
175
+ options = self.options()
176
+ cmap = get_cmap(options.pop('cmap',None))
177
+ flip_y = options['flip_y']
178
+
179
+ norm = options['norm']
180
+
181
+ if norm == 'value':
182
+ import matplotlib
183
+ norm = matplotlib.colors.NoNorm()
184
+
185
+ lim = self.get_minmax_data()
186
+ if options['subdivisions']:
187
+ subdiv_options = options['subdivision_options']
188
+ if isinstance(subdiv_options['boundaries'], (list, tuple)):
189
+ rowsub,colsub = subdiv_options['boundaries']
190
+ else:
191
+ rowsub = subdiv_options['boundaries']
192
+ colsub = subdiv_options['boundaries']
193
+ if isinstance(subdiv_options['style'], (list, tuple)):
194
+ rowstyle,colstyle = subdiv_options['style']
195
+ else:
196
+ rowstyle = subdiv_options['style']
197
+ colstyle = subdiv_options['style']
198
+ if rowstyle is None:
199
+ rowstyle = {}
200
+ if colstyle is None:
201
+ colstyle = {}
202
+
203
+ # Make line objects for subdivisions
204
+ from .line import line2d
205
+ # First draw horizontal lines representing row subdivisions
206
+ for y in rowsub:
207
+ y = lim['ymin'] + ((lim['ymax'] - lim['ymin'])
208
+ * y / self.xy_array_row)
209
+ l = line2d([(lim['xmin'], y), (lim['xmax'], y)], **rowstyle)[0]
210
+ l._render_on_subplot(subplot)
211
+ for x in colsub:
212
+ x = lim['xmin'] + ((lim['xmax'] - lim['xmin'])
213
+ * x / self.xy_array_col)
214
+ l = line2d([(x, lim['ymin']), (x, lim['ymax'])], **colstyle)[0]
215
+ l._render_on_subplot(subplot)
216
+
217
+ if hasattr(self.xy_data_array, 'tocoo'):
218
+ # Sparse matrix -- use spy
219
+ opts = options.copy()
220
+ for opt in ['vmin', 'vmax', 'norm', 'flip_y', 'subdivisions',
221
+ 'subdivision_options', 'colorbar', 'colorbar_options']:
222
+ del opts[opt]
223
+ subplot.spy(self.xy_data_array, **opts)
224
+ else:
225
+ extent = (lim['xmin'], lim['xmax'],
226
+ lim['ymax' if flip_y else 'ymin'],
227
+ lim['ymin' if flip_y else 'ymax'])
228
+ opts = {'cmap': cmap, 'interpolation': 'nearest',
229
+ 'aspect': 'equal', 'norm': norm,
230
+ 'vmin': options['vmin'], 'vmax': options['vmax'],
231
+ 'origin': ('upper' if flip_y else 'lower'),
232
+ 'extent': extent, 'zorder': options.get('zorder')}
233
+ image = subplot.imshow(self.xy_data_array, **opts)
234
+
235
+ if options.get('colorbar', False):
236
+ colorbar_options = options['colorbar_options']
237
+ from matplotlib import colorbar
238
+ cax,kwds = colorbar.make_axes_gridspec(subplot, **colorbar_options)
239
+ colorbar.Colorbar(cax, image, **kwds)
240
+
241
+ if flip_y:
242
+ subplot.xaxis.tick_top()
243
+ else:
244
+ subplot.xaxis.tick_bottom()
245
+ subplot.xaxis.set_ticks_position('both') # only tick marks, not tick labels
246
+
247
+
248
+ @suboptions('colorbar', orientation='vertical', format=None)
249
+ @suboptions('subdivision',boundaries=None, style=None)
250
+ @options(aspect_ratio=1, axes=False, cmap='Greys', colorbar=False,
251
+ frame=True, marker='.', norm=None, flip_y=True,
252
+ subdivisions=False, ticks_integer=True, vmin=None, vmax=None)
253
+ def matrix_plot(mat, xrange=None, yrange=None, **options):
254
+ r"""
255
+ A plot of a given matrix or 2D array.
256
+
257
+ If the matrix is sparse, colors only indicate whether an element is
258
+ nonzero or zero, so the plot represents the sparsity pattern of the
259
+ matrix.
260
+
261
+ If the matrix is dense, each matrix element is given a different
262
+ color value depending on its relative size compared to the other
263
+ elements in the matrix.
264
+
265
+ The default is for the lowest number to be black and the highest
266
+ number to be white in a greyscale pattern; see the information about
267
+ normalizing below. To reverse this, use ``cmap='Greys'``.
268
+
269
+ The tick marks drawn on the frame axes denote the row numbers
270
+ (vertical ticks) and the column numbers (horizontal ticks) of the
271
+ matrix.
272
+
273
+ INPUT:
274
+
275
+ - ``mat`` -- a 2D matrix or array
276
+
277
+ - ``xrange`` -- (default: ``None``) tuple of the horizontal extent
278
+ ``(xmin, xmax)`` of the bounding box in which to draw the matrix. The
279
+ image is stretched individually along x and y to fill the box.
280
+
281
+ If ``None``, the extent is determined by the following conditions. Matrix
282
+ entries have unit size in data coordinates. Their centers are on integer
283
+ coordinates, and their center coordinates range from 0 to columns-1
284
+ horizontally and from 0 to rows-1 vertically.
285
+
286
+ If the matrix is sparse, this keyword is ignored.
287
+
288
+ - ``yrange`` -- (default: ``None``) tuple of the vertical extent
289
+ ``(ymin, ymax)`` of the bounding box in which to draw the matrix.
290
+ See ``xrange`` for details.
291
+
292
+ The following input must all be passed in as named parameters, if
293
+ default not used:
294
+
295
+ - ``cmap`` -- a colormap (default: ``'Greys'``); the name of a predefined
296
+ colormap, a list of colors, or an instance of a matplotlib Colormap
297
+
298
+ The list of predefined color maps can be visualized in `matplotlib's
299
+ documentation
300
+ <https://matplotlib.org/examples/color/colormaps_reference.html>`__. You
301
+ can also type ``import matplotlib.cm; matplotlib.cm.datad.keys()`` to list
302
+ their names.
303
+
304
+ - ``colorbar`` -- boolean (default: ``False``); show a colorbar or not
305
+ (dense matrices only)
306
+
307
+ The following options are used to adjust the style and placement
308
+ of colorbars. They have no effect if a colorbar is not shown.
309
+
310
+ - ``colorbar_orientation`` -- string (default: ``'vertical'``);
311
+ controls placement of the colorbar, can be either 'vertical'
312
+ or 'horizontal'
313
+
314
+ - ``colorbar_format`` -- a format string, this is used to format
315
+ the colorbar labels
316
+
317
+ - ``colorbar_options`` -- dictionary of options for the matplotlib
318
+ colorbar API. Documentation for the :mod:`matplotlib.colorbar` module
319
+ has details.
320
+
321
+ - ``norm`` -- if ``None`` (default), the value range is scaled to the interval
322
+ [0,1]. If 'value', then the actual value is used with no
323
+ scaling. A :class:`matplotlib.colors.Normalize` instance may
324
+ also passed.
325
+
326
+ - ``vmin`` -- the minimum value (values below this are set to this value)
327
+
328
+ - ``vmax`` -- the maximum value (values above this are set to this value)
329
+
330
+ - ``flip_y`` -- boolean (default: ``True``); if ``False``, the first row of the
331
+ matrix is on the bottom of the graph. Otherwise, the first row is on the
332
+ top of the graph.
333
+
334
+ - ``subdivisions`` -- if ``True``, plot the subdivisions of the matrix as lines
335
+
336
+ - ``subdivision_boundaries`` -- list of lists in the form
337
+ ``[row_subdivisions, column_subdivisions]``, which specifies
338
+ the row and column subdivisions to use. If not specified,
339
+ defaults to the matrix subdivisions
340
+
341
+ - ``subdivision_style`` -- dictionary of properties passed
342
+ on to the :func:`~sage.plot.line.line2d` command for plotting
343
+ subdivisions. If this is a two-element list or tuple, then it
344
+ specifies the styles of row and column divisions, respectively.
345
+
346
+ EXAMPLES:
347
+
348
+ A matrix over `\ZZ` colored with different grey levels::
349
+
350
+ sage: matrix_plot(matrix([[1,3,5,1],[2,4,5,6],[1,3,5,7]]))
351
+ Graphics object consisting of 1 graphics primitive
352
+
353
+ .. PLOT::
354
+
355
+ P = matrix_plot(matrix([[1,3,5,1],[2,4,5,6],[1,3,5,7]]))
356
+ sphinx_plot(P)
357
+
358
+ Here we make a random matrix over `\RR` and use ``cmap='hsv'``
359
+ to color the matrix elements different RGB colors::
360
+
361
+ sage: matrix_plot(random_matrix(RDF, 50), cmap='hsv')
362
+ Graphics object consisting of 1 graphics primitive
363
+
364
+ By default, entries are scaled to the interval [0,1] before
365
+ determining colors from the color map. That means the two plots
366
+ below are the same::
367
+
368
+ sage: P = matrix_plot(matrix(2,[1,1,3,3]))
369
+ sage: Q = matrix_plot(matrix(2,[2,2,3,3]))
370
+ sage: P; Q
371
+ Graphics object consisting of 1 graphics primitive
372
+ Graphics object consisting of 1 graphics primitive
373
+
374
+ However, we can specify which values scale to 0 or 1 with the
375
+ ``vmin`` and ``vmax`` parameters (values outside the range are
376
+ clipped). The two plots below are now distinguished::
377
+
378
+ sage: P = matrix_plot(matrix(2,[1,1,3,3]), vmin=0, vmax=3, colorbar=True)
379
+ sage: Q = matrix_plot(matrix(2,[2,2,3,3]), vmin=0, vmax=3, colorbar=True)
380
+ sage: P; Q
381
+ Graphics object consisting of 1 graphics primitive
382
+ Graphics object consisting of 1 graphics primitive
383
+
384
+ We can also specify a norm function of 'value', which means that
385
+ there is no scaling performed::
386
+
387
+ sage: matrix_plot(random_matrix(ZZ,10)*.05, norm='value', colorbar=True)
388
+ Graphics object consisting of 1 graphics primitive
389
+
390
+ Matrix subdivisions can be plotted as well::
391
+
392
+ sage: m=random_matrix(RR,10)
393
+ sage: m.subdivide([2,4],[6,8])
394
+ sage: matrix_plot(m, subdivisions=True,
395
+ ....: subdivision_style=dict(color='red',thickness=3))
396
+ Graphics object consisting of 1 graphics primitive
397
+
398
+ You can also specify your own subdivisions and separate styles
399
+ for row or column subdivisions::
400
+
401
+ sage: m=random_matrix(RR,10)
402
+ sage: matrix_plot(m, subdivisions=True, subdivision_boundaries=[[2,4],[6,8]],
403
+ ....: subdivision_style=[dict(color='red',thickness=3),
404
+ ....: dict(linestyle='--',thickness=6)])
405
+ Graphics object consisting of 1 graphics primitive
406
+
407
+ Generally matrices are plotted with the (0,0) entry in the upper
408
+ left. However, sometimes if we are plotting an image, we'd like
409
+ the (0,0) entry to be in the lower left. We can do that with the
410
+ ``flip_y`` argument::
411
+
412
+ sage: matrix_plot(identity_matrix(100), flip_y=False)
413
+ Graphics object consisting of 1 graphics primitive
414
+
415
+ A custom bounding box in which to draw the matrix can be specified using
416
+ the ``xrange`` and ``yrange`` arguments::
417
+
418
+ sage: P = matrix_plot(identity_matrix(10), xrange=(0, pi), yrange=(-pi, 0)); P # needs sage.symbolic
419
+ Graphics object consisting of 1 graphics primitive
420
+ sage: P.get_minmax_data() # needs sage.symbolic
421
+ {'xmax': 3.14159..., 'xmin': 0.0, 'ymax': 0.0, 'ymin': -3.14159...}
422
+
423
+ If the horizontal and vertical dimension of the image are very different,
424
+ the default ``aspect_ratio=1`` may be unsuitable and can be changed to
425
+ ``automatic``::
426
+
427
+ sage: matrix_plot(random_matrix(RDF, 2, 2), (-100, 100), (0, 1),
428
+ ....: aspect_ratio='automatic')
429
+ Graphics object consisting of 1 graphics primitive
430
+
431
+ Another random plot, but over `\GF{389}`::
432
+
433
+ sage: m = random_matrix(GF(389), 10) # needs sage.rings.finite_rings
434
+ sage: matrix_plot(m, cmap='Oranges') # needs sage.rings.finite_rings
435
+ Graphics object consisting of 1 graphics primitive
436
+
437
+ It also works if you lift it to the polynomial ring::
438
+
439
+ sage: matrix_plot(m.change_ring(GF(389)['x']), cmap='Oranges') # needs sage.rings.finite_rings
440
+ Graphics object consisting of 1 graphics primitive
441
+
442
+ We have several options for colorbars::
443
+
444
+ sage: matrix_plot(random_matrix(RDF, 50), colorbar=True,
445
+ ....: colorbar_orientation='horizontal')
446
+ Graphics object consisting of 1 graphics primitive
447
+
448
+ ::
449
+
450
+ sage: matrix_plot(random_matrix(RDF, 50), colorbar=True, colorbar_format='%.3f')
451
+ Graphics object consisting of 1 graphics primitive
452
+
453
+ The length of a color bar and the length of the adjacent
454
+ matrix plot dimension may be quite different. This example
455
+ shows how to adjust the length of the colorbar by passing a
456
+ dictionary of options to the matplotlib colorbar routines. ::
457
+
458
+ sage: m = random_matrix(ZZ, 40, 80, x=-10, y=10)
459
+ sage: m.plot(colorbar=True, colorbar_orientation='vertical',
460
+ ....: colorbar_options={'shrink':0.50})
461
+ Graphics object consisting of 1 graphics primitive
462
+
463
+ Here we plot a random sparse matrix::
464
+
465
+ sage: sparse = matrix(dict(((randint(0, 10), randint(0, 10)), 1)
466
+ ....: for i in range(100)))
467
+ sage: matrix_plot(sparse)
468
+ Graphics object consisting of 1 graphics primitive
469
+
470
+ ::
471
+
472
+ sage: A = random_matrix(ZZ, 100000, density=.00001, sparse=True)
473
+ sage: matrix_plot(A, marker=',')
474
+ Graphics object consisting of 1 graphics primitive
475
+
476
+ As with dense matrices, sparse matrix entries are automatically
477
+ converted to floating point numbers before plotting. Thus the
478
+ following works::
479
+
480
+ sage: b = random_matrix(GF(2), 200, sparse=True, density=0.01) # needs sage.rings.finite_rings
481
+ sage: matrix_plot(b) # needs sage.rings.finite_rings
482
+ Graphics object consisting of 1 graphics primitive
483
+
484
+ While this returns an error::
485
+
486
+ sage: b = random_matrix(CDF, 200, sparse=True, density=0.01)
487
+ sage: matrix_plot(b)
488
+ Traceback (most recent call last):
489
+ ...
490
+ ValueError: cannot convert entries to floating point numbers
491
+
492
+ To plot the absolute value of a complex matrix, use the
493
+ ``apply_map`` method::
494
+
495
+ sage: b = random_matrix(CDF, 200, sparse=True, density=0.01)
496
+ sage: matrix_plot(b.apply_map(abs))
497
+ Graphics object consisting of 1 graphics primitive
498
+
499
+ Plotting lists of lists also works::
500
+
501
+ sage: matrix_plot([[1,3,5,1],[2,4,5,6],[1,3,5,7]])
502
+ Graphics object consisting of 1 graphics primitive
503
+
504
+ As does plotting of NumPy arrays::
505
+
506
+ sage: import numpy # needs numpy
507
+ sage: matrix_plot(numpy.random.rand(10, 10)) # needs numpy
508
+ Graphics object consisting of 1 graphics primitive
509
+
510
+ A plot title can be added to the matrix plot.::
511
+
512
+ sage: matrix_plot(identity_matrix(50), flip_y=False, title='not identity')
513
+ Graphics object consisting of 1 graphics primitive
514
+
515
+ The title position is adjusted upwards if the ``flip_y`` keyword is set
516
+ to ``True`` (this is the default).::
517
+
518
+ sage: matrix_plot(identity_matrix(50), title='identity')
519
+ Graphics object consisting of 1 graphics primitive
520
+
521
+ TESTS::
522
+
523
+ sage: P.<t> = RR[]
524
+ sage: M = random_matrix(P, 3, 3)
525
+ sage: (i,j) = (ZZ.random_element(3), ZZ.random_element(3))
526
+ sage: M[i,j] = P.random_element(degree=(1,5)) # always nonconstant
527
+ sage: matrix_plot(M)
528
+ Traceback (most recent call last):
529
+ ...
530
+ TypeError: cannot convert nonconstant polynomial
531
+
532
+ ::
533
+
534
+ sage: matrix_plot([1,2,3])
535
+ Traceback (most recent call last):
536
+ ...
537
+ TypeError: mat must be a Matrix or a two dimensional array
538
+
539
+ ::
540
+
541
+ sage: matrix_plot([[sin(x), cos(x)], [1, 0]]) # needs sage.symbolic
542
+ Traceback (most recent call last):
543
+ ...
544
+ TypeError: mat must be a Matrix or a two dimensional array
545
+
546
+ Test that sparse matrices also work with subdivisions::
547
+
548
+ sage: matrix_plot(sparse, subdivisions=True, subdivision_boundaries=[[2,4],[6,8]])
549
+ Graphics object consisting of 1 graphics primitive
550
+
551
+ Test that matrix plots have aspect ratio one (see :issue:`15315`)::
552
+
553
+ sage: P = matrix_plot(random_matrix(RDF, 5))
554
+ sage: P.aspect_ratio()
555
+ 1
556
+
557
+ The origin keyword is deprecated::
558
+
559
+ sage: matrix_plot(identity_matrix(100), origin='lower')
560
+ doctest:...: DeprecationWarning: the option 'origin' is replaced by 'flip_y'
561
+ See https://github.com/sagemath/sage/issues/27891 for details.
562
+ Graphics object consisting of 1 graphics primitive
563
+ """
564
+ if 'origin' in options:
565
+ from sage.misc.superseded import deprecation
566
+ deprecation(27891, "the option 'origin' is replaced by 'flip_y'")
567
+ options['flip_y'] = (options['origin'] != 'lower')
568
+ del options['origin']
569
+
570
+ import numpy as np
571
+ import scipy.sparse as scipysparse
572
+ from sage.plot.all import Graphics
573
+ from sage.structure.element import Matrix
574
+ from sage.rings.real_double import RDF
575
+ orig_mat = mat
576
+ if isinstance(mat, Matrix):
577
+ sparse = mat.is_sparse()
578
+ if sparse:
579
+ entries = list(mat._dict().items())
580
+ try:
581
+ data = np.asarray([d for _,d in entries], dtype=float)
582
+ except Exception:
583
+ raise ValueError("cannot convert entries to floating point numbers")
584
+ positions = np.asarray([[row for (row,col),_ in entries],
585
+ [col for (row,col),_ in entries]], dtype=int)
586
+ mat = scipysparse.coo_matrix((data,positions), shape=(mat.nrows(), mat.ncols()))
587
+ else:
588
+ mat = mat.change_ring(RDF).numpy()
589
+ elif hasattr(mat, 'tocoo'):
590
+ sparse = True
591
+ else:
592
+ sparse = False
593
+
594
+ try:
595
+ if sparse:
596
+ xy_data_array = mat
597
+ else:
598
+ xy_data_array = np.asarray(mat, dtype=float)
599
+ except TypeError:
600
+ raise TypeError("mat must be a Matrix or a two dimensional array")
601
+ except ValueError:
602
+ raise ValueError("cannot convert entries to floating point numbers")
603
+
604
+ if len(xy_data_array.shape) < 2:
605
+ raise TypeError("mat must be a Matrix or a two dimensional array")
606
+
607
+ # Sparse matrices are not plotted with imshow, so extent is not supported,
608
+ # hence we ignore custom bounds.
609
+ if sparse:
610
+ xrange = None
611
+ yrange = None
612
+ if xrange:
613
+ xrange = tuple(float(v) for v in xrange)
614
+ if yrange:
615
+ yrange = tuple(float(v) for v in yrange)
616
+
617
+ if options['subdivisions'] and options['subdivision_options']['boundaries'] is None:
618
+ options['subdivision_options']['boundaries'] = orig_mat.get_subdivisions()
619
+
620
+ # Custom position the title. Otherwise it overlaps with tick labels
621
+ if options['flip_y'] and 'title_pos' not in options:
622
+ options['title_pos'] = (0.5, 1.05)
623
+
624
+ g = Graphics()
625
+ g._set_extra_kwds(Graphics._extract_kwds_for_show(options))
626
+ # Keep flip_y for _render_on_subplot
627
+ options['flip_y'] = g._extra_kwds['flip_y']
628
+ g.add_primitive(MatrixPlot(xy_data_array, xrange, yrange, options))
629
+ return g