using Matplotlib and sagetex

83 views
Skip to first unread message

Adam Webb

unread,
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,
Adam

Constantin

unread,
Nov 17, 2010, 6:39:26 PM11/17/10
to sage-s...@googlegroups.com


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

unread,
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

unread,
Nov 18, 2010, 9:59:47 PM11/18/10
to sage-s...@googlegroups.com
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

unread,
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

unread,
Nov 19, 2010, 1:09:02 AM11/19/10
to sage-s...@googlegroups.com
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
Reply all
Reply to author
Forward
0 new messages