Sage / SageMath Wrapper: Graphing with x-y values in a table

Below is some, as yet unrefactored, wrapper code that I wrote to generate plots, that are aware of asymptotes, using Sage that include corresponding x and y values in the form a table. Below is an image (here a polynomial function) and then the code.
# handle division by zero
def catch(func, handle=lambda e : e, *args, **kwargs):
        return func(*args, **kwargs)
    except Exception as e:
        #return handle(e)
        return NaN

# graphic, table, labeled points, point of interest               
def go(fx=0, gx=0, xmin=-3, xmax=3, ymin=None, ymax=None, step=1, x1=None, label=True, simple=False, rotation=0):
    """Show a graph, table of values, and points of interest """
    import numpy as np # for arange

    x = var('x'); fn = 'plot' + str(int(random()*10000)) + '.png'
    f(x) = fx
    g(x) = gx
    if simple == True:
        s = abs(xmin/ceil(step))
        s = step
    # data
    fv = [(i, catch(lambda: f(i).n())) for i in np.arange(xmin,xmax,s)] # include xmax
    gv = [(i, catch(lambda: g(i).n())) for i in np.arange(xmin,xmax,s)] # include xmax
    # plot with points
    G = plot(f(x),(x,xmin,xmax), ymin=ymin, ymax=ymax, detect_poles='show', color='green');
    G += plot(g(x),(x,xmin,xmax),ymin=ymin, ymax=ymax, detect_poles='show', color='red');
    G += points(fv+gv,pointsize=40,color='black');
    for p in fv+gv:  # label points
        if label:
            if math.isnan(p[1])==False: # don't plot NaNs
                G += text(' (%.1f,%.1f)'%(p[0],p[1]),p,horizontal_alignment='left',rotation=rotation,color='black',fontsize=10, fontweight='normal')
        if math.isnan(p[1]): # plot NaNs
            G += text(' (%.1f,Div0)'%q[0],q,horizontal_alignment='left',rotation=rotation,color='black',fontsize=10, fontweight='normal')
            G += points(q,pointsize=40,color='blue');
    # horizontal asymptotes
    a1 = limit(f,x=+infinity)
    a2 = limit(f,x=-infinity)
    G += line([(-100,a1),(100,a2)], xmin=xmin,xmax=xmax,ymin=ymin, ymax=ymax, color='gray', linestyle='dashed')
    if x1:
        p1 = (x1, catch(lambda: f(x1))) # point of interest
        G += points(p1,pointsize=40,color='blue')
        G += text(' (%.1f,%.1f)'%(p1[0],p1[1]),p1,horizontal_alignment='left',rotation=rotation,color='blue',fontsize=10, fontweight='bold')
        p1 = (None, None)
    + fn) # required due to Sage object caching
    html('<div style="float:left;">')
    html("<img src="+fn+"></img>")
    html('</div><div style="float:left; padding-left:50px;">Green Graph')
    html.table([["$x$", f]] + fv, header = True)
    html('</div><div style="float:left; padding-left:50px;">Red Graph')
    html.table([["$x$", g]] + gv, header = True)
    html('</div><div style="float:left; padding-left:50px;">Interesting Points')
    html.table([["$x$", "$y$"]] + [p1], header = True)
    html('</div>') # html
    import time; time.sleep(1); os.remove(DATA + fn) # cleanup

Example of how to use it

NOTE: The 4 comma-separated numbers following f(x), g(x) are the minimum x and y values.


Add new comment

Filtered HTML

  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.

Plain text

  • No HTML tags allowed.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Lines and paragraphs break automatically.