Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Building on Jason's idea, I made an interactive graph that does not contact the sage server, using javascript to change the frames. On my computer it does not lag at all. I find it so useful that I'm thinking of making a feature request for something with similar functionality. What do you think?

def jslider(f,start,end,num_steps):

    # Draw a tile for the slider
    import Image, ImageDraw
    img=Image.new("RGB",(3,20))
    draw = ImageDraw.Draw(img)
    draw.line(((2,0),(2,19)),(255,255,255))
    img.save("data/jslider_tile.png", "PNG")

    step_size=(end-start)/num_steps

    for i in range(num_steps+1):
        f(start+i*step_size).save(DATA+'jslider_%d.png'%i)

    html("""
        <script>
        function jslider_switch(n)
        {
              document.getElementsByClassName('jslider_image')[0].src='data/jslider_'+n+'.png';
        }
        </script>
        """)

    def tile_html(n): #Returns the html code for the (n)th tile of the slider
        return '<img src="data/jslider_tile.png" onMouseover="jslider_switch(%d)">'%n

    slider_html=""
    for i in range(num_steps+1):
        slider_html=slider_html+tile_html(i)

    html(slider_html)
    html('<img src="data/jslider_0.png" class="jslider_image">')

jslider(lambda a:plot(lambda x:sin(a*x),xmin=0,xmax=pi,ymin=-1,ymax=1),0,5,50) # This can take a minute or two.

If you use a remote notebook, transferring the images will introduce significant lag. To avoid it, after running jslider run the following function. It will load all of the images once, so they will hopefully get stored in the browser's cache.

def load_images(num_steps):
    def frame_html(n):
        return '<img src="data/jslider_%d.png">'%n
    cmd=""
    for i in range(num_steps+1):
        cmd=cmd+frame_html(i)
    html(cmd)

load_images(51)

