Scott Hanselman

Generating complex math visualizations in SVG using C# and ILNumerics

October 17, '13 Comments [15] Posted in Open Source
Sponsored By

I was recently turned on to the ILNumerics library. It's a high performance math library for .NET developers that my math skills can barely comprehend. It has a clean and elegant syntax, but more importantly, it's visualization graphics engine is thoughtful, flexible, and well-factored.

Having worked on a lot of websites, including ones that do a lot of backend image generation, resizing and analysis (like check imaging almost 10 years ago) I was impressed at how easily I was able to get an equation onto a basic website with ILNumerics and SVG.

Of course, it's not just a web library, in fact, most of the samples are WPF and WinForms, so it's an engine that you can use anywhere. Regardless, as a web person, I wanted to see how quickly I could get something into my browser.

The ILNumerics website has a cool sample 3D graph on their home page that was generated with this code:

var scene = new ILScene {
new ILPlotCube(twoDMode: false) {
new ILSurface(ILSpecialData.sincf(40, 60, 2.5f)) {
}
}
};
scene.First<ILPlotCube>().Rotation = Matrix4.Rotation(
new Vector3(1f,0.23f,1), 0.7f);
scene;

However, you'll notice in their sample they just end with the variable "scene." That's a no-op there, but it's their coder way of saying "at this point, the scene variable holds a representation of our plot. Do with it as you will."

NOTE: Do check out their home page...the little sample there is deeper than you'd think. The dropdown shows they can generate PNGs, JPGs, JPG HD, SVG, but also "EXE." Hm, download a random EXE from the internet? Yes please! ;) Take a risk and you'll get a nice self-contained EXE visualizer that not only renders the graph but lets you rotate it. You can download the ILView 3D viewer and play around, it's harmless - all the code for ILView is on GitHub! The best part is that it has a built in REPL so you can type your C# right there and see the results! It even runs on Linux and uses Mono. ;)

ILNumeric

Back to my goal. I want to use the library on a basic website and dynamically generate an SVG of this plot.

Here's the same plot, put inside an ASP.NET HttpHandler (which could also be made routable and used in ASP.NET MVC/Web Forms, etc.)

public void ProcessRequest(HttpContext context)
{
var scene = new ILScene {
new ILPlotCube(twoDMode: false) {
new ILSurface(ILSpecialData.sincf(40, 60, 2.5f)) {
}
}
};
scene.First<ILPlotCube>().Rotation = Matrix4.Rotation(
new Vector3(1f, 0.23f, 1), 0.7f);

var driver = new ILSVGDriver(context.Response.OutputStream, 1200, 800, scene, Color.White);
driver.Render();
}

Here I'm passing context.Response.OutputStream to their ILSVGDriver and saving the result not to a file, but directly out to the browser. I could certainly save it to cloud blob storage or a local file system for caching, reuse or email.

using (FileStream fs = new FileStream(@"test.svg", FileMode.Create)) {
new ILSVGDriver(fs, scene: whateveryoursceneis).Render();
}

While a SVG is preferable, one could also make a PNG.

var driver = new ILGDIDriver(1280, 800, whateveryoursceneis); 
driver.Render();
driver.BackBuffer.Bitmap.Save("whatever", System.Drawing.Imaging.ImageFormat.Png);

Their docs are excellent and many include a similar interactive viewer within the website itself.

It's so much more than a plot visualizer, though. It reminds me a little of D3.js, except more math focused and less live-data binding. It's almost as flexible though, with many kinds of visualizations beyond what you'd expect.

3D graph that looks like a mountainDonut graph

Three 3D graphs in one plotTopographical plot

Infinite TrianglesHalf a sphere intersected by a blue gear

Here's the code to show a green sphere that's composed of triangles, but has the top chopped off, as an example. This is just 10 lines of code, and could be made less.

var scene = new ILScene(); 
// create a new sphere
var sphere = new ILSphere();
// the sphere is a group containing the Fill (ILTriangles)
// and the Wireframe (ILLines) of the sphere. Both shapes
// share the same vertex positions buffer. Hence, we only
// need to alter one of them:
using (ILScope.Enter()) {
// take the vertex positions from the Fill.Positions buffer
ILArray<float> pos = sphere.Fill.Positions.Storage;
// set all vertices with a Y coordinate larger than 0.3 to 0.3
pos[1, pos[1, ":"] > 0.3f] = 0.3f;
// write all values back to the buffer
sphere.Fill.Positions.Update(pos);
}
// add the "sphere" to the scene
scene.Camera.Add(sphere);
// add another light (for niceness only)
scene.Add(new ILPointLight() {
Position = new Vector3(-0, 1, -2)
});
// move the camera upwards
scene.Camera.Position = new Vector3(0,3,-10);
// display the scene
scene;

And this gives you:

Half a green sphere

It's a really amazing project. ILNumerics is GPL3 and also uses OpenTK for OpenGL bindings, and Mono.CSharp for C# compiling and evaluation. ILView is under the MIT/X11 license.

You can get it via NuGet with just "Install-Package ILNumerics." Check it out and tell your friends, scientists, and friends of Edward Tufte.


Sponsor: Thanks to Red Gate for sponsoring the feed this week! Check out a simpler way to deploy with Red Gate’s Deployment Manager. It can deploy your .NET apps, services, and databases in a single, repeatable process. Get your free Starter edition now.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by ORCS Web
Thursday, October 17, 2013 8:55:56 AM UTC
You had me until GPL(v3).
I don't like how restrictive it is and I wouldn't consider it "free".

Which is a shame, because the library itself looks amazing.
Peter Gruber
Thursday, October 17, 2013 9:22:06 AM UTC
@Peter Gruber. I initially thought the same, but once I checked their website I saw that you can buy a commercial license if you need one.

I say that's fair enough. They've clearly put a lot of work in.
James Chaldecott
Thursday, October 17, 2013 10:48:54 AM UTC
Good work.....Interesting.
Thursday, October 17, 2013 11:20:41 AM UTC
@James Chaldecott. Well, that does change things a bit.
But not really for me, I don't make money off the programs I write, I make them to scratch an itch and release them if I think it's going to help others too.
So, NumericalIL is out of the question as I don't have 1k lying around :)
Having said that, I certainly understand the need of getting paid and don't object to that. I guess a gpl version is better than no (unpaid) version at all.
Peter Gruber
Thursday, October 17, 2013 11:45:36 AM UTC
I like this, but for the sake of not downloading an exe id rather use something like http://unity3d.com designed for game dev and such but has a really cool web page embedded browser.

Nice for writing desktop code that want to show off on the web or stuff like this :)
Thursday, October 17, 2013 12:40:53 PM UTC
I'd have to agree with the GPL(v3) show stopper. Shame they didn't go for LGPL(v3) instead.
Thursday, October 17, 2013 1:45:06 PM UTC
90% of classes are "ILSomethingOrOther". Mega ultra facepalm.

Guess they were concentrating more on the math than the framework guidelines.
Will sullivan
Friday, October 18, 2013 10:01:48 AM UTC
Great post. I'm confused by the syntax though:


var scene = new ILScene {
new ILPlotCube(twoDMode: false) {
new ILSurface(ILSpecialData.sincf(40, 60, 2.5f)) {
}
}
};


I have never seen an object initializer without a named parameter, is this valid C# syntax?
Marty
Friday, October 18, 2013 10:29:27 AM UTC
Great article! I like the way you use ILNumerics for offscreen rendering :)

@Will sullivan You name it. The guidelines are great in general. But they sometimes conflict with the need for expressive math syntax.

Regarding the GPL License: We clearly understand the wish for an (even more) free version. There was an LGPL version in the past. But at the end the GPL simply gives us better opportunities for supporting the community in the long run.

But not really for me, I don't make money off the programs I write, I make them to scratch an itch and release them if I think it's going to help others too.
So, NumericalIL is out of the question as I don't have 1k lying around :)

So, why not use the GPL version than? I am positive, your programs will be useful to others, regardless of GPL / LGPL? If one of your users really _needs_ a less restrictive license, you can get in touch with us and we can negotiate a discount on the PRO license.
Friday, October 18, 2013 11:12:55 AM UTC
@Marty This is valid C#. Object initializers make the setup of complex scenes painless and very short. In general you have two options:

1. Use object initializer to set properties of the new object:


new ILSurface(ILSpecialData.sincf(40, 60, 2.5f)) {
Wireframe = { Color = Color.Red }
}


2. Use collection initializers to conveniently Add() objects to a new collection. In your example this is used to add the surface to the plot cube and the plot cube to the scene.
Friday, October 18, 2013 11:30:57 AM UTC
@Haymo Thanks very much for the clear explanation. It should have crossed my mind that ILScene is in fact a collection and the initializer is a collection initializer! Maybe I should go back to C# basics before I start using this library :).
Marty
Friday, October 18, 2013 11:46:38 AM UTC
@Marty ... it's not that complicated ;) Just a short version of

var plotcube = scene.Add(new ILPlotCube(...));
plotcube.Add(new ILSurface...);
Friday, October 18, 2013 12:56:25 PM UTC
It is nice to find something like this is available for C#!

At this time, the primary reason to invest the effort in learning to use this library vs. the standard open-source graphing tools is when the production environment dictates use of Microsoft technologies.

How many people care about "ILNumerics" on your resume vs. R, ggplot2, etc? Even the python stuff has greater recognition. Every project has to start somewhere though and I'm glad to find out about ILNumerics sooner rather than later.
Jed
Friday, October 18, 2013 1:53:14 PM UTC
Thanks Jed, I'm glad you like it!

You are right, there are other graphing tools around. ILNumerics does not so much focus on the prototyping part. It rather eases the "build an application out of it" part. As soon as you must create an application out of your algorithm, build an efficient visualization, have configurable interactivity, pack it into an installer or even deploy it as a single executable to some customers... ILNumerics supports cases like that.

BTW, it is not bound to C#. ILNumerics can be used with every .NET/mono language, let it be C#, F#, VisualBasic or IronPython. And, as Scott pointed out, it runs on Linux without having to recompile :)
Monday, October 21, 2013 2:54:18 PM UTC
@Haymo Kutschbach


But not really for me, I don't make money off the programs I write, I make them to scratch an itch and release them if I think it's going to help others too.
So, NumericalIL is out of the question as I don't have 1k lying around :)

So, why not use the GPL version than? I am positive, your programs will be useful to others, regardless of GPL / LGPL? If one of your users really _needs_ a less restrictive license, you can get in touch with us and we can negotiate a discount on the PRO license.

Because I don't want others to be locked in in GPL, or let them use my code for closed-source or commercial projects. It really depends on the project. GPL is a one way street - almost everything leads in, but nothing out of it.

I appreciate the offer, but like I said, I don't do this for a living or even make a dollar off of it.

Anyway, your library is awesome and keep up the good work :)

asb
Peter Gruber
Comments are closed.

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.