No matter what you work on, data drives decisions these days. At Uber, we like to see this data move in order to really understand it. Now anyone with a big data set can do the same on the Web.

Today, we open sourced deck.gl, a WebGL-powered framework specifically designed for exploring and visualizing data sets at scale. deck.gl lets us visualize it without compromises.

Data, Visualized Fast

While deck.gl’s architecture suits both abstract and scientific visualization needs, map-related data is our biggest asset at Uber. We’ve stretched and tested deck.gl in many different mapping environments prior to this first release.

At Uber, the many GPS points we process every day serves needs across the company. If we have a problem in our platform, we can diagnose it by exploring historical geolocation data. If there’s an accident on the road, we can explore GPS traces for a given trip to get full context. If there are pain points around pickup locations in a city, we can communicate plans to city authorities by visualizing them. We need this data to be web-based, real-time, and shareable so other teams at Uber can use it. To meet all these needs, we developed deck.gl.

deck.gl focuses on the following key aspects for users:

  • Performance: Get high-performance rendering of large data sets (millions of points or vertices), including features like on-the-fly aggregation and visual exploration, based on latest WebGL technologies.
  • Accuracy: Achieve high-precision numerical computations on the GPU, thanks to our custom fp64 math library. To our knowledge, no WebGL-based library currently provides this functionality, which is crucial for full interactivity of geo data sets.
  • Extensibility: Use the latest coding standards, including ES2016, and a rich ecosystem of libraries and settings that enable easy debugging and profiling of WebGL applications

What deck.gl Offers to Mapping Use Case

deck.gl’s set of features adapts to a wide range of use cases, including mapping. As an example, deck.gl can be used in conjunction with MapboxGL’s camera system, so data can be optionally displayed on top of a Mapbox map and visualized in perspective mode. You can also jump start any data visualization project with deck.gl’s set of core layers, including the scatter plot, line, arc, choropleth, and grid layers, or you can optionally connect to other third-party libraries like our popular open source framework react-map-gl, a thin React wrapper around the MapboxGL JavaScript API.

To demonstrate, we developed a set of simple examples that focus on mapping use cases. Check out this demo to see the performance of deck.gl with large data sets: 2M points and 36K taxi trips in NYC with live GPU interpolation.

36K taxi trips make up to 2M points rendered with full building structures of Manhattan.

36K taxi trips make up to 2M points rendered with full building structures of Manhattan.

We’ve also developed layers to visualize 3D building structures, street segments, point-cloud data, and more, which we will be open sourcing in future releases. Let’s dive deeper into some of the design and architecture decisions behind deck.gl!

Instancing + Layering

By combining instances and layers, deck.gl makes complex visualizations possible without crashing computers. If you’ve worked with D3 visualizations in the past, then you’re already familiar with the concept of instancing. Instancing is when you render multiple copies of a single object, with little tweaks among the copies. You end up with what appear to be different objects, but all of these are displayed inexpensively because of how the WebGL API works. For example, to create a scatter plot, you have circle elements and apply modifiers on the radius, position, and color of these circles based on the values of each row in the data.

We instance 860K circles with deck.gl.

We instance 860K circles with deck.gl.

To make use of this instancing feature, deck.gl has a layering system to overlay different data sets (with blending modes, clipping, etc.). You can reason about different types of data with clear semantic separations in one big picture, adding and removing layers as you need to. For example, a common Uber deck.gl application might include layers for pickups, dropoffs, requests, elevation, 3D buildings, and point-cloud data, all rendered with high performance because the geometric primitives are all just copies.

Layers can also create computations like grouping and aggregations. This is useful to create on-the-fly heatmaps of population density, median ETAs, etc. This example shows dynamic aggregation in a grid. The computations are performed live so that granularity changes with the zoom level.

On-the-fly dynamic aggregations with the grid layer.

On-the-fly dynamic aggregations with the grid layer.

High-Precision GPU Computations

One deck.gl feature we’re really proud of is its ability to handle high-precision transformations and other numerical calculations on the GPU. WebGL and many other graphics libraries like Apple’s Metal support only 32-bit single precision floating point numbers. WebGL is particularly lenient about numerical accuracy on many of its supporting platforms.

As deck.gl aims to provide both accuracy and performance for high-dynamic-range (HDR), scientific-grade data, we implemented a powerful extension to emulate 64-bit double precision floating point numbers on all platforms that support WebGL 1.0. With twice the significant digits (46 bits) in the mantissa, the emulated high-precision data type enables rendering of primitives that can never be handled by the GPU, using intrinsic single precision floating point numbers. This is incredibly useful for rendering geographic elements specified in lat/long pairs at the centimeter level or for rendering interactive data-dense visualizations that span from the city level down to the intersection level of a map.

Most other libraries that handle high zoom levels either use different coordinate systems (like UTM), which trade dynamic range for precision, or perform CPU-based computations for alignment with the overall map, which trade performance for precision. By doing all math in this high-precision type of floating point numbers, we’re able to move over all computations to the GPU and attain accuracy, performance, and interactivity at the same time. This example showcases the high-precision GPU float operations.

Mandelbrot set with a high zoom level (2.0e6) rendered on GPU using native 32-bit math and 64-bit math library provided by deck.gl.

Mandelbrot set with a high zoom level (2.0e6) rendered on GPU using native 32-bit math and 64-bit math library provided by deck.gl.

Built with Latest Coding Standards

We built deck.gl to be as relevant as possible to other users like us. deck.gl therefore uses the latest JavaScript coding standards, with classes and other concepts from ES6 (ES2015) and ES7 (ES2016), supported via Babel transpilation. Naturally, it comes packaged as an npm module and is compatible with standard JavaScript bundlers like Browserify and webpack.

To make deck.gl easy to use, we created a companion utility library called luma.gl, which uses the same coding and design conventions as deck.gl. luma.gl comes with the following:

  • Latest JavaScript coding standards, including ES2016
  • Well-supported features from the coming WebGL 2.0 standard, such as instanced arrays in WebGL1 applications
  • Classes that expose WebGL 2.0 features (like transform feedback), enabling you to start experimenting today on supporting browsers*
  • Advanced debugging, tracing, error checking, and facilities for inspecting buffers and memory to simplify the notoriously difficult process of debugging WebGL applications
  • Shader library with a 64-bit floating point emulation package for the GPU, tested and made to work across the majority of the industry’s GPU drivers (the fp64 library is heavily used in deck.gl for creating high-precision layers)

*It will soon enable the use of WebGL to run compute shaders for general-purpose computation.

Interoperability with React and Mapbox

We built deck.gl with reactive programming model principles (popularized by React) and worked on full interoperability with Mapbox’s camera system. As a result, perspective mode and alignment work out-of-the-box for mapping applications. This example showcases perspective mode in Mapbox with the core Arc Layer in deck.gl. It’s displaying county-to-county migration in the United States. Use shift + drag to change the perspective of the map.

A visualization connects U.S. counties with the arc layer.

A visualization connects U.S. counties with the arc layer.

We have future plans of integrating with other aspects of Mapbox, but we’re also keeping the library decoupled so that it can be used with other packages of your choice.

More to Come

With this first announcement of deck.gl we also are working on an ambitious roadmap, tightening the interoperability with Mapbox but also pushing in another direction: making deck.gl a building block for abstract data visualizations or other types of scientific visualization. Feel free to reach out to the team at data-viz@uber.com if you have any comments. Looking forward to seeing what you build with this!

Nicolas Garcia Belmonte leads the data visualization team within Uber Engineering.

0 Comments