new version

63 views
Skip to first unread message

William Stein

unread,
Sep 19, 2013, 2:15:25 AM9/19/13
to sage-...@googlegroups.com
Dear Sagemath Cloud Users,

I've updated the site with the following changes.

- Fixed some bugs with password reset, especially with Safari
(reported by Nathan Carter and others)

- PARI/GP syntax highlighting mode -- this should work automatically
when you edit .gp scripts,
and when you make a %gp cell in a worksheet (inspired by a Stack
Overflow question from Kate Stange).
(requires browser refresh)

- (requires project server restart) New worksheet function:
salvus.link! You can now do

salvus.link("path/to/directory") or salvus.link("path/to/foo.bar")

and you'll get a link to that thing. There are some options,
including customizing
the CSS classes (to get a button) -- type salvus.link? [return] for help.
This is an *incredibly* useful new feature, since you can make a
file such as index.sagews
in the top of your project, and put shortcuts in there to your
favorite files and directories,
to make them easy to open later.

- (requires project server restart) New plotting functionality. You
can now make it so when
you click on a point in a plot, then a Python function is called.
Here's a complete interact
that illustrates using this new feature:

@interact
def f0(fun=x*sin(x), mousemove='', click=''):
g = plot(fun, (0,5))
def h(p):
f0.mousemove = p
def c(p):
print "click"
f0.click = p
show(g, events={'click':c, 'mousemove':h}, gridlines=True)

Basically, I've extended show with an events option, which a
dictionary with keys
the names of Javascript events, and values functions that take
input a point (x,y).
It's a very simple API, but also easy to use/remember. I think it
should also get
implemented in the sage cell server.

NOTE: I have only implemented two events so far 'click' and
'mousemove' -- no other
ones are implemented! Also, you can only use this with Sage 2d
plots right now,
not matplotlib plots, though that will be very easy to add.

-- William

(Most of the above features were inspired by some features my wife
needs for her thesis work...)

--
William Stein
Professor of Mathematics
University of Washington
http://wstein.org

Jason Grout

unread,
Sep 19, 2013, 7:59:34 AM9/19/13
to sage-...@googlegroups.com
Very nice. We'll get on that. I notice some accuracy problems
sometimes, though. For example, in the above example, when trying to
put my cursor on the point (0,0), I get coordinates of something like
(-.07, .008). I actually have to move it fairly far to the right of
(0,0) (definitely past the tick mark) to get the coordinate to be
nonnegative. Does anyone else see that?

The same horizontal appears less at (1,0) and (2,0), and seems to
disappear around (3,0), and reverses at (4,0) (I have to go right of the
(4,0) point to get x-coordinates less than 4). I guess this points to
some issue with the horizontal scaling or pixel-to-data-coordinates
transformation.

Thanks,

Jason

William Stein

unread,
Sep 19, 2013, 10:44:22 AM9/19/13
to sage-...@googlegroups.com
I hope that means that you agree with my api choice. There are a
*lot* of possibilities -- several which I tried -- but I think the
above fits with the straightforward Sage/Python way of doing things.
You can only have one handler for each mouse event, but I think that's
ok. I can easily imagine teaching anybody who knows Sage this
plotting mouse api in like two minutes.

One thing for cloud.sagemath that took me some thought is -- where
exactly should the *output* of the event functions go? E.g, whne you
click the function c above prints "click". I decided to *render* this
output in the cell in which the show occurs -- but not to *store* it
anywhere in the worksheet. This means multiple users of a single
worksheet can click at the same time, and at least the output actions
are independent, though of course the global Python process state is
the same. Also, recording the clicks forever would be silly. You
don't have to worry about this with sage cell server.


The relevant file for you to look at is salvus/salvus/graphics.py, by
the way. There's a few innocent little lines in there involving
change of coordinates, which took me way too long to figure out.

> I notice some accuracy problems sometimes,
> though. For example, in the above example, when trying to put my cursor on
> the point (0,0), I get coordinates of something like (-.07, .008). I
> actually have to move it fairly far to the right of (0,0) (definitely past
> the tick mark) to get the coordinate to be nonnegative. Does anyone else
> see that?

Jason -- thanks for pointing this out -- this is a genuine bug; more
accurately, it was me just
not fully finishing the implementation yet. If you include the
fig_tight=False option, it should be *exactly* right. (You can also
pass svg=True to show to see svg output instead.)

@interact
def f0(fun=x*sin(x), mousemove='', click=''):
g = plot(fun, (0,5))
def h(p):
f0.mousemove = p
def c(p):
print "click"
f0.click = p
show(g, events={'click':c, 'mousemove':h}, gridlines=True, fig_tight=False)