Sometimes you may need to refresh the notebook (the browser's reload/refresh button) for the html/javascript to work properly. I don't yet know when or why. Also, do not run jslider in more than one cell - only the first cell's image will be interactive. And be aware that the code above saves .png files in the worksheet's data directory and does not clean them up.

Building on Jason's idea, I made an interactive graph that does not contact the sage server, using javascript to change the frames. On my computer it does not lag at all. I find it so useful that I'm thinking of making a feature request for something with similar functionality. What do you think?

def jslider(f,start,end,num_steps):

    # Draw a tile for the slider
    import Image, ImageDraw
    img=Image.new("RGB",(3,20))
    draw = ImageDraw.Draw(img)
    draw.line(((2,0),(2,19)),(255,255,255))
    img.save("data/jslider_tile.png", "PNG")

    step_size=(end-start)/num_steps

    for i in range(num_steps+1):
        f(start+i*step_size).save(DATA+'jslider_%d.png'%i)

    html("""
        <script>
        function jslider_switch(n)
        {
              document.getElementsByClassName('jslider_image')[0].src='data/jslider_'+n+'.png';
        }
        </script>
        """)

    def tile_html(n): #Returns the html code for the (n)th tile of the slider
        return '<img src="data/jslider_tile.png" onMouseover="jslider_switch(%d)">'%n

    slider_html=""
    for i in range(num_steps+1):
        slider_html=slider_html+tile_html(i)

    html(slider_html)
    html('<img src="data/jslider_0.png" class="jslider_image">')

jslider(lambda a:plot(lambda x:sin(a*x),xmin=0,xmax=pi,ymin=-1,ymax=1),0,5,50) # This can take a minute or two.

If you use a remote notebook, transferring the images will introduce significant lag. To avoid it, after running jslider run the following function. It will load all of the images once, so they will hopefully get stored in the browser's cache.

def load_images(num_steps):
    def frame_html(n):
        return '<img src="data/jslider_%d.png">'%n
    cmd=""
    for i in range(num_steps+1):
        cmd=cmd+frame_html(i)
    html(cmd)

load_images(51)
load_images(50)

Sometimes you may need to refresh the notebook (the browser's reload/refresh button) for the html/javascript to work properly. I don't yet know when or why. Also, do not run jslider in more than one cell - only the first cell's image will be interactive. And be aware that the code above saves .png files in the worksheet's data directory and does not clean them up.

Building on Jason's idea, I made an interactive graph that does not contact the sage server, using javascript to change the frames. On my computer it does not lag at all. I find it so useful that I'm thinking of making a feature request for something with similar functionality. What do you think?

def jslider(f,start,end,num_steps):

    # Draw a tile for the slider
    import Image, ImageDraw
    img=Image.new("RGB",(3,20))
    draw = ImageDraw.Draw(img)
    draw.line(((2,0),(2,19)),(255,255,255))
    img.save("data/jslider_tile.png", "PNG")

    step_size=(end-start)/num_steps

    for i in range(num_steps+1):
        f(start+i*step_size).save(DATA+'jslider_%d.png'%i)

    html("""
        <script>
        function jslider_switch(n)
        {
              document.getElementsByClassName('jslider_image')[0].src='data/jslider_'+n+'.png';
        }
        </script>
        """)

    def tile_html(n): #Returns the html code for the (n)th tile of the slider
        return '<img src="data/jslider_tile.png" onMouseover="jslider_switch(%d)">'%n

    slider_html=""
    for i in range(num_steps+1):
        slider_html=slider_html+tile_html(i)

    html(slider_html)
    html('<img src="data/jslider_0.png" class="jslider_image">')

jslider(lambda a:plot(lambda x:sin(a*x),xmin=0,xmax=pi,ymin=-1,ymax=1),0,5,50) # This can take a minute or two.

Now refresh the notebook (the browser's reload/refresh button) for the html/javascript to work properly.

If you use a remote notebook, transferring the images will introduce significant lag. To avoid it, after running jslider run the following function. It will load all of the images once, so they will hopefully get stored in the browser's cache.

def load_images(num_steps):
    def frame_html(n):
        return '<img src="data/jslider_%d.png">'%n
    cmd=""
    for i in range(num_steps+1):
        cmd=cmd+frame_html(i)
    html(cmd)

load_images(50)

Sometimes you may need to refresh the notebook (the browser's reload/refresh button) for the html/javascript to work properly. I don't yet know when or why. Also, do Do not run jslider in more than one cell - only the first cell's image will be interactive. And be aware that the code above saves .png files in the worksheet's data directory and does not clean them up.

Building on Jason's idea, I made an interactive graph that does not contact the sage server, using javascript to change the frames. On my computer it does not lag at all. I find it so useful that I'm thinking of making a feature request for something with similar functionality. What do you think?

EDIT: The code below in a published worksheet: http://nt.sagenb.org/home/pub/36/

def jslider(f,start,end,num_steps):

    # Draw a tile for the slider
    import Image, ImageDraw
    img=Image.new("RGB",(3,20))
    draw = ImageDraw.Draw(img)
    draw.line(((2,0),(2,19)),(255,255,255))
    img.save("data/jslider_tile.png", "PNG")

    step_size=(end-start)/num_steps

    for i in range(num_steps+1):
        f(start+i*step_size).save(DATA+'jslider_%d.png'%i)

    html("""
        <script>
        function jslider_switch(n)
        {
              document.getElementsByClassName('jslider_image')[0].src='data/jslider_'+n+'.png';
        }
        </script>
        """)

    def tile_html(n): #Returns the html code for the (n)th tile of the slider
        return '<img src="data/jslider_tile.png" onMouseover="jslider_switch(%d)">'%n

    slider_html=""
    for i in range(num_steps+1):
        slider_html=slider_html+tile_html(i)

    html(slider_html)
    html('<img src="data/jslider_0.png" class="jslider_image">')

jslider(lambda a:plot(lambda x:sin(a*x),xmin=0,xmax=pi,ymin=-1,ymax=1),0,5,50) # This can take a minute or two.

Now refresh the notebook (the browser's reload/refresh button) for the html/javascript to work properly.

If you use a remote notebook, transferring the images will introduce significant lag. To avoid it, after running jslider run the following function. It will load all of the images once, so they will hopefully get stored in the browser's cache.

def load_images(num_steps):
    def frame_html(n):
        return '<img src="data/jslider_%d.png">'%n
    cmd=""
    for i in range(num_steps+1):
        cmd=cmd+frame_html(i)
    html(cmd)

load_images(50)

Do not run jslider in more than one cell - only the first cell's image will be interactive. And be aware that the code above saves .png files in the worksheet's data directory and does not clean them up.