✊🏿 Black Lives Matter. Please consider donating to Black Girls Code today.
🧬 Learn how to build RNA-Seq data apps with Python & Dash. Register for the May 20 Webinar!

Color Bleedthrough Invalid Polygon or GeoJSON

I am going to make this as clear as I can.
I am currently working on a library to plot hexagonally binned data in a geospatial context. So far I have used Plotly graph objects with great results. I had an earlier problem with the way that my GeoJSON Polygons were defined through the 180th meridian (a common issue as far as I can tell). The recommended way to fix the problem was to split these Polygons into two separate Polygons stored in a MultiPolygon however, I found doing this programmatically was a big challenge, so I opted for another method where Polygons that cross have their coordinates shifted properly, and it has worked for every case thus far. The new issue comes where I try to use that same algorithm over Polygons containing either geographic pole, and perhaps other Polygons. I have ensured the winding order of my Polygons comply with RCF7946 (RFC 7946 - The GeoJSON Format). If these Polygons are viewed at certain angles, they appear fine but if they are moved the plot has a color bleedthrough. I believe the problem either has to do with the invalidity with the Polygon itself or the GeoJSON form of the Polygon.

Although I don’t think this is the issue, the code used to generate the choropleth traces is here.

        geojson = gcg.geodataframe_to_geojson(gdf, 'value_field')

        choro = Choropleth(
            locations=gdf.index,  # [id_field],

For the purposes of the example shown above, I have retrieved the GeoJSON object of the seemingly problematic Polygon:

{"geometry": {"coordinates": [[[8.384361, 87.823618], [58.384449, 88.499393], [146.008397, 89.074149], [232.289931, 88.477001], [281.816835, 87.808244], [325.048764, 87.58501], [8.384361, 87.823618]]], "type": "Polygon"}, "id": "820327fffffffff", "properties": {"value": 0.0}, "type": "Feature"}

This is the current algorithm I use to conform the Polygons:

def _wraps_lat(poly: Polygon):
    coordinates = list(poly.exterior.coords)
    for x in range(1, len(coordinates)):
        p0 = coordinates[x - 1]
        p1 = coordinates[x]
        if _check_antimeridian(p0[0], p1[0]):
            return True
    return False

def _fix_polygon_bounds(poly: Polygon):
    wraps = _wraps_lat(poly)
    coordinates = list(poly.exterior.coords)
    new_poly = []
    for cord in coordinates:
        lon = _fix_lon(cord[0]) if wraps else cord[0]
        lat = _fix_lat(cord[1])
        new_poly.append((lon, lat))
    return Polygon(new_poly)

If anyone knows anything about what could be going on here it would help a lot. This issue is quite pressing!


See a more detailed version: