Sept 23 | Uncover insights and realize outcomes at the speed of thought with Plotly Studio.

author photo

Cameron DeCoster

August 12, 2025

Improved Map Accuracy in plotly.js with UN Geodata

In our new release of plotly.js v3.1.0, we’re switching to new map data based on United Nations geospatial boundaries. The goal of the project was to create a drop-in replacement for the existing maps; just with a different source for the map data. The motivation for this change came from community feedback and internal discussions. This change addresses long-standing challenges with how disputed territories and unclaimed regions are represented.

For users, this means maps will align more closely with UN-recognized boundaries and reduce surprises in politically sensitive regions.

Geography fact: there are two disputed territories along the Egypt/Sudan border: Bir Tawil and the Halaib Triangle. Bir Tawil is one of a few non-polar regions in the world that isn’t claimed by any country (referred to as terra nullius). These territories aren’t represented in Natural Earth data but they are in the UN data, so some decisions had to be made about how to show these in the new maps. The ultimate solution was to provide unique country codes (XBT, XHT) and not show them as belonging to any other state.

Handling edge cases like Bir Tawil and the Halaib Triangle pushed us to rethink how we represent political geography. That work fed directly into a larger update to our base maps.

Why we switched to UN geodata

For a number of years, Plotly has been using (indirectly) mapping data from Natural Earth Data. Natural Earth maps are excellent and are provided free of charge in the public domain. But Natural Earth uses a controversial policy showing boundaries of disputed territories. This can lead to situations where occupied territories are shown to be a part of the occupying group rather than the occupied state. In an effort to move away from maps built using this policy, we’ve started using geodata derived from United Nations Geospatial Data.

How we process and serve the new maps

The plotly.js library provides maps using TopoJSON, which is an extension of GeoJSON. Both of these formats are used to encode geographic data wrapped in a JSON file. TopoJSON tends to be more compact from the reduction of redundant geometries. For the new maps, GeoJSON from the UN is transformed via a number of steps into TopoJSON. This includes parsing the correct polygons, saving them to different files for a number of regions, and compiling them all into different layers for the final set of maps. That sounds simple enough, but can actually be pretty involved. For example, transforming a spherical map into a flat projection means that the world needs to be cut somewhere. The standard location that this cut occurs is at the 180th meridian (also called the antimerdian). This meridian crosses through land in Antarctica, Fiji, and Russia. The cut needs to be made correctly or viewers can see odd visual artifacts. See below:

maps in plotly.js

Another important step in the conversion process is preparing the geodata to be displayed in a spherical representation. The antimeridian cuts mentioned above are important for this step because they need to be stitched together. If the cuts aren’t made correctly, the stitching process won’t work and map layers (oceans, coastlines, etc.) won’t render correctly. At this point, it’s necessary to make sure the polygons are in the correct winding order: exterior borders should wind counterclockwise and interior borders should wind clockwise. Put another way, “solid” country borders should wind counterclockwise and “holes” should wind clockwise.

It’s worth mentioning that the UN and Natural Earth data aren’t exactly the same and some work needs to be done to get the UN data close to parity with the NE data. As mentioned before, one of the project goals was to make the new maps a drop in replacement. This requires filtering continents/countries into a number of regions, showing/hiding water bodies, and adding/removing metadata to get all the lookups in the library to work correctly. In the end, using Natural Earth data is still necessary to provide subunit borders (states, provinces, etc.) because that isn’t included in the UN data.

These new maps will become the default in v3.1.0. You can access them in the package or you can find them on our CDN at a special path (https://cdn.plot.ly/un/<map_name>). The legacy maps (https://cdn.plot.ly/<map_name>) will remain available on the CDN for now to maintain compatibility with older versions of plotly.js. Please let us know if you have any feedback.

Maps available in plotly.js:

Region

50m Resolution

110m Resolution

Africa

africa_50m.json

africa_110m.json

Antarctica

antarctica_50m.json

antarctica_110m.json

Asia

asia_50m.json

asia_110m.json

Europe

europe_50m.json

europe_110m.json

North America

north-america_50m.json

north-america_110m.json

Oceania

oceania_50m.json

oceania_110m.json

South America

south-america_50m.json

south-america_110m.json

USA

usa_50m.json

usa_110m.json

World

world_50m.json

world_110m.json

Bluesky icon
X icon
Instagram icon
Youtube icon
Medium icon
Facebook icon

Product

© 2025
Plotly. All rights reserved.
Cookie Preferences