Ticket #14175: trac_14175_plot_options.patch
File trac_14175_plot_options.patch, 11.7 KB (added by , 9 years ago) |
---|
-
sage/geometry/polyhedron/base.py
# HG changeset patch # User Volker Braun <vbraun@stp.dias.ie> # Date 1362210542 36000 # Node ID cc1407623ad3fd8765aaa666f84d0d3129ad99b9 # Parent d636994612526f2134cd5e4617439b41aa656e3e #14175: More plot options for polytopes diff --git a/sage/geometry/polyhedron/base.py b/sage/geometry/polyhedron/base.py
a b class Polyhedron_base(Element): 420 420 for other_H, self_V in 421 421 CartesianProduct(other.Hrepresentation(), self.Vrepresentation()) ) 422 422 423 def plot(self, **kwds): 423 def plot(self, 424 point=None, line=None, polygon=None, # None means unspecified by the user 425 wireframe='blue', fill='green', 426 **kwds): 424 427 """ 425 428 Return a graphical representation. 426 429 427 430 INPUT: 428 431 429 - ``**kwds`` -- optional keyword parameters. 430 431 See :func:`render_2d`, :func:`render_3d`, :func:`render_4d` 432 for a description of available options for different ambient 433 space dimensions. 432 - ``point``, ``line``, ``polygon`` -- Parameters to pass to 433 point (0d), line (1d), and polygon (2d) plot commands. 434 Allowed values are: 435 436 * A Python dictionary to be passed as keywords to the plot 437 commands. 438 439 * A string or triple of numbers: The color. This is 440 equivalent to passing the dictionary ``{'color':...}``. 441 442 * ``False``: Switches off the drawing of the corresponding 443 graphics object 444 445 - ``wireframe``, ``fill`` -- Similar to ``point``, ``line``, 446 and ``polygon``, but ``fill`` is used for the graphics 447 objects in the dimension of the polytope (or of dimension 2 448 for higher dimensional polytopes) and ``wireframe`` is used 449 for all lower-dimensional graphics objects 450 (default: 'green' for fill and 'blue' for wireframe) 451 452 - ``**kwds`` -- optional keyword parameters that are passed to 453 all graphics objects. 434 454 435 455 OUTPUT: 436 456 437 A graphics object. 457 A (multipart) graphics object. 458 459 EXAMPLES:: 460 461 sage: square = polytopes.n_cube(2) 462 sage: point = Polyhedron([[1,1]]) 463 sage: line = Polyhedron([[1,1],[2,1]]) 464 sage: cube = polytopes.n_cube(3) 465 sage: hypercube = polytopes.n_cube(4) 466 467 By default, the wireframe is rendered in blue and the fill in green:: 468 469 sage: square.plot() 470 sage: point.plot() 471 sage: line.plot() 472 sage: cube.plot() 473 sage: hypercube.plot() 474 475 Draw the lines in red and nothing else:: 476 477 sage: square.plot(point=False, line='red', polygon=False) 478 sage: point.plot(point=False, line='red', polygon=False) 479 sage: line.plot(point=False, line='red', polygon=False) 480 sage: cube.plot(point=False, line='red', polygon=False) 481 sage: hypercube.plot(point=False, line='red', polygon=False) 482 483 Draw points in red, no lines, and a blue polygon:: 484 485 sage: square.plot(point={'color':'red'}, line=False, polygon=(0,0,1)) 486 sage: point.plot(point={'color':'red'}, line=False, polygon=(0,0,1)) 487 sage: line.plot(point={'color':'red'}, line=False, polygon=(0,0,1)) 488 sage: cube.plot(point={'color':'red'}, line=False, polygon=(0,0,1)) 489 sage: hypercube.plot(point={'color':'red'}, line=False, polygon=(0,0,1)) 490 491 If we instead use the ``fill`` and ``wireframe`` options, the 492 coloring depends on the dimension of the object:: 493 494 sage: square.plot(fill='green', wireframe='red') 495 sage: point.plot(fill='green', wireframe='red') 496 sage: line.plot(fill='green', wireframe='red') 497 sage: cube.plot(fill='green', wireframe='red') 498 sage: hypercube.plot(fill='green', wireframe='red') 438 499 439 500 TESTS:: 440 501 441 sage: polytopes.n_cube(2).plot() 502 sage: for p in square.plot(): 503 ... print p.options()['rgbcolor'], p 504 blue Point set defined by 4 point(s) 505 blue Line defined by 2 points 506 blue Line defined by 2 points 507 blue Line defined by 2 points 508 blue Line defined by 2 points 509 green Polygon defined by 4 points 510 511 sage: for p in line.plot(): 512 ... print p.options()['rgbcolor'], p 513 blue Point set defined by 2 point(s) 514 green Line defined by 2 points 515 516 sage: for p in point.plot(): 517 ... print p.options()['rgbcolor'], p 518 green Point set defined by 1 point(s) 519 520 Draw the lines in red and nothing else:: 521 522 sage: for p in square.plot(point=False, line='red', polygon=False): 523 ... print p.options()['rgbcolor'], p 524 red Line defined by 2 points 525 red Line defined by 2 points 526 red Line defined by 2 points 527 red Line defined by 2 points 528 529 Draw vertices in red, no lines, and a blue polygon:: 530 531 sage: for p in square.plot(point={'color':'red'}, line=False, polygon=(0,0,1)): 532 ... print p.options()['rgbcolor'], p 533 red Point set defined by 4 point(s) 534 (0, 0, 1) Polygon defined by 4 points 535 536 sage: for p in line.plot(point={'color':'red'}, line=False, polygon=(0,0,1)): 537 ... print p.options()['rgbcolor'], p 538 red Point set defined by 2 point(s) 539 540 sage: for p in point.plot(point={'color':'red'}, line=False, polygon=(0,0,1)): 541 ... print p.options()['rgbcolor'], p 542 red Point set defined by 1 point(s) 543 544 Draw in red without wireframe:: 545 546 sage: for p in square.plot(wireframe=False, fill="red"): 547 ... print p.options()['rgbcolor'], p 548 red Polygon defined by 4 points 549 550 sage: for p in line.plot(wireframe=False, fill="red"): 551 ... print p.options()['rgbcolor'], p 552 red Line defined by 2 points 553 554 sage: for p in point.plot(wireframe=False, fill="red"): 555 ... print p.options()['rgbcolor'], p 556 red Point set defined by 1 point(s) 442 557 """ 558 def merge_options(*opts): 559 merged = dict() 560 for i in range(len(opts)): 561 opt = opts[i] 562 if opt is None: 563 continue 564 elif opt is False: 565 return False 566 elif isinstance(opt, (basestring, list, tuple)): 567 merged['color'] = opt 568 else: 569 merged.update(opt) 570 return merged 571 572 d = min(self.dim(), 2) 573 opts = [wireframe] * d + [fill] + [False] * (2-d) 574 # The point/line/polygon options take precedence over wireframe/fill 575 opts = [merge_options(opt1, opt2, kwds) 576 for opt1, opt2 in zip(opts, [point, line, polygon])] 577 443 578 from plot import render_2d, render_3d, render_4d 444 579 render_method = [ None, None, render_2d, render_3d, render_4d ] 445 580 if self.ambient_dim() < len(render_method): 446 581 render = render_method[self.ambient_dim()] 447 582 if render != None: 448 return render(self, **kwds)583 return render(self, *opts) 449 584 raise NotImplementedError('Plotting of '+str(self.ambient_dim())+ 450 585 '-dimensional polyhedra not implemented') 451 586 -
sage/geometry/polyhedron/plot.py
diff --git a/sage/geometry/polyhedron/plot.py b/sage/geometry/polyhedron/plot.py
a b from constructor import Polyhedron 29 29 30 30 31 31 ############################################################# 32 def render_2d(projection, **kwds):32 def render_2d(projection, point_opts={}, line_opts={}, polygon_opts={}): 33 33 """ 34 34 Return 2d rendering of the projection of a polyhedron into 35 35 2-dimensional ambient space. … … def render_2d(projection, **kwds): 54 54 """ 55 55 if is_Polyhedron(projection): 56 56 projection = Projection(projection) 57 return \ 58 projection.render_points_2d(zorder=2, pointsize=10, **kwds) + \ 59 projection.render_outline_2d(zorder=1, **kwds) + \ 60 projection.render_fill_2d(zorder=0, rgbcolor=(0,1,0), **kwds) 57 from sage.plot.graphics import Graphics 58 plt = Graphics() 59 if isinstance(point_opts, dict): 60 point_opts.setdefault('zorder', 2) 61 point_opts.setdefault('pointsize', 10) 62 plt += projection.render_points_2d(**point_opts) 63 if isinstance(line_opts, dict): 64 line_opts.setdefault('zorder', 1) 65 plt += projection.render_outline_2d(**line_opts) 66 if isinstance(polygon_opts, dict): 67 polygon_opts.setdefault('zorder', 0) 68 plt += projection.render_fill_2d(**polygon_opts) 69 return plt 61 70 62 71 63 def render_3d(projection, **kwds):72 def render_3d(projection, point_opts={}, line_opts={}, polygon_opts={}): 64 73 """ 65 74 Return 3d rendering of a polyhedron projected into 66 75 3-dimensional ambient space. … … def render_3d(projection, **kwds): 90 99 """ 91 100 if is_Polyhedron(projection): 92 101 projection = Projection(projection) 93 return \ 94 projection.render_vertices_3d(width=3, color='green', **kwds) +\ 95 projection.render_wireframe_3d(width=3, color='green', **kwds) + \ 96 projection.render_solid_3d(**kwds) 102 from sage.plot.plot3d.base import Graphics3d 103 plt = Graphics3d() 104 if isinstance(point_opts, dict): 105 point_opts.setdefault('width', 3) 106 plt += projection.render_vertices_3d(**point_opts) 107 if isinstance(line_opts, dict): 108 line_opts.setdefault('width', 3) 109 plt += projection.render_wireframe_3d(**line_opts) 110 if isinstance(polygon_opts, dict): 111 plt += projection.render_solid_3d(**polygon_opts) 112 return plt 97 113 98 99 def render_4d(polyhedron, **kwds): 114 def render_4d(polyhedron, point_opts={}, line_opts={}, polygon_opts={}, projection_direction=None): 100 115 """ 101 116 Return a 3d rendering of the Schlegel projection of a 4d 102 117 polyhedron projected into 3-dimensional space. … … def render_4d(polyhedron, **kwds): 111 126 - ``polyhedron`` -- A 112 127 :mod:`~sage.geometry.polyhedron.constructor.Polyhedron` object. 113 128 114 - ``kwds`` -- plot keywords. Passing 115 ``projection_direction=<list>`` sets the projetion direction of 116 the Schlegel projection. If it is not given, the center of a 117 facet is used. 129 - ``point_opts``, ``line_opts``, ``polygon_opts`` -- dictionaries 130 of plot keywords or ``False`` to disable. 131 132 - ``projection_direction`` -- list/tuple/iterable of coordinates 133 or ``None`` (default). Sets the projetion direction of the 134 Schlegel projection. If it is not given, the center of a facet 135 is used. 118 136 119 137 EXAMPLES:: 120 138 … … def render_4d(polyhedron, **kwds): 135 153 sage: tach_str.count('FCylinder') 136 154 32 137 155 """ 138 projection_direction = None 139 try: 140 projection_direction = kwds.pop('projection_direction') 141 except KeyError: 156 if projection_direction is None: 142 157 for ineq in polyhedron.inequality_generator(): 143 158 center = [v() for v in ineq.incident() if v.is_vertex()] 144 159 center = sum(center) / len(center) … … def render_4d(polyhedron, **kwds): 146 161 projection_direction = center 147 162 break 148 163 projection_3d = Projection(polyhedron).schlegel(projection_direction) 149 return render_3d(projection_3d, **kwds)164 return render_3d(projection_3d, point_opts, line_opts, polygon_opts) 150 165 151 166 152 167