Skip to content
This repository was archived by the owner on Jan 30, 2023. It is now read-only.

Commit

Permalink
Add 2d graphics to the ipython notebook
Browse files Browse the repository at this point in the history
  • Loading branch information
vbraun committed Sep 20, 2014
1 parent 7db4081 commit e7e7f9c
Show file tree
Hide file tree
Showing 10 changed files with 429 additions and 64 deletions.
1 change: 1 addition & 0 deletions src/doc/en/reference/structure/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Basic Structures
sage/structure/element_wrapper
sage/structure/indexed_generators
sage/structure/global_options
sage/structure/graphics_file

sage/sets/cartesian_product
sage/sets/family
Expand Down
16 changes: 5 additions & 11 deletions src/sage/geometry/polyhedron/plot.py
Original file line number Diff line number Diff line change
Expand Up @@ -714,25 +714,19 @@ def show(self, *args, **kwds):
deprecation(16625, 'use Projection.plot instead')
return self.plot(*args, **kwds)

def _graphics_(self):
def _graphics_(self, **kwds):
"""
Display projection graphically on the Sage command line.
See :meth:`~sage.plot.graphics.Graphics._graphics_`.
EXAMPLES::
sage: polytopes.n_cube(3).projection()._graphics_()
False
sage: polytopes.n_cube(3).projection()._graphics_(
....: mime_types={'image/png'})
Graphics file image/png
"""
from sage.doctest import DOCTEST_MODE
if DOCTEST_MODE:
return False
try:
self.plot().show()
return True
except AttributeError:
return False
return self.plot()._graphics_(**kwds)

def _init_from_2d(self, polyhedron):
"""
Expand Down
8 changes: 4 additions & 4 deletions src/sage/interfaces/sage0.py
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,7 @@ def new(self, x):

class SageElement(ExpectElement):

def _graphics_(self):
def _graphics_(self, **kwds):
"""
Disable graphical output.
Expand All @@ -436,10 +436,10 @@ def _graphics_(self):
EXAMPLES::
sage: m = sage0(4)
sage: m._graphics_()
False
sage: m._graphics_() is None
True
"""
return False
return None

def __getattr__(self, attrname):
"""
Expand Down
8 changes: 4 additions & 4 deletions src/sage/misc/sage_input.py
Original file line number Diff line number Diff line change
Expand Up @@ -1428,7 +1428,7 @@ def __getattr__(self, attr):
"""
return SIE_getattr(self._sie_builder, self, attr)

def _graphics_(self):
def _graphics_(self, **kwds):
"""
Disable graphical output.
Expand All @@ -1440,10 +1440,10 @@ def _graphics_(self):
sage: from sage.misc.sage_input import SageInputBuilder
sage: sib = SageInputBuilder()
sage: sie = sib.name('x')
sage: sie._graphics_()
False
sage: sie._graphics_() is None
True
"""
return False
return None

def __pow__(self, other):
r"""
Expand Down
81 changes: 55 additions & 26 deletions src/sage/plot/graphics.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
from sage.misc.html import html
from sage.misc.temporary_file import tmp_filename, graphics_filename
from sage.structure.sage_object import SageObject
from sage.structure.graphics_file import GraphicsFile
from sage.misc.decorators import suboptions
from colors import rgbcolor

Expand Down Expand Up @@ -129,6 +130,8 @@ class Graphics(SageObject):
sage: isinstance(g2, Graphics)
True
.. automethod:: _graphics_
"""

def __init__(self):
Expand Down Expand Up @@ -818,29 +821,54 @@ def _repr_(self):
"""
return self.__str__()

def _graphics_(self):
def _graphics_(self, mime_types=None, figsize=None, dpi=None):
"""
Show graphics.
Magic graphics method.
The presence of this method is used by the displayhook to
decide that we want to see a graphical output by default.
INPUT:
- ``mime_types`` -- set of mime types (as strings).
- ``figsize`` -- pair of integers (optional). The desired
graphics size in pixels. Suggested, but need not be
respected by the output.
- ``dpi`` -- integer (optional). The desired resolution in
dots per inch. Suggested, but need not be respected by the
output.
OUTPUT:
Return ``True`` if graphical output was generated (might not
be shown in doctest mode), otherwise ``False``.
Return an instance of
:class:`sage.structure.graphics_file.GraphicsFile`
encapsulating a suitable image file. If ``mime_types`` is
specified, the resulting file format must match one of these.
Alternatively, this method can return ``None`` to indicate
that textual representation is preferable and/or no graphics
with the desired mime type can be generated.
EXAMPLES::
sage: g = Graphics()
sage: g._graphics_()
True
Graphics file image/png
sage: [g, g]
[Graphics object consisting of 0 graphics primitives,
Graphics object consisting of 0 graphics primitives]
sage: g._graphics_(mime_types={'foo/bar'}) is None
True
"""
self.show()
return True
from sage.structure.graphics_file import Mime, graphics_from_save
preference = [Mime.PNG, Mime.SVG, Mime.JPG, Mime.PDF]
return graphics_from_save(self.save, preference,
allowed_mime_types=mime_types,
figsize=figsize, dpi=dpi)

