# using Matplotlib and sagetex

83 views

Dec 1, 2008, 6:29:00 AM12/1/08
to sage-support
Hi,

I would like to add plots to a document using sagetex and my script
uses matplotlib to generate the plot. Is it possible to matplotlib
with sagetex? I understand that /sageplot{} wants a <graphics obj>
with a .save method. However, I have not found how to generate such an
object.

For example if I use the simple example:
sage: from pylab import *
sage: t = arange(0.0, 2.0, 0.01)
sage: s = sin(2*pi*t)
sage: P = plot(t, s, linewidth=1.0)
sage: xl = xlabel('time (s)')
sage: yl = ylabel('voltage (mV)')
sage: t = title('About as simple as it gets, folks')
sage: grid(True)
sage: savefig('sage.png')

Where is the <graphics obj>?

cheers,

### Constantin

Nov 17, 2010, 6:39:26 PM11/17/10

Hi,
i know that it's been a while since this question was asked, but since i
struggled with it a bit (and to have a reference for later), here's the
workaround i've come up with:

1. (assuming that this is the file that produces the Matplotlib figure, eg.
$HOME/sagetexInclude.py): def f(): from numpy import arange from matplotlib.pyplot import plot plot(range(10), arange(1.5, 2.5, .1)) 2. tweek the file$SAGE_ROOT/local/bin/sage-env (so that is uses PYTHONPATH)*:
" ...
PYTHONPATH="$SAGE_PATH:$SAGE_ROOT/local/lib/python:$PYTHONPATH" && export PYTHONPATH ... " [*Note: now i see that probably setting SAGE_PATH to the appropriate value would suffice] 3. in the .tex file do something like: \begin{sagesilent} import sagetexInclude as sti import matplotlib.pyplot as plt f = plt.figure() # so that we get a separate image for the plot sti.f() # here we do the PLOTting plt.save = plt.savefig # SageTeX's plotting apparently relies on *this*! \end{sagesilent} \begin{center} \sageplot{plt} \end{center} % plot as a normal Sage object % this is not really necessary, but whatever \begin{sagesilent} plt.close() \end{sagesilent} 4. generate latex and run sage on the file as usually (don't forget to set PYTHONPATH or SAGE_PATH to the directory containing sagetexInclude [i.e. export PYTHONPATH=$HOME:\$PYTHONPATH]):
pdflatex texfile.tex
sage texfile.sage
pdflatex texfile.tex

Hope this helps [someone :) ].

Best regards,
Constantin

### kcrisman

Nov 17, 2010, 9:21:55 PM11/17/10
to sage-support
Wow, what service! If Google groups were easier to use, we could
track down more such requests :)

I'd like to point out that http://trac.sagemath.org/sage_trac/ticket/5128
might also be relevant - Dan D., can you comment on whether an
eventual solution to that ticket would take care of this? (I assume,
out of ignorance, that there isn't anything else obvious one can do to
the current SageTeX package or Sage to do this directly.)

- kcrisman

### Dan Drake

Nov 18, 2010, 9:59:47 PM11/18/10
On Wed, 17 Nov 2010 at 06:21PM -0800, kcrisman wrote:
> I'd like to point out that
> http://trac.sagemath.org/sage_trac/ticket/5128 might also be relevant
> - Dan D., can you comment on whether an eventual solution to that
> ticket would take care of this? (I assume, out of ignorance, that
> there isn't anything else obvious one can do to the current SageTeX
> package or Sage to do this directly.)

You're correct that there's nothing *obvious* one can do. But I think
there's something non-obvious...

When you do \sageplot{p} in SageTeX, it doesn't require much of the
object p'. It basically needs to be able to do

p.save('path/foo.png')

and get a PNG file saved properly. It's very useful for 'foo.eps' and
'foo.pdf' to also work.

So, you don't really need a Sage Graphics() object; you just need
something that has an appropriate save() method. So it's possible that
something like this would work:

class GoodEnoughGraphics():

def __init__(self, obj):
self.obj = obj

def save(filename):
if filename.endswith('png'):
# do whatever you need to do to save a PNG to filename'
if filename.endswith('eps'):
# do whatever you need to do to save an EPS to `filename'
# etc

So, if you're working with pure matplotlib graphics, you would write the
above class putting whatever specific code you need in .save(), and then
do something like \sageplot{GoodEnoughGraphics(p)}. This approach should
work for any kind of graphics whatsoever; if you can somehow save them
to the right kind of file, then you can write the above wrapper.

I see that the OP effectively did this; see above where he did "plt.save
= plt.savefig", which gives his object the .save() method that SageTeX
wants.

As a disclaimer: I haven't tested any of this, or even looked at the
SageTeX code to make sure it would work. So caveat emptor. :) Let me
know if this works!

Dan

--
--- Dan Drake
----- http://mathsci.kaist.ac.kr/~drake
-------

signature.asc

### kcrisman

Nov 18, 2010, 10:55:22 PM11/18/10
to sage-support

On Nov 18, 9:59 pm, Dan Drake <dr...@kaist.edu> wrote:
> On Wed, 17 Nov 2010 at 06:21PM -0800, kcrisman wrote:
> > I'd like to point out that
> >http://trac.sagemath.org/sage_trac/ticket/5128might also be relevant
> > - Dan D., can you comment on whether an eventual solution to that
> > ticket would take care of this? (I assume, out of ignorance, that
> > there isn't anything else obvious one can do to the current SageTeX
> > package or Sage to do this directly.)
>
> You're correct that there's nothing *obvious* one can do. But I think
> there's something non-obvious...
>

> I see that the OP effectively did this; see above where he did "plt.save
> = plt.savefig", which gives his object the .save() method that SageTeX
> wants.

Hmm... so what if mpl included a save, not just savefig, method?

- kcrisman

### Dan Drake

Nov 19, 2010, 1:09:02 AM11/19/10
On Thu, 18 Nov 2010 at 07:55PM -0800, kcrisman wrote:
> > I see that the OP effectively did this; see above where he did
> > "plt.save = plt.savefig", which gives his object the .save() method
> > that SageTeX wants.
>
> Hmm... so what if mpl included a save, not just savefig, method?

If mpl included a save method that had the above interface
(foo.save('/path/to/blah.png'), and so on), then I'm pretty sure it
would work in SageTeX with no modifications.

signature.asc