Needless to say, I just need to check in my code what options are
passed to show and handle the fig_tight=True case properly. I'll fix
this right now (it should be easy).

---

Regarding sage-cell, should I make a script based on
$HOME/.sagemathcloud/ipython-notebook, which is instead
$HOME/.sagemathcloud/sagecell-server? And, should we have a file
format for a sage cell -- e.g., foo.sagecell -- which would store the
input to the cell, other config options, etc., -- this would be an
alternative to using html/javascript to embed a sage cell. Soon
people might start posting public sage cell servlets like this:

https://cloud.sagemath.com/grout/demos/master/foo.sagecell

For collaborator access, it's clear what the above should do. For
public access, I think I'll have to setup some seamless system whereby
one can run an LXC container inside a project, and have one spawned
for each client, with certain results saved in the project... or
something like that. I spent some time with LXC recently, and I'm
very, very impressed with all the progress that is being made on it
(thanks to the Linux devs/distros out there, to Docker, etc.).




>
> Thanks,
>
> Jason
>
> --
> You received this message because you are subscribed to the Google Groups
> "sage-cloud" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to sage-cloud+...@googlegroups.com.
> To post to this group, send email to sage-...@googlegroups.com.
> Visit this group at http://groups.google.com/group/sage-cloud.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/sage-cloud/523AE726.8070907%40creativetrax.com.
> For more options, visit https://groups.google.com/groups/opt_out.

Jason Grout

unread,
Sep 19, 2013, 11:14:52 AM9/19/13
to sage-...@googlegroups.com
On 9/19/13 9:44 AM, William Stein wrote:
> On Thu, Sep 19, 2013 at 4:59 AM, Jason Grout
> <jason...@creativetrax.com> wrote:
>> Very nice. We'll get on that.
>
> I hope that means that you agree with my api choice. There are a
> *lot* of possibilities -- several which I tried -- but I think the
> above fits with the straightforward Sage/Python way of doing things.
> You can only have one handler for each mouse event, but I think that's
> ok. I can easily imagine teaching anybody who knows Sage this
> plotting mouse api in like two minutes.
>
> One thing for cloud.sagemath that took me some thought is -- where
> exactly should the *output* of the event functions go? E.g, whne you
> click the function c above prints "click". I decided to *render* this
> output in the cell in which the show occurs -- but not to *store* it
> anywhere in the worksheet. This means multiple users of a single
> worksheet can click at the same time, and at least the output actions
> are independent, though of course the global Python process state is
> the same. Also, recording the clicks forever would be silly. You
> don't have to worry about this with sage cell server.
>
>
> The relevant file for you to look at is salvus/salvus/graphics.py, by
> the way. There's a few innocent little lines in there involving
> change of coordinates, which took me way too long to figure out.

I'll play with it a bit more and then give comments about the API. One
thing on my radar is the current work being done in matplotlib and
IPython to have interactive 2d graphics, and I'd like to make sure that
the API at least takes those advancements in consideration.

We are hampered a lot by not being able to modify a matplotlib graphic
over the web in real-time (e.g., adding data and having the plot update,
rather than having to generate a whole new image). That's one of the
things the matplotlib/IPython community is addressing over the next
several months.

Sorry---if I had realized you were doing this, I would have pointed you
to the transformations documentation. A long time ago you mentioned
this idea of using image clicks to trigger handlers, and I thought I
mentioned using the matplotlib transformation framework to get the data
coordinates from image coordinates. But that was a few years ago.
Because the sage cell relies on patches to Sage, it will be a little
harder than the ipython-notebook. Right now I maintain those patches on
a git branch of Sage. I'll make getting those patches into Sage one of
the things to do next.

Thanks,

Jason

William Stein

unread,
Sep 19, 2013, 11:31:05 AM9/19/13
to sage-...@googlegroups.com
On Thu, Sep 19, 2013 at 8:14 AM, Jason Grout
Thanks -- since I know absolutely nothing about that.

> We are hampered a lot by not being able to modify a matplotlib graphic over
> the web in real-time (e.g., adding data and having the plot update, rather
> than having to generate a whole new image). That's one of the things the
> matplotlib/IPython community is addressing over the next several months.

That's a different problem, indeed. The 3d analogue of this (with
threejs), which I'm thinking about right now, is fortunately going to
be a lot easier to do right, since the renderer itself has a
javascript API for dynamically modifying anything about the scene.

I don't know what the matplotlib/IPython people are doing these days,
but I remember giving a lightning talk at EuroScipy 2009 (?) of a
web-based backend for matplotlib, which is probably what they are
developing (surely it is done by now?).

