CarlaVdB
CarlaVdB

Reputation: 315

Plotly in Python - layer points over polygon on map

Good day,

I am very new to Plotly. I am trying to make the following visualisation: enter image description here

In essence - it is a layer of points (blue points) and a layer of one polygon (red polygon). I don't want to use Mapbox, because I need the background map to be very simple.

I have managed to get the points in:

import plotly.express as px
import json

fig = px.scatter_geo(points, 
                     'y',
                     'x',
                     color='blue',
                     labels={"poi": "Points of Interest"},
                     )
fig.update_geos(showcoastlines=True, coastlinecolor="Black",
                showland=True, landcolor="White",
                showocean=True, oceancolor="LightBlue")

fig.show()

But now I need the polygon on the map.

The file containing the points and the other file containing the polygon, are both in GeoJSON format.

How do I do this? I cannot seem to find documentation on making different layers on the plot.

Any and all assistance is greatly appreciated. Thanks!

Upvotes: 1

Views: 1847

Answers (1)

Rob Raymond
Rob Raymond

Reputation: 31146

  • have generated a line string and some points to make code run in any environment
  • scatter geo can plot lines in same way that scatter traces work. mode="lines"
  • key to this is having a sequence of points that make up the polygon/line that you want. I have used geojson to provide this (generated with geopandas as outline of a number of countries in area of Africa you have shown interest in)

solution

# given coordinates of a polygon add another trace that are lines not points
fig.add_traces(
    px.scatter_geo(
        pd.DataFrame(
            geojson["features"][0]["geometry"]["coordinates"], columns=["x", "y"]
        ),
        "x",
        "y",
    )
    .update_traces(mode="lines", line_color="red")
    .data
)

output

enter image description here

full working example

import plotly.express as px
import pandas as pd

geojson = {
    "type": "FeatureCollection",
    "features": [
        {
            "id": "0",
            "type": "Feature",
            "properties": {},
            'geometry': {'type': 'LineString',
            'coordinates': [[26.4, 5.15], [22.41, 4.03], [19.47, 5.03], [16.01, 2.27], [14.48, 4.73], [15.44, 7.69], [13.95, 9.55], [15.47, 9.98], [14.5, 12.86], [4.37, 13.75], [3.61, 11.66], [1.02, 12.85], [0.37, 14.93], [3.64, 15.57], [4.27, 19.16], [12.0, 23.47], [14.14, 22.49], [15.86, 23.41], [23.84, 19.58], [23.89, 15.61], [23.02, 15.68], [21.94, 12.59], [23.81, 8.67], [24.57, 8.23], [23.89, 8.62], [24.19, 8.73], [24.54, 8.92], [25.07, 10.27], [25.79, 10.41], [26.75, 9.47], [31.35, 9.81], [32.07, 11.97], [33.21, 12.18], [33.97, 8.68], [32.95, 7.78], [35.3, 5.51], [31.88, 3.56], [26.4, 5.15]]},  # fmt: skip
            "bbox": [0.37, 2.27, 35.3, 23.47],
        }
    ],
    "bbox": [0.37, 2.27, 35.3, 23.47],
}

# implied this dataframe exists in the question
points = pd.DataFrame(
    {
        "y": [9.34, 19.9, 9.62, 11.32, 15.43, 17.72, 23.9],
        "x": [15.78, 10.93, 21.53, 20.55, 21.79, 20.48, 7.48],
        "blue": ["blue"] * 7,
    }
)

fig = px.scatter_geo(
    points,
    "y",
    "x",
    color="blue",
    labels={"poi": "Points of Interest"},
)
fig.update_geos(
    showcoastlines=True,
    coastlinecolor="Black",
    showland=True,
    landcolor="White",
    showocean=True,
    oceancolor="LightBlue",
    projection_scale=3,
)

# given coordinates of a polygon add another trace that are lines not points
fig.add_traces(
    px.scatter_geo(
        pd.DataFrame(
            geojson["features"][0]["geometry"]["coordinates"], columns=["x", "y"]
        ),
        "x",
        "y",
    )
    .update_traces(mode="lines", line_color="red")
    .data
)

Upvotes: 1

Related Questions