Automating xkcd Diagrams: Transforming Serious to Funny

On early Monday morning I noticed an interesting question posted on Mathematica Stack Exchange titled quite innocently “xkcd-style graphs.” Due to the popularity of Randall Munroe’s xkcd web comic, I expected a bit more than average of about ten or so up-votes, a few bookmarks. Little did I know. Spontaneously emerging viral events are hard to predict, so if you are lucky to catch one, it is fascinating to watch its propagation across the web and the growth of its ranks. In a matter of two days, this post received more than 100,000 views, 200 up-votes, and 150 bookmarks; produced responses and similar posts across other Stack Exchange communities; triggered a small tornado on Twitter; and was discussed on Hacker News and reddit. For convenience, I repeat Amatya‘s original post and example xkcd image here:

“I received an email to which I wanted to respond with a xkcd-style graph, but I couldn’t manage it. Everything I drew looked perfect, and I don’t have enough command over Plot Legends to have these pieces of text floating around. Any tips on how one can create xkcd-style graphs? Where things look hand-drawn and imprecise. I guess drawing weird curves must be especially hard in Mathematica.“

Well, it turned out, “drawing weird curves” in Mathematica is as easy as it is fun. Mathematica Stack Exchange is a rapidly growing Q&A community organized entirely by the efforts of our users. I was delighted to see that it attracted so much attention with an intriguing motivating question, and quite a few beautiful, inventive answers. To view all the answers, I encourage readers to visit the original post. Here I will discuss just one solution, by Simon Woods, which can be applied more or less universally to all types of Mathematica graphics and even images.

Simon starts with the definition of a font style that would imitate well the humorous appearance of xkcd comics.

The next step is to provide a function that makes text call outs like the ones so eminently used in xkcd. Given a point on a graphic and an offset for a text label, the function uses splines to connect the designated point by a smooth curve with its label.

Now it is time to define the rules that, given a graphical object, will replace its styles with our predefined xkcd text style and a thicker line style. Notice how the sixth line of the code replaces lines in graphics with thick black lines drawn over identical, but slightly wider, white lines. This is to produce a noticeable gap in one curve when another is crossing over—a characteristic detail of cartoonish hand-drawn diagrams.

The next function applies the above rules and makes the axes thicker.

It is finally time for the image processing part, the most innovative and attractive element of Simon’s solution, in my opinion. The reason—it can work independently from the rest of the code with arbitrary images, not only with Mathematica graphics. As we will see later, this allows the application of xkcd style to any image of a scientific diagram. The goal of the function below is to slightly distort the perfect lines of a graphic to imitate somewhat uneven human hand-drawn figures.

The function first rasterizes a Mathematica graphic, turning it effectively into an image. Then it generates two extra random images and smoothes them by a convolution with a Gaussian kernel. The randomly but smoothly changing pixel values of these images are the guides to how much to displace the pixels in the original image. The pixel displacement is done with the ImageTransformation function. The very last function combines the application of xkcd styles with image processing distortion.

Let’s now try this on a few plots. Here is the first example given by Simon to illustrate everything working together.

And here are his other 2D and 3D examples with xkcdConvert applied to all sorts of Mathematica graphics functions. Note xkcdConvert can be applied to function names as well as to the graphic’s output. This means you can first produce a 3D graphic, adjust it with mouse rotation, zoom, and panning, and then apply xkcdConvert directly to the result.

I must tell you that a few years back, Jon McLoone wrote another xkcd automation blog post titled “Self-Description.” There he showed how to make an xkcd self-referential chart and give it some more color. Now we can even give it some wiggle proper for hand-drawn figures (click to magnify):

I think the look is quite authentic. Excellent work, Simon! Please, take a look at the examples’ code and other solutions at the original post. Note how the xkcdConvert function can be applied directly to an image. We miss the opportunity to replace original with funny fonts, because the fonts are rasterized in the image. Yet it still produces quite a realistic effect.

Yu-Sung Chang had a great idea of designing a CDF app that will take a URL of an image and stylize it in an xkcd manner. Below we use an idea that is slightly different from Simon’s. In our case, a randomized BSplineFunction serves as a guide for ImageTransformation pixel displacement. It also allows for adjustable controls to tune-up wiggling amplitude and frequency. Go ahead and paste a URL of a diagram image on the web and hit Enter. You can invert the colors if you wish, and even copy the result to the clipboard to save the image on your computer.

To view the full content of this page, please enable JavaScript in your browser.

You might be wondering how a product used by professionals across industries and academics for advanced research can so easily be turned to efficiently solving rather unusual problems involving arts, creative thinking, and unconventional approaches. The answer lies in integration. Mathematica comes with a wide range of technologies and algorithms, all available out of the box. They are developed in a meticulously consistent manner, so users can flexibly combine them as LEGO pieces to build versatile applications. Let’s see how many domains of applications we used: typesetting, graphics, rules and patterns, splines, image processing, importing and exporting, web operations, dynamic interactivity, interface construction, deployment, and CDF. So I hope the next time our readers open a Mathematica notebook to solve an equation or plot a graph, they will remember that the almost limitless possibilities for improvisation can take them far beyond routine single tasks.

19 Comments

Hear! Hear! I really enjoyed all of this! I used the code provided and the Humor Sans font to make that piechart showing one sector that resembles pacman and the remaining area that doesn’t! I’ve wanted to do that in Mathematica in this style since I first saw that joke! Thank you!

Not to denigrate anyone, but I think this post inadvertantly highlighted the biggest weakness of Simon Wood’s solution. With parallel lines that are close together, like in Jon McLoone’s self-referential drawing, the wiggles looks unnaturally synchronized for hand drawings.

Really? This awesome post, and the only comments are about the font choice? (Which, by the way, god forbid we use a font that comes installed on every computer instead of a font which must be installed!)

I was curious how this would look when applied to complicated images, like fractals. Fractals looked okay, but I think the bifurcation diagram of the logistic map looks… better when xkcd-ified! I wonder if there are other “formal” things that might look cool – maybe polyhedra or polytopes?

To be honest, I simply chose a font that was installed on *my* PC. And because the text gets distorted along with everything else, I used one that was clear enough to withstand a bit of wobbling. I know it’s widely disliked but perhaps I underestimated how much!

This is really neat. Every now and then I give more general talks on scientific aspects, in which I use Mathematica. I usually hide the input to make sure that Mathematica does not become the message and use relatively simple graphics or none at all. Kind of hand-made graphs are definitely a brilliant way to emphasize basics as well as simplicity. Since they do not look so perfect they certainly reduce the distance between the speaker and the audience. You should make this an Option in Show: xcdStyle->True or xcdStyle->{True, frequency, amplitude}.