I think the most straightforward solution for Sage plots to this
problem would be (1) define a JSON export format for Sage plots
independent of matplotlib, and (2) write something using
http://svgjs.com/ (or raphael?) to render them, which has an API for
modifying the 2d scene. If g is a 2d graphics object, then Robert
Bradshaw wrote a function g.plot3d(), which is basically how to start
doing (1). I think doing this would take about a week's work, since
you have to figure out how to render each Graphics thing using svg.js,
which is just a bunch of little problems to solve. Note that this
approach is not solving the matplotlib/IPython problem at all, since
it's not providing a new web-based backend for matplotlib figures --
it's a totally different thing. But I think it will work very well,
as one can see by just implementing a few basic primitives.

> Sorry---if I had realized you were doing this, I would have pointed you to
> the transformations documentation.

Fortunately, it only took a few minutes to find, since the matplotlib
documentation is well organized.
What took me a long time was realizing that if G is a Sage graphics
object, then the matplotlib figure output by:

G.matplotlib()

is *NOT* the figure that actually gets plotted, so I was really
confused about how the transformations were all just broken. The
figure that gets plotted is the result of setting
a backend, then applying various transformations and crops to the
above figure.
I wonder if Sage's function "G.matplotlib()" should be
deprecated/fixed? It could be called

G.matplotlib_figure(**args)

and take exactly the same options as show/save, with the same
defaults. That's fully what
I expected. Anyway, just a thought -- I'm not going to change
anything about that myself.

> A long time ago you mentioned this idea
> of using image clicks to trigger handlers, and I thought I mentioned using
> the matplotlib transformation framework to get the data coordinates from
> image coordinates. But that was a few years ago.

Thanks!
Cool. So far, no cloud.sagemath stuff relies on patches to Sage...
except for ipython-notebook, which relies on upgrading to ipython
1.0.0, and applying your patches to make that work.

I can patch the systemwide Sage with your sage cell patches, though.

>
>
> Thanks,
>
> Jason
>
> --
> You received this message because you are subscribed to the Google Groups
> "sage-cloud" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to sage-cloud+...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/sage-cloud/523B14EC.3090403%40creativetrax.com.

William Stein

unread,
Sep 19, 2013, 3:43:09 PM9/19/13
to sage-...@googlegroups.com
Hi,

I made some updates to interact and plot event detection, based on
feedback here. To see any of these changes, you have to restart your
project and refresh your browser (otherwise, just ignore this):

* Make show(matplotlib figure) work and fig.show() and just fig --
reported recently by Harald Schilly (I had only implemented some
special cases of this sort of thing -- there are a million ways to
show matplotlib stuff...)

* make image click events still work with custom options (e.g., ymin/ymax)

* make click event stuff work with matplotlib figures too

* new command salvus.clear() that clear the output of a cell
(needed for interacts with graphics)

* changed semantics of calling interact functions so now massively
more useful -- Jason, did I get this right?-- you kept requesting
this, and I think I did it all wrong before today

Here an example involving a clickable plot, which draws a dot and tangent line:

@interact
def f0(fun=x*sin(x^2), mousemove='', click='(0,0)'):
click = sage_eval(click)
g = plot(fun, (x,0,5), zorder=0) + point(click, color='red',
pointsize=100, zorder=10)
ymax = g.ymax(); ymin = g.ymin()
m = fun.derivative(x)(x=click[0])
b = fun(x=click[0]) - m*click[0]
g += plot(m*x + b, (click[0]-1,click[0]+1), color='red', zorder=10)
def h(p):
f0.mousemove = p
def c(p):
f0(click=p)
show(g, events={'click':c, 'mousemove':h}, svg=True,
gridlines='major', ymin=ymin, ymax=ymax)
event.png

Harald Schilly

unread,
Sep 19, 2013, 4:44:04 PM9/19/13
to sage-...@googlegroups.com

On Thu, Sep 19, 2013 at 9:43 PM, William Stein <wst...@gmail.com> wrote:
   * new command salvus.clear() that clear the output of a cell
(needed for interacts with graphics)


That was also on the list of my requests ;)

To add this to a library in a general way, my only questions are:

* How can someone determine, if it is running on SMC? IPython seems to define a "__IPYTHON__" variable. Just testing if "savlus" exists is not so elegant …

* Is the "saluvs" module name stable, or will you at some point in time change it?

H

William Stein

unread,
Sep 19, 2013, 4:55:29 PM9/19/13
to sage-...@googlegroups.com
On Thu, Sep 19, 2013 at 1:44 PM, Harald Schilly
<harald....@gmail.com> wrote:
>
> On Thu, Sep 19, 2013 at 9:43 PM, William Stein <wst...@gmail.com> wrote:
>>
>> * new command salvus.clear() that clear the output of a cell
>> (needed for interacts with graphics)
>
>
>
> That was also on the list of my requests ;)
>
> To add this to a library in a general way, my only questions are:
>
> * How can someone determine, if it is running on SMC? IPython seems to
> define a "__IPYTHON__" variable. Just testing if "savlus" exists is not so
> elegant …