def __str__(self):
r"""
Expand Down Expand Up @@ -1866,9 +1894,9 @@ def show(self, filename=None, linkmode=False, **kwds):
else:
html("<img src='cell://%s'>" % filename)
return
if not sage.doctest.DOCTEST_MODE:
os.system('%s %s 2>/dev/null 1>/dev/null &'
% (sage.misc.viewer.png_viewer(), filename))

gfx = GraphicsFile(filename, mime_type='image/png')
gfx.launch_viewer()

def xmin(self, xmin=None):
"""
Expand Down Expand Up @@ -2995,10 +3023,13 @@ def description(self):
data.sort()
return '\n'.join(g[1] for g in data)


class GraphicsArray(SageObject):
"""
GraphicsArray takes a (`m` x `n`) list of lists of
graphics objects and plots them all on one canvas.
.. automethod:: _graphics_
"""
def __init__(self, array):
"""
Expand Down Expand Up @@ -3071,27 +3102,26 @@ def _repr_(self):
"""
return self.__str__()

def _graphics_(self):
def _graphics_(self, mime_types=None, figsize=None, dpi=None):
"""
Show graphics.
The presence of this method is used by the displayhook to
decide that we want to see a graphical output by default.
OUTPUT:
Magic graphics method.
Return ``True`` if graphical output was generated (might not
be shown in doctest mode), otherwise ``False``.
See :meth:`sage.plot.graphics.Graphics._graphics_` for details.
EXAMPLES::
sage: from sage.plot.graphics import GraphicsArray
sage: g = GraphicsArray([])
sage: g._graphics_()
Graphics file image/png
sage: g._graphics_(mime_types={'foo/bar'}) is None
True
"""
self.show()
return True
from sage.structure.graphics_file import Mime, graphics_from_save
preference = [Mime.PNG, Mime.SVG, Mime.JPG, Mime.PDF]
return graphics_from_save(self.save, preference,
allowed_mime_types=mime_types,
figsize=figsize, dpi=dpi)

def __str__(self):
"""
Expand Down Expand Up @@ -3355,7 +3385,7 @@ def save_image(self, filename=None, *args, **kwds):


def show(self, filename=None, dpi=DEFAULT_DPI, figsize=None,
axes = None, **kwds):
axes=None, **kwds):
r"""
Show this graphics array using the default viewer.
Expand Down Expand Up @@ -3384,7 +3414,6 @@ def show(self, filename=None, dpi=DEFAULT_DPI, figsize=None,
"""
if filename is None:
filename = graphics_filename()
self.save(filename, dpi=dpi, figsize=figsize, axes = axes, **kwds)
if not sage.doctest.DOCTEST_MODE and not sage.plot.plot.EMBEDDED_MODE:
os.system('%s %s 2>/dev/null 1>/dev/null &'%(
sage.misc.viewer.png_viewer(), filename))
self.save(filename, dpi=dpi, figsize=figsize, axes=axes, **kwds)
gfx = GraphicsFile(filename, mime_type='image/png')
gfx.launch_viewer()
45 changes: 35 additions & 10 deletions src/sage/plot/plot3d/base.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ pi = RDF.pi()
cdef class Graphics3d(SageObject):
"""
This is the baseclass for all 3d graphics objects.
.. automethod:: _graphics_
.. automethod:: __add__
"""
def _repr_(self):
"""
Expand All @@ -81,30 +84,40 @@ cdef class Graphics3d(SageObject):
"""
return str(self)

def _graphics_(self):
def _graphics_(self, mime_types=None, figsize=None, dpi=None):
"""
Show graphics.
Magic graphics method.
The presence of this method is used by the displayhook to
decide that we want to see a graphical output by default.
OUTPUT:
INPUT/OUTPUT:
Return ``True`` if graphical output was generated (might not
be shown in doctest mode), otherwise ``False``.
See :meth:`sage.plot.graphics.Graphics._graphics_` for details.
EXAMPLES::
sage: S = sphere((0, 0, 0), 1)
sage: S._graphics_()
True
sage: S._graphics_(mime_types={'image/png'})
Graphics file image/png
sage: S # also productes graphics
Graphics3d Object
sage: [S, S]
[Graphics3d Object, Graphics3d Object]
"""
self.show()
return True
from sage.structure.graphics_file import (
Mime, graphics_from_save, GraphicsFile)
if (mime_types is None) or (Mime.JMOL in mime_types):
# default to jmol
from sage.misc.temporary_file import tmp_filename
filename = tmp_filename(
ext=os.path.extsep + Mime.extension(Mime.JMOL))
self.save(filename)
return GraphicsFile(filename, Mime.JMOL)
preference = [Mime.PNG, Mime.JPG]
return graphics_from_save(self.save, preference,
allowed_mime_types=mime_types,
figsize=figsize, dpi=dpi)

def __str__(self):
"""
Expand Down Expand Up @@ -1283,6 +1296,8 @@ end_scene""" % (render_params.antialiasing,

def save(self, filename, **kwds):
"""
Save to file.
Save the graphic to an image file (of type: PNG, BMP, GIF, PPM, or TIFF)
rendered using Tachyon, or pickle it (stored as an SOBJ so you can load it
later) depending on the file extension you give the filename.
Expand Down Expand Up @@ -1322,7 +1337,6 @@ end_scene""" % (render_params.antialiasing,
ext = os.path.splitext(filename)[1].lower()
if ext == '' or ext == '.sobj':
SageObject.save(self, filename)
return
elif ext in ['.bmp', '.png', '.gif', '.ppm', '.tiff', '.tif', '.jpg', '.jpeg']:
opts = self._process_viewing_options(kwds)
T = self._prepare_for_tachyon(
Expand All @@ -1341,6 +1355,17 @@ end_scene""" % (render_params.antialiasing,
if ext != '.png':
import PIL.Image as Image
Image.open(out_filename).save(filename)
elif filename.endswith('.spt.zip'):
# Jmol zip archive
opts = self._process_viewing_options(kwds)
zoom = opts['zoom']
T = self._prepare_for_jmol(
opts['frame'],
opts['axes'],
opts['frame_aspect_ratio'],
opts['aspect_ratio'],
zoom)
T.export_jmol(filename, zoom=zoom*100, **kwds)
else:
raise ValueError('filetype not supported by save()')

Expand Down
15 changes: 9 additions & 6 deletions src/sage/repl/display/formatter.py
Original file line number Diff line number Diff line change
Expand Up @@ -264,9 +264,10 @@ def __call__(self, obj):
EXAMPLES::
sage: class FooGraphics(SageObject):
....: def _graphics_(self):
....: def _graphics_(self, **kwds):
....: print('showing graphics')
....: return True
....: from sage.structure.graphics_file import GraphicsFile
....: return GraphicsFile('/nonexistent.png', 'image/png')
....: def _repr_(self):
....: return 'Textual representation'
sage: from sage.repl.display.formatter import SageDoctestTextFormatter
Expand Down Expand Up @@ -308,9 +309,10 @@ def __call__(self, obj):
EXAMPLES::
sage: class FooGraphics(SageObject):
....: def _graphics_(self):
....: def _graphics_(self, **kwds):
....: print('showing graphics')
....: return True
....: from sage.structure.graphics_file import GraphicsFile
....: return GraphicsFile('/nonexistent.png', 'image/png')
....: def _repr_(self):
....: return 'Textual representation'
sage: from sage.repl.display.formatter import SageConsoleTextFormatter
Expand All @@ -321,7 +323,8 @@ def __call__(self, obj):
"""
from sage.structure.sage_object import SageObject
if isinstance(obj, SageObject) and hasattr(obj, '_graphics_'):
success = obj._graphics_()
if success:
gfx = obj._graphics_()
if gfx:
gfx.launch_viewer()
return ''
return super(SageConsoleTextFormatter, self).__call__(obj)
4 changes: 2 additions & 2 deletions src/sage/repl/notebook_ipy.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
DEFAULT_SAGE_NOTEBOOK_CONFIG = Config(
SageNotebookApp = Config(
notebook_dir = NOTEBOOK_DIR,
# log_level = 'DEBUG', # if you want more logs
# open_browser = False, # if you want to avoid browser restart
log_level = 'DEBUG', # if you want more logs
open_browser = False, # if you want to avoid browser restart
),
)

Expand Down
Loading

0 comments on commit e7e7f9c

Please sign in to comment.