From b3e656b4507d9f6544e87641614836dc6275e929 Mon Sep 17 00:00:00 2001 From: Jeroen Demeyer Date: Fri, 20 Dec 2013 13:51:27 +0100 Subject: [PATCH] graphics_filename: return a tmp_filename() if not in EMBEDDED_MODE --- src/sage/matrix/matrix2.pyx | 4 +- src/sage/matrix/matrix_modn_sparse.pyx | 6 +- src/sage/misc/temporary_file.py | 55 +++++++++-- src/sage/plot/graphics.py | 127 +++++++++++-------------- src/sage/plot/plot3d/tachyon.py | 19 ++-- 5 files changed, 112 insertions(+), 99 deletions(-) diff --git a/src/sage/matrix/matrix2.pyx b/src/sage/matrix/matrix2.pyx index e657f6fb26b..3bfdf4819b6 100644 --- a/src/sage/matrix/matrix2.pyx +++ b/src/sage/matrix/matrix2.pyx @@ -35,7 +35,6 @@ from sage.misc.randstate cimport randstate, current_randstate from sage.structure.sequence import Sequence from sage.structure.element import is_Vector from sage.misc.misc import verbose, get_verbose -from sage.misc.temporary_file import graphics_filename from sage.rings.number_field.number_field_base import is_NumberField from sage.rings.integer_ring import ZZ, is_IntegerRing from sage.rings.integer import Integer @@ -7924,7 +7923,7 @@ cdef class Matrix(matrix1.Matrix): EXAMPLE:: sage: M = random_matrix(CC, 4) - sage: M.visualize_structure(os.path.join(SAGE_TMP, "matrix.png")) + sage: M.visualize_structure() """ import gd import os @@ -7979,6 +7978,7 @@ cdef class Matrix(matrix1.Matrix): setPixel((y,x), val) if filename is None: + from sage.misc.temporary_file import graphics_filename filename = graphics_filename() im.writePng(filename) diff --git a/src/sage/matrix/matrix_modn_sparse.pyx b/src/sage/matrix/matrix_modn_sparse.pyx index 3cdc57035dc..12a7bb2ca6b 100644 --- a/src/sage/matrix/matrix_modn_sparse.pyx +++ b/src/sage/matrix/matrix_modn_sparse.pyx @@ -642,12 +642,8 @@ cdef class Matrix_modn_sparse(matrix_sparse.Matrix_sparse): setPixel( (x,y), colorExact((r-delta,g-delta,b-delta)) ) if filename is None: - from sage.misc.temporary_file import graphics_filename, tmp_dir - from sage.doctest import DOCTEST_MODE + from sage.misc.temporary_file import graphics_filename filename = graphics_filename() - if DOCTEST_MODE: - import os - filename = os.path.join(tmp_dir(), filename) im.writePng(filename) diff --git a/src/sage/misc/temporary_file.py b/src/sage/misc/temporary_file.py index 59ec45bec06..2580311a1d8 100644 --- a/src/sage/misc/temporary_file.py +++ b/src/sage/misc/temporary_file.py @@ -120,7 +120,9 @@ def tmp_filename(name="tmp_", ext=""): - ``name`` -- (default: ``"tmp_"``) A prefix for the file name. - - ``ext`` -- (default: ``""``) A suffix for the file name. + - ``ext`` -- (default: ``""``) A suffix for the file name. If you + want a filename extension in the usual sense, this should start + with a dot. OUTPUT: @@ -147,14 +149,51 @@ def tmp_filename(name="tmp_", ext=""): def graphics_filename(ext='png'): """ - Return the next available canonical filename for a plot/graphics - file. + When run from the Sage notebook, return the next available canonical + filename for a plot/graphics file in the current working directory. + Otherwise, return a temporary file inside ``SAGE_TMP``. + + INPUT: + + - ``ext`` -- (default: ``"png"``) A file extension (without the dot) + for the filename. + + OUTPUT: + + The path of the temporary file created. In the notebook, this is + a filename without path in the current directory. Otherwise, this + an absolute path. + + EXAMPLES:: + + sage: from sage.misc.temporary_file import graphics_filename + sage: print graphics_filename() # random, typical filename for sagenb + sage0.png + + TESTS: + + When doctesting, this returns instead a random temporary file. + We check that it's a file inside ``SAGE_TMP`` and that the extension + is correct:: + + sage: fn = graphics_filename(ext="jpeg") + sage: fn.startswith(str(SAGE_TMP)) + True + sage: fn.endswith('.jpeg') + True """ - i = 0 - while os.path.exists('sage%d.%s'%(i,ext)): - i += 1 - filename = 'sage%d.%s'%(i,ext) - return filename + ext = '.' + ext + # Don't use this unsafe function except in the notebook, #15515 + import sage.plot.plot + if sage.plot.plot.EMBEDDED_MODE: + i = 0 + while os.path.exists('sage%d%s'%(i,ext)): + i += 1 + filename = 'sage%d%s'%(i,ext) + return filename + else: + return tmp_filename(ext=ext) + ################################################################# # write to a temporary file and move it in place diff --git a/src/sage/plot/graphics.py b/src/sage/plot/graphics.py index 1e07333537e..169e194c110 100644 --- a/src/sage/plot/graphics.py +++ b/src/sage/plot/graphics.py @@ -35,7 +35,6 @@ ALLOWED_EXTENSIONS = ['.eps', '.pdf', '.png', '.ps', '.sobj', '.svg'] DEFAULT_DPI = 100 -DOCTEST_MODE_FILE = os.path.join(sage.misc.misc.SAGE_TMP, 'test.png') def show_default(default=None): r""" @@ -1244,7 +1243,7 @@ def _set_scale(self, figure, scale=None, base=None): labelspacing=0.02, loc='best', markerscale=0.6, ncol=1, numpoints=2, shadow=False, title=None) - def show(self, **kwds): + def show(self, filename=None, linkmode=False, **kwds): r""" Show this graphics image with the default image viewer. @@ -1813,24 +1812,20 @@ def show(self, **kwds): ValueError: 'title_pos' must be a list or tuple of two real numbers. """ - # This option should not be passed on to save(). - linkmode = kwds.pop('linkmode', False) + if filename is None: + filename = graphics_filename() - if sage.doctest.DOCTEST_MODE: - kwds.pop('filename', None) - self.save(DOCTEST_MODE_FILE, **kwds) - elif sage.plot.plot.EMBEDDED_MODE: - kwds.setdefault('filename', graphics_filename()) - self.save(**kwds) - if linkmode == True: - return "" % kwds['filename'] + self.save(filename, **kwds) + + if sage.plot.plot.EMBEDDED_MODE: + if linkmode: + return "" % filename else: - html("" % kwds['filename']) - else: - kwds.setdefault('filename', tmp_filename(ext='.png')) - self.save(**kwds) + html("" % filename) + return + if not sage.doctest.DOCTEST_MODE: os.system('%s %s 2>/dev/null 1>/dev/null &' - % (sage.misc.viewer.png_viewer(), kwds['filename'])) + % (sage.misc.viewer.png_viewer(), filename)) def xmin(self, xmin=None): """ @@ -2878,9 +2873,12 @@ def save(self, filename=None, **kwds): fig_tight = options.pop('fig_tight') if filename is None: - filename = options.pop('filename') - if filename is None: - filename = graphics_filename() + try: + filename = options.pop('filename') + except KeyError: + # Put this in except (not in pop()) such that the file is + # only created when needed. + filename = graphics_filename() ext = os.path.splitext(filename)[1].lower() if ext not in ALLOWED_EXTENSIONS: @@ -3222,20 +3220,40 @@ def append(self, g): raise NotImplementedError('Appending to a graphics array is not yet implemented') - def _render(self, filename, dpi=None, figsize=None, axes=None, **args): + def save(self, filename=None, dpi=DEFAULT_DPI, figsize=None, **kwds): r""" - ``_render`` loops over all graphics objects in the array - and adds them to the subplot. This is only used internally - when the plot is actually saved or shown. + Save the ``graphics_array`` to a png called ``filename``. + + We loop over all graphics objects in the array and add them to + a subplot and then render that. + + INPUT: + + - ``filename`` - (default: None) string + + - ``dpi`` - dots per inch + + - ``figsize`` - width or [width, height] + + - ``axes`` - (default: True) EXAMPLES:: - sage: graphics_array([[plot(sin), plot(cos)], [plot(tan), plot(sec)]]) + sage: F = tmp_filename(ext='.png') + sage: L = [plot(sin(k*x),(x,-pi,pi)) for k in [1..3]] + sage: G = graphics_array(L) + sage: G.save(F, dpi=500, axes=False) # long time (6s on sage.math, 2012) TESTS:: - sage: graphics_array([]) + sage: graphics_array([]).save() + sage: graphics_array([[]]).save() """ + if figsize is not None: + self._set_figsize_(figsize) + if filename is None: + filename = graphics_filename() + #glist is a list of Graphics objects: glist = self._glist rows = self._rows @@ -3246,15 +3264,15 @@ def _render(self, filename, dpi=None, figsize=None, axes=None, **args): rows = cols = dims = 1 #make a blank matplotlib Figure: from matplotlib.figure import Figure - figure = Figure(figsize) + figure = Figure(self._figsize) global do_verify do_verify = True for i,g in zip(range(1, dims+1), glist): subplot = figure.add_subplot(rows, cols, i) g.matplotlib(filename, figure=figure, sub=subplot, - verify=do_verify, axes = axes, **args) + verify=do_verify, **kwds) g.save(filename, dpi=dpi, figure=figure, sub=subplot, - verify=do_verify, axes = axes, **args) + verify=do_verify, **kwds) def save_image(self, filename=None, *args, **kwds): r""" @@ -3278,34 +3296,8 @@ def save_image(self, filename=None, *args, **kwds): """ self.save(filename, *args, **kwds) - def save(self, filename=None, dpi=DEFAULT_DPI, figsize=None, - axes = None, **args): - """ - Save the ``graphics_array`` to (for now) a png called - 'filename'. - - OPTIONAL INPUT: - - - ``filename`` - (default: None) string - - - ``dpi`` - dots per inch - - - ``figsize`` - width or [width, height] - - - ``axes`` - (default: True) - - EXAMPLES:: - - sage: F = tmp_filename(ext='.png') - sage: L = [plot(sin(k*x),(x,-pi,pi)) for k in [1..3]] - sage: G = graphics_array(L) - sage: G.save(F,500,axes=False) # long time (6s on sage.math, 2012) - """ - if (figsize is not None): self._set_figsize_(figsize) - self._render(filename, dpi=dpi, figsize=self._figsize, axes = axes, **args) - def show(self, filename=None, dpi=DEFAULT_DPI, figsize=None, - axes = None, **args): + def show(self, filename=None, **kwds): r""" Show this graphics array using the default viewer. @@ -3324,26 +3316,17 @@ def show(self, filename=None, dpi=DEFAULT_DPI, figsize=None, - ``frame`` - (default: False) draw a frame around the image - EXAMPLES: This draws a graphics array with four trig plots and no - axes in any of the plots. + EXAMPLES: - :: + This draws a graphics array with four trig plots and no + axes in any of the plots:: sage: G = graphics_array([[plot(sin), plot(cos)], [plot(tan), plot(sec)]]) sage: G.show(axes=False) """ - if (figsize is not None): self._set_figsize_(figsize) - if sage.doctest.DOCTEST_MODE: - self.save(DOCTEST_MODE_FILE, - dpi=dpi, figsize=self._figsize, axes = axes, **args) - return - if sage.plot.plot.EMBEDDED_MODE: - self.save(filename, dpi=dpi, figsize=self._figsize, axes = axes, **args) - return if filename is None: - filename = tmp_filename(ext='.png') - self._render(filename, dpi=dpi, figsize=self._figsize, axes = axes, **args) - os.system('%s %s 2>/dev/null 1>/dev/null &'%( + filename = graphics_filename() + self.save(filename, **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)) - - diff --git a/src/sage/plot/plot3d/tachyon.py b/src/sage/plot/plot3d/tachyon.py index 82f9fcdb17f..7c47b39a925 100644 --- a/src/sage/plot/plot3d/tachyon.py +++ b/src/sage/plot/plot3d/tachyon.py @@ -344,20 +344,15 @@ def show(self, verbose=0, extra_opts=''): sage: q.light((-1,-1,10), 1,(1,1,1)) sage: q.texture('s') sage: q.sphere((0,0,0),1,'s') - sage: q.show(verbose = False) + sage: q.show(verbose=False) """ - import sage.plot.plot - if sage.doctest.DOCTEST_MODE: - filename = graphics_filename() - self.save(os.path.join(SAGE_TMP, 'test.png'), verbose=verbose, extra_opts=extra_opts) - return - if sage.plot.plot.EMBEDDED_MODE: - filename = graphics_filename() - self.save(filename, verbose=verbose, extra_opts=extra_opts) - return - filename = tmp_filename(ext='.png') + filename = graphics_filename() self.save(filename, verbose=verbose, extra_opts=extra_opts) - os.system('%s %s 2>/dev/null 1>/dev/null &'%(sage.misc.viewer.png_viewer(), filename)) + + from sage.doctest import DOCTEST_MODE + from sage.plot.plot import EMBEDDED_MODE + if not DOCTEST_MODE and not EMBEDDED_MODE: + os.system('%s %s 2>/dev/null 1>/dev/null &'%(sage.misc.viewer.png_viewer(), filename)) def _res(self): r"""