Should I define __SMC__ ?

> * Is the "saluvs" module name stable, or will you at some point in time
> change it?

It's actually not a module -- it's an instance of a class. Each time
you run code in a cell
a new instance is created that has specialized info for that cell.

But yes, the name salvus is stable. I don't plan on calling
"cloud.sagemath.com" salvus anymore, but
it is used all over the place internally, e.g, to prefix css classes, etc.:

~/salvus/salvus$ grep salvus *.coffee *.py page/*.coffee |wc -l
905

William

>
> H
>
> --
> You received this message because you are subscribed to the Google Groups
> "sage-cloud" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to sage-cloud+...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/sage-cloud/CAGG4CB5P8idJnecvLxfXydHR%3DVAAapmeakswtX2C2%3D4%2BRHOVSA%40mail.gmail.com.
>
> For more options, visit https://groups.google.com/groups/opt_out.



Robert Beezer

unread,
Sep 20, 2013, 12:31:23 AM9/20/13
to sage-...@googlegroups.com
On Wednesday, September 18, 2013 11:15:25 PM UTC-7, William Stein wrote:
  - (requires project server restart) New worksheet function:
salvus.link!  You can now do

        salvus.link("path/to/directory")   or  salvus.link("path/to/foo.bar")

    and you'll get a link to that thing.

Very good!

Can I get this functionality in a pure-HTML cell (ie one begun with %html)?  In other words, if I am writing whole paragraphs of stuff in HTML and want to have a link in mid-sentence to another worksheet (or target within some other worksheet), can this be made to do that?   Would reverse-engineering what this command injects (visible in output cell in split view) be a way to get the functionality in mid-HTML?  (I'm not writing by hand, I can automate producing any amount of code needed to get the job done, but so far I have not been writing out code for the output portion of the cell, and maybe that is not even practical.)

Thanks,
Rob

William Stein

unread,
Sep 20, 2013, 12:37:39 AM9/20/13
to sage-...@googlegroups.com
Not yet -- however, I'm going to have a (by default) post-processing
phase for all html output that automatically makes all local relative
links be processed in the same way as salvus.link uses... so you'll
just do the normal <a href=...> business. This will just be another
phase, like the mathjax application. Similar remarks for markdown...


>
> Thanks,
> Rob
>
> --
> You received this message because you are subscribed to the Google Groups
> "sage-cloud" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to sage-cloud+...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/sage-cloud/5bfdf62e-b868-486a-967a-092424294b59%40googlegroups.com.
>
> For more options, visit https://groups.google.com/groups/opt_out.



William Stein

unread,
Sep 20, 2013, 1:07:12 AM9/20/13
to sage-...@googlegroups.com
On Thu, Sep 19, 2013 at 1:55 PM, William Stein <wst...@gmail.com> wrote:
> On Thu, Sep 19, 2013 at 1:44 PM, Harald Schilly
> <harald....@gmail.com> wrote:
>>
>> On Thu, Sep 19, 2013 at 9:43 PM, William Stein <wst...@gmail.com> wrote:
>>>
>>> * new command salvus.clear() that clear the output of a cell
>>> (needed for interacts with graphics)
>>
>>
>>
>> That was also on the list of my requests ;)
>>
>> To add this to a library in a general way, my only questions are:
>>
>> * How can someone determine, if it is running on SMC? IPython seems to
>> define a "__IPYTHON__" variable. Just testing if "savlus" exists is not so
>> elegant …
>
> Should I define __SMC__ ?

I've just added

__SAGEWS__

instead of __SMC__. The reason being that code could run in
SagemathCloud (SMC), but not be running in a sagews file. For
example, code might run in the command line terminal, an ipython
notebook, a .sage file you're editing (yes, there is secretely
functionality for having sage sessions attached to Codemirror
editors...), etc. This will get pushed out in the next day.

William

Rob Beezer

unread,
Sep 20, 2013, 1:25:02 AM9/20/13
to sage-...@googlegroups.com
On 09/19/2013 09:37 PM, William Stein wrote:
> links be processed in the same way as salvus.link uses... so you'll
> just do the normal <a href=...> business. This will just be another
> phase, like the mathjax application. Similar remarks for markdown...

Sounds excellent. I'll sit tight. ;-)

Thanks for the forward-looking statements.
Reply all
Reply to author
Forward
0 new messages