Reputation: 832
I have two separate map plots, one is cultural boundaries in a country (just like the state borders) in the form of custom polygons based on latitude and longitude values, defined in geojson format. I can plot the polygons easily using geopandas:
states = gpd.read_file('myfile.geojson')
states.boundary.plot()
Here is a sample output:
The second is a series of latitudes and longitudes with corresponding values that I need to plot over a map layer, which I can do with plotly express's scatter_mapbox:
fig = px.scatter_mapbox(df_year,
lat='y', lon='x',
color='drought_index',
range_color=(-4, 4),
hover_data={'x': False, 'y': False},
zoom=5, height=800, width=1050,
center={'lat': 32.7089, 'lon': 53.6880},
color_continuous_scale=px.colors.diverging.RdYlGn,
color_continuous_midpoint=0,
)
fig.update_layout(mapbox_style="outdoors", mapbox_accesstoken=mb_token)
Which will look like this:
Is there any way to add these two plots together and have the scatter points and shape boundaries overlap on a single map? Meaning that on top of the mapbox layer, I have the scatter points and the boundaries of the polygons visible.
The problem is that geopandas plot uses matplotlib and returens AxesSubplot:, and I couldn't find any way to add this to the plotly fig. I tried the mpl_to_plotly() from plotly.tools, but it threw an exception on 'Canvas is null'.
I also tried to find a way to plot the geojson shapes with plotly, but all I could find was the choropleth mapbox which requires the shapes to be filled with a color. I tried to use it anyways by decreasing the opacity of the choropleth plot but it either will cover the scatter plot or be barely visible.
Any suggestion on how to approach this is appreciated.
Upvotes: 1
Views: 3794
Reputation: 31236
"source": json.loads(gdf.geometry.to_json()),
is really the solution to add a GEOJSON layer from a geopandas dataframeimport requests
import geopandas as gpd
import pandas as pd
import json, io
import plotly.express as px
# UK admin area boundaries
res = requests.get("https://opendata.arcgis.com/datasets/69dc11c7386943b4ad8893c45648b1e1_0.geojson")
# geopandas dataframe of "cultural layer"
gdf = gpd.GeoDataFrame.from_features(res.json()["features"], crs="CRS84")
# get some public addressess - hospitals. data that can be scattered
dfhos = pd.read_csv(io.StringIO(requests.get("http://media.nhschoices.nhs.uk/data/foi/Hospital.csv").text),
sep="¬",engine="python",)
fig = (
px.scatter_mapbox(
dfhos.head(100),
lat="Latitude",
lon="Longitude",
color="Sector",
hover_data=["OrganisationName", "Postcode"],
)
.update_traces(marker={"size": 10})
.update_layout(
mapbox={
"style": "open-street-map",
"zoom": 5,
"layers": [
{
"source": json.loads(gdf.geometry.to_json()),
"below": "traces",
"type": "line",
"color": "purple",
"line": {"width": 1.5},
}
],
},
margin={"l": 0, "r": 0, "t": 0, "b": 0},
)
)
fig.show()
Upvotes: 3