How to Jitter Well
By: Tony Boyles
Tags: Data Visualization

In Data Visualization, you sometimes run into a problem where you want to put multiple things in the same place. Most visualization software is happy to accommodate this: it simply draws one thing, and then the second thing right on top. This is called overplotting.

This map is badly overplotted. You can’t tell, though, because it’s overplotted. ¯\_(ツ)_/¯

Sometimes it’s fine, but usually you want tools to avoid overplotting. There are a couple. The first is to manage the opacity of the elements (i.e. how un-transparent they are).

This map has nodes with limited opacities.

This approach is usually pretty easy, but has some severe limitations. You can see that the point in the bottom left is very dark, so it must have many nodes (circles) drawn on that location. Unfortunately, we have no idea how many nodes. The other circles are pretty light, but there’s still no telling whether they’re one, two, or many nodes with very low opacity. All we can tell is that there’s more at that one point than at the others.

A second approach is to cluster closeby nodes together. Here’s the same map with clustered circles:

Clustering shows us how many circles are around any given location

Now we can see exactly how many nodes are approximately at a given location, with little more than a glance. That’s definitely an ideal for most data visualization applications, so this approach is a very strong contender for “generally best”. However, there’s a third option with another advantage.

Often times in public health, we’re working with Personally Identifiable Information, which means we have to be very careful about how we disclose it. Publishing a map with people’s exact locations on it would be a huge privacy breach. So, to avoid that, we can add some randomness to their location on the map. This randomness is called jittering. It looks like this:

This map has jittered points.

Because we add different random values to each node’s location, this helps to reduce overplotting. Here we see that with a small amount of jittering, we‘ve transformed a badly overplotted location into a cloud of nodes that’s only mildly overplotted. This can help to protect individual information (e.g. transforming specific information like an address to general information like a city).

But jittering presents its own unique problem. Web Content Accessibility Guidelines (WCAG) 2.1 (which we use to test MicrobeTrace’s Section 508-compliance) specifically warn against animations that flash at certain rates. If you drag the MicrobeTrace jitter slider bar, you’ll tend to see the circles “flashing” across the screen at those rates.

Trigger Warning: can cause seizures. If you’re not susceptible, click here to see an example.

This flashing occurs because the existing algorithm simply takes the distance represented by the slider bar, multiplies that by a random value, and then adds that product to each node’s latitude. Then it does the same thing with the longitude. To avoid causing flickering, we have to rethink this approach to adding the randomness to our node locations.

Instead of adding a new random value each time, we can pick a random direction at the beginning, and then have each point “walk” in that direction as we change the slider bar. To do that, we’ll need to do a little trigonometry.

To start, the “direction” should be a number between 0 and 2*pi, or 6.283whatever… If you’ve had trig, you’ll recognize this as an angle in radians. If you haven’t, it’s just a different way of measuring the same thing that degrees measure (radians are more convenient for trig functions).

A unit circle with the relevant trig functions. h/t Wikimedia Commons

In this case, r is the distance given by the slider, θ (pronounced theta) is the random direction we picked, sin θ is the amount to add to the latitude, and cos θ is the amount to add to the longitude.

Now that we can calculate that, let’s imagine what it will look like: as you drag the slider bar, the points will expand and contract from their original location, as though walking at equal speeds from the center of a circle. See the problem?

You can infer exactly where that circle of nodes came from.

If your circles are equidistant from their origin, clever users can make reasonable inferences about which points belong to the same origin and where that origin is. So, in addition to randomizing the angle at which circles “walk”, we must also randomize the “speed” at which they walk. To do this, simply pick a second random variable at the beginning when you’re choosing the angle. Each time you change the jitter slider, multiply that by the circle’s speed to get the final distance the circle should cover. The end result should look something like this:

Voila! Flashing-free, PII-safe jittering. Since it involves both a direction and a magnitude (speed), I’m calling this velocity-based jittering (but if there’s an official name for this technique that I don’t know, please let me know about it). So, the final formulation of the algorithm goes like this:

When you load data, give each node a random angle and a random speed. When you change the jitter, compute the new location of each node using simple trigonometry.

And there you go. Go forth and jitter well!

Velocity-based jittering will be available in the Map and Globe views of the next release (0.5.6) of MicrobeTrace. In the meanwhile, you can test it on MicrobeTrace’s Dev version.