GSoC 2014 Application Sahil Shekhawat: Web based backend for SymPy's plotting module and 3D plotting

sahil shekhawat edited this page Mar 25, 2014 · 39 revisions

This proposal is still in progress.

CLARIFICATION The backend will not be a separate one, i am calling it the backend due to separate server and use of JS (calculations still done by Sympy). I will break mathbox.js a bit so that it will support SurfaceOver2DRangeSeries, Parametric3DLineSeries and ParametricSurfaceSeries**


Personal Details

Name: Sahil Shekhawat

University: Indraprastha Institute of Information Technology


Github: sahilshekhawat

Profile:My University webpage


Hi everyone!,I am a first year Computer Science student at Indraprastha Institute of Information Technology, Delhi, India. During my High School, I have extensively used Wolfram|Alpha and this is what excites me about SymPyGamma.The fact that,now I can develop and design it the way I always wanted the Wolfram|Alpha to work is the most Awesome part! Wolfram|Alpha's 3D plotting is not very nice, at-least not in the free version. You can use their interactivity CDF plugin for browsers only in the pro version.

Coding skills

I have done coding mainly in Python and C. I have been using Python from the past 1 year and I like Python because being a Python Programmer, I can complete a task in 2 months which takes a year in C++ or Java and its Dynamic typed nature is fantastic.

I started Web Development soon after starting Python using frameworks like Django hosted on Google App Engine in our Software Development club.Also, I started using GIT after being involved in SymPy community and now I can use it quite well and during that period I became familiar with the SymPyGamma's codebase and coding styles.

I belong to the Churches of Emacs.I started using Emacs about 6 months back firstly,It took a lot of time to understand the core and practice the keys but now it feels pretty awesome.I barely need to exit it.

I will mainly use JavaScript and Python during my project and I feel very comfortable with both, Due to my experience with Web Development.

My contributions to SymPy community

  • (Working On) Implementing issue 22 of SymPyGamma11 #32:
    Adding the feature to download and share the entire result as IPython Notebook and storing that result as GIST for future reference.currently I am writing codes to interact with REST api of GITHUB so that not only we can store the results as GIST but also query them based on their input so that we can provide faster results and also provide suggestions to users which will improve their queries and our result set.

  • (Awaiting Merge) Fixing the issue #7010 by making the count_ops() function to work with logic functions also#7303:
    Adding the Logic functions to used as operations in count_ops() attribute.

  • (Rejected) Rejected pull request of the issue #7010 #7251:
    I closed this pull due to bad code quality but i learned how to run tests before commiting and debug it.

  • (Merged) Ordering factorint factors and making the SymPyGamma's arrows clickable #33:
    fixed the Issue 30 by ordering the fatorint factors and making the arrow in examples, clickable.The issue were very simple to fix but it exposed me to the code structure of SymPy Gamma.

The Project

Project Synopsis

Plotting module in SymPy is mainly based on matplotlib whose backend is TkAGG.Though Matplotlib's hooks which are into multiple backends works well for static images, they are very cumbersome and unpredictable for more dynamic, interactive plots (for example, the animation toolkit still does not work with the MacOSX backend, and this is unlikely to improve any time soon). Also, SymPy's web-based sub-projects like Gamma and Live can not use it (They can if someone add matplotlib's support but then again interactivity issue will be there).

To resolve this issue I propose a Web based backend for SymPy which will serve interactive plots to local users (who constitute about 99% of sympy's userbase) as well as to Gamma and Live. I will write this backend in Sympy itself so that it can further be developed to support D3.js for even the static plots
Also, I will integrate Javascript libraries Mathbox.js and dat.gui in Sympy for browser based 3D plotting. As, SymPy's code will include mathbox.js, it will not be dependent on anything like matplotlib which requires matplotlib to be installed locally (obviously)

Note: Goal is not to replace matplotlib but to provide a web based more interactive rich plotting options and for that this backend will be easily extendible to D3.js by reusing the plotting codes from SymPyGamma to provide the support of D3.js to local users also.

###Why Mathbox.js? Mathbox.js is built on top of Three.js, which supports HTML5 Canvas2D and WebGL (if available),thus it is pretty fast on laptop and works on Andriod and Iphones and everything else with HTML5 canvas (All the O.S's and all the browsers, even IE7) .It also supports selecting individual objects in a 3D scene and moving them around which is useful for the interactive interface between the plot and the user. All of it will be done client side. Also, Mathbox.js already has what we need to render multivariable functions (cameras, lights, canvas etc). Thus, Instead of writing our own basic functions (cameras, lights, canvas etc) in Three.js which are do not vary much, I will use Mathbox.js. Its main attraction is Shader.js which provides much nicer animations.

##Deliverables SEE WHAT I WISH TO DO!
Mainly my project will have five main goals:

  1. Create a Python backend (a small script actually) which will interact with SymPy to create a JSON for mathbox.js
    An example of how it will be done is here by stefan though my python script will create json instead of JS, but this is my Motivation for this project.

  2. Write JS which will use the JSON to create static HTML and those static HTML can directly be used by Gamma and Live to render plots
    This will be based on JS which will use JSON to create Mathbox.js's Javascript. I will integrate dat.gui to change parameters interactively and client side due to its present integration with Three.js.

  3. Create a simple Server for local users to fetch the static files and render them in the browser
    This will not be much difficult, see PyDy-viz's server, for example.Server will not run in the case of Gamma/Live, it is only for the local users.

  4. Enable 3D plotting in SymPyGamma by using this backend
    SymPyGamma doesnot support 3D plots. This will fix that issue.

  5. To reuse D3.js codes from SymPyGamma and make it available for local user
    Gamma doesnot use plotting module, neither the evalf nor lambdify to plot but still is able to plot basic functions. I want to add this support of Gamma into Sympy itself for local users. Though it is just a small step but it will open door to full-fled development of D3.js into Sympy.

###Interactive Features which the 3D plots will support are:

  1. Mouse based panning of plot like MATLAB
    The users can simply pan the plot by using his mouse Click and Drag .
  2. Change the particular equation to plot another 3D plot in the browser itself
    As, the user can't see two plots simultaneously, he will have an option to load another plot right into the browser.This is also an existing SympyGamma issue
  3. Zooming the plot
    Just mouse controls can also be used like Mouse wheel or trackpad scrolling for zooming
  4. See the graph better by Animation of flat surface to show its intersection with the plot for better clarity using ShaderGraph.js [4].
    This is the most nicest thing about mathbox.js for reference see Mathbox.js example

###Disclaimer/Logistics: I will not be able to extend the backend for D3.js in my project due to time limitations. I propose to add the present support of D3.js on Gamma into Sympy. See here for discussion of adding D3.js into Sympy
Having said that, I don't have any problem to start my project early from 3rd MAY which will give me a 15 day headstart so that i can work on adding a full-fled support of D3.js in Sympy after completing my project early and to work on GUI of Gamma (we have to accept that it is obsolete) and static files of my project but still that will not be under my project.

After project i will cover the entire ground related to this work but in my proposal i can propose only limited things.

##Demo LINK:
SOURCE CODE: Demo's-github-repo
The main plotting file which is doing the magic is here
I have created a Demo which is a plot of cos(x)cos(y)-cos(x-2y) using Three.js and dat.gui. The function is hard-coded with value cos(x)cos(y)-cos(x-2y) in the codes but it can also be passed by a form. It does not support any interactivity feature yet. It is just 100 lines of code and was written overnight. The purpose of doing this was to show i have the basic knowledge and experience to pursue this idea. Even though I have just scratched the surface, still it gives a nice idea about the project.
Note: I have also used Detector.js provided by "mrdoob/Three.js" to detect if the user have WebGL or not.

##Timeline My semester ends on 3 May and i can start the project "early" from 4 May itself. There is so much to cover and by starting early i can finish more which will help in further development of web-based plotting. This way i can also explore plotting module more and get familiar with it. I will send one Pull Request per Week including my week's long work.

###Week 1

  • Write python script to create JSON data from SurfaceOver2DRangeSeries, Parametric3DLineSeries and ParametricSurfaceSeries classes.
  • Add parameter browser=False to enable browser based plotting.
  • Send Pull Request including the JSON gereating script

###Week 2

  • Write JavaScript to parse JSON and set other parmeters which are function specific.
  • Start writing Mathbox.js based JavaScript codes which will plot the data received from SymPy
  • Send Pull Request including the JSON parser and some mathbox codes.

###Week 3

  • Finish JavaScript codes based on Mathbox.js
  • Fix the errors and bugs to include all three types of 3D plots.
  • Send Pull Request including the Javascript code.

###Week 4

  • Write Static files and widgets
  • Write the Server to render the static files into browser
  • Send Pull Request including the sever and the static files.

###Week 5

  • Write JavaScript for the mouse based gestures in Three.js which will support zooming and panning
  • Send Pull Request including JS code for mouse gestures.

###Week 6

  • Implement dat.gui into the JavaScript code.
  • Integrate the sympy to change parameters interactively.( will use plot class)
  • Send Pull Request including the implementation of dat.gui and sympy integartion for interactivity.

###Mid-Term Evaluation

###Week 7

  • Finish Documentation for the new plotting option.
  • Write tests for server and plotting to ensure completeness.
  • Send Pull Request including documentation anted tests

###Week 8

  • Implement Shader.js animations into the plots for better details without more density which may be slow.
  • Try to find more bugs and extra time for some problem which may occur.
  • Send a Pull Request including shader.js support.

###Week 9

  • Implement the Mathbox.js integration from Sympy into Gamma so that it can plot 3D plots.
  • Send a Pull Request into SymPyGamma for 3D plotting.

###Week 10

  • Implementing D3.js from the Gamma into Sympy on the base created.
  • Write python and Javascript codes for the same.
  • Send a Pull Request adding support of D3.js into sympy

###Week 11

  • Finish the D3.js integration into Sympy.
  • Fix any related bug.
  • Will send a pull request including week's progress.

###Week 12

  • Make sure the code is bug free and follows Sympy coding style.
  • Fix bugs in tests, documentation and codes.
  • Send a PR with week's progress.

###Week 13

  • Buffer period for any unexpected problem.
  • Will complete the entire project by this time
  • Start working on further development including full-fleg support of D3.js and Mathbox.js in Sympy but they will not be included in project.

###Final evaluations

##Implementational Details ###1. Python based backend which will create JSON. This will be the standard base which will create JSON. I will break out mathbox.js's expression which by default take Javascript functions like Math.sin(x) or Math.cos(x) and customize it to use Sympy (Numpy arrays seems like a good choice, the Gamma way). Basically, the idea is to implement a SymPyGama like approach into 3D plotting too. This way ,like Gamma, not everything which can be plotted by sympy will be able to plotted into 3D too BUT following functions will be (these are the basic ones which sympy support for 3D plotting):

1. 3D plots of functions in two variables.    ==> SurfaceOver2DRangeSeries
2. 3D line plots of parametric variable.      ==> Parametric3DLineSeries
3. 3D surface plots of parametric equations.  ==> ParametricSurfaceSeries

Data sent will also include camera, light, scene along with the points thought most of which can be changed client side. They all will be separate and will create separate json's so that when a user demand a change in any one of them only that part will need to recalculate which will be faster. This base will use BaseSeries and Plot classes of the SymPy's plotting module. User will also be able to change the segment's density (more density means more sharper plot)

###2.Json (link between Python and Javascript ) To parse JSON in JavaScript i will use jquery's $.getJSON(url, function (json)) ,so that we can iterate through it with $.each but i can also use THREE.JsonLoader for that. i still have to decide between the two.For reference see what mathics have (see there discussion here)

To setup a scene i will simply call mathbox. Values of its properties will be provided by the JSON. Various function that will be defined additional to mathbox.js will handle all the possible cases and give user what he wants , also, Any of its value can also be set by the user itself. The advantage of using JS rather than Python is that we don't need to do recalculations like stefan's blog code at the expenses of reduces plotting capabilities

###3. JavaScript part JavaScript which will use the json created by python to render the plot will call mathbox object from Mathbox.js .This will be entirely separate from the main SymPy's code-base and Json will be the only link between sympy and JavaScript. The advantage to write the JavaScript into sympy itself is to reduce recalculations. Following code shows a possible way BUT I WILL NOT USE JavaScript FUNCTIONS BUT SymPy's

  type: 'cartesian',
  range: [[-3, 3], [-3, 3]],
  scale: [1, 1],
  id: 'x-axis',
  axis: 0,
  color: 0xffffff,
  ticks: 6,
  lineWidth: 1,
  size: .025,
  labels: true,
  id: 'y-axis',
  axis: 1,
  color: 0xffffff,
  ticks: 6,
  lineWidth: 1,
  size: .025,
  labels: true,
  zero: false,
  id: 'z-axis',
  axis: 2,
  color: 0xffffff,
  ticks: 6,
  lineWidth: 1,
  size: .025,
  zero: false,
  labels: true,
  id: 'my-grid',
  axis: [0, 2],
  color: 0xffffff,
  lineWidth: 1,
  id: 'my-curve',
  domain: [-5, 5],
  expression: function (x) { return Math.cos(x); },
  line: true,
  points: true,
  lineWidth: 1,
  id: 'my-curve',
  domain: [-3, 3],
  expression: function (x) { return [Math.sin(x)*2, Math.cos(x)*2]; }, //This will be change by array 
                                                                      //points in a syntax which will 
                                                                      //adhere to mathbox.js's 
  line: true,
  points: true,
  lineWidth: 1,

I want to point out the issue of time limit imposed by App engine on Live and Gamma. This is the main reason that i am not using python to create JavaScript directly because then this will not be usable for them. We could have used AJAX magic but this is a nice solution.

###4. Rendering JavaScript locally I will use browser to render the javascript generated locally, (if the user wants it as he can always choose matplotlib plots) due to their dynamic nature and the JS library that makes it possible.I will write a server script which will pass the static files containing the sliders to the browser. These sliders will be used to change the parameters which users can define according to their will. Note: This server will be small and will be used only locally. Gamma and Live will not use it. For reference see PyDy-viz's server

###5. Interating dat.gui into the Three.js Due to its present integration with Three.js i will write the sliders with dat.gui . This is an awesome library which directly plays with the Three.js to change it parameters which changes the plot Client Side, This is the main reason that it outperforms matplotlib. They can change certain parameters without recalculations but for changing some parameters recalculations will be required.
I will also customize dat.gui for the SymPyGamma look and feel.

###6. Integarting D3.js based plotting from Gamma into Sympy and Mathbox.js into Gamma. Gamma plots 2D plots nicely but local users cannot use it and for it i want to integrate their support into Sympy itself as my backend and Gamma's plotting have the same philosophy. See for example Gamma's JSON.
To integrate mathbox.js into Gamma i will send the the static files as result card from here . Server will not be activated for Gamma and for that i will write a functions Gamma which will prevent the server from starting when gamma=True and all the 3D plots in gamma will have gamma=True

##Further Scope ###1. Vector Calculus Standard vector calculus operators in three dimensions. Includes coordinate transformations between orthogonal coordinate systems by simply using the .vector function of mathbox as: (taken from mathbox's examples)

  n: 1,                              // Number of vectors
  data: null,                        // Array of alternating start and end points,
                                     // each an array of 2 or 3 elements
  expression: function (i, end) {    // Live expression for start/end points.
    return 0;                        // Return single value or array of 2/3 elements.
  line: true,                        // Whether to draw vector lines
  arrow: true,                       // Whether to draw arrowheads
  size: .07,                         // Size of the arrowhead relative to the stage

Can be developed to include DotProduct, CrossProduct</code, ScalarTripleProduct, CoordinatesToCartesian conversion and vice-versa, JacobianDeterminant, JacobianMatrix etc,visualisations. Can be done similarly by generating JSON and using mathbox.js

###2. Bézier curve Something for PyDy-viz, this can be developed for their use. (mathbox.js's example)

  n: 64,                         // Number of points
  domain: [0, 1],                // Domain, expressed in interpolation space
  data: null,                    // Array of control points, each an array of 2 or 3 elements
  order: 3,                      // Order of bezier curve (1-3)
  expression: function (x, i) {  // Live expression for data points.
    return 0;                    // Return single value or array of 2/3 elements.
  points: false,                 // Whether to draw points
  line: true,                    // Whether to draw lines


  1. This discussion shows that how can we send the points from the Sympy to Three.js as Json.
  2. A nice demo for the usage of dat.gui. I haven't used dat.gui in my own demo because this link is very good demo in its own to show what i intend to do.
  3. Shading library to let the user see the graph more clearly.
  4. This is a nice example of what i wish to achieve. It uses Shader.js and Three.js.
  5.!topic/mathics-devel/r71v18mwwSk This discussion of the Mathics developers is where i started from.Its nice and show how they started 3D plotting.
  6. The discussion about parsing JSON in JavaScript
  7. My philosophy is quite similar to Bokeh.
  8. PyDy-viz's server, reference for my server.
Clone this wiki locally
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.