How to center plotly scatter_geo to a specific country in python - python

I use the scatter_geo function from plotly.express to plot geographical data on a map.
import geopandas as gpd
import plotly.express as px
fig = px.scatter_geo(gdf,
lat = 'latitude',
lon = 'longitude',
geojson='geometry',
scope='europe',
animation_frame = 'year')
fig.show()
How can I archive that the map is centered to only one country, in my case Germany? The parameter scope accepted only continents. There are two more parameters, center and fitbounds, that sounds useful, but I don't understand to fill in the right value.
center (dict) – Dict keys are 'lat' and 'lon' Sets the center point of
the map.
fitbounds (str (default False).) – One of False, locations or geojson.
Dummie data:
geometry latitude longitude value year
0 POINT (13.72740 51.05570) 51.0557 13.7274 35.55 1838
1 POINT (13.72740 51.05570) 51.0557 13.7274 35.15 1842

There are two ways to specify a specific latitude and longitude: by writing it directly or by adding it in a layout update. Adding it via layout update is more flexible and adjustable. For the scope, select Europe to draw the area by country. To zoom in on the map, use projection_scalse instead of zoom. I was not sure about the center of Germany so I used the data you presented, please change it.
fig = px.scatter_geo(gdf,
lat = 'latitude',
lon = 'longitude',
geojson='geometry',
scope='europe',
center=dict(lat=51.0057, lon=13.7274),
animation_frame = 'year')
Update layout
import plotly.express as px
df = px.data.gapminder().query("year == 2007")
fig = px.scatter_geo(df,
locations="iso_alpha",
size="pop",
projection="natural earth"
)
fig.update_layout(
autosize=True,
height=600,
geo=dict(
center=dict(
lat=51.0057,
lon=13.7274
),
scope='europe',
projection_scale=6
)
)
fig.show()

Related

How to add static text in map using Plotly Choropleth Python

I am plotting a map using plotly express and geojson file.I want to show static values on the individual district. Currently those values are visible on hover, but I want the values to be seen all the time even without hovering on it.
This is my code:
import json
import pandas as pd
import numpy as np
import plotly.express as px
import plotly.io as pio
x = json.load(open("./odisha_disticts.geojson","r"))
user_data = []
for i in range(len(x['features'])):
d = x['features'][i]['properties']
d['Females'] = np.random.randint(0,100,1)[0]
user_data.append(d)
df = pd.DataFrame(user_data)
df.head()
ID_2 NAME_2 Females
0 16084 Angul 19
1 16085 Baleshwar 45
2 16086 Baragarh 52
3 16087 Bhadrak 81
4 16088 Bolangir 49
fig = px.choropleth(
df,
locations="ID_2",
featureidkey="properties.ID_2",
geojson=x,
color="Females"
)
fig.update_geos(fitbounds="locations", visible=False)
px.scatter_geo(
df,
geojson=x,
featureidkey="properties.NAME_2",
locations="District",
text = df["District"]
)
fig.show()
The link to required files is HERE
To annotate on a map, use a graph_object to go.Choroplethmapbox with go.Scattermapbox with textmode. As a preparation before creating the graph, we need the latitude and longitude for the annotation, so we use geopandas to read the geojson file and find the center of geometry. A warning is displayed at this point because the loaded geometry uses an inappropriate geodetic system to calculate the center. If you have a latitude and longitude you wish to use for your annotations use it. There are two caveats in creating the map: first, you will need the free Mapbox API token. Get it here. second, in go.Scattemapbox(), the mode is text + marker, but if you use text only, an error will occur. The reason is unknown.
import geopandas as gpd
import pandas as pd
import plotly.graph_objects as go
# read your data
data = pd.read_csv('./data.csv', index_col=0)
# read geojson
x = json.load(open("./odisha_disticts.geojson","r"))
gdf = gpd.read_file('./odisha_disticts.geojson')
gdf['centroid'] = gdf['geometry'].centroid
gdf['lon'] = gdf['centroid'].map(lambda p:p.x)
gdf['lat'] = gdf['centroid'].map(lambda p:p.y)
gdf.head()
ID_2 NAME_2 geometry centroid lon lat
0 16084 Angul POLYGON ((85.38891 21.17916, 85.31440 21.15510... POINT (84.90419 20.98316) 84.904186 20.983160
1 16085 Baleshwar POLYGON ((87.43902 21.76406, 87.47124 21.70760... POINT (86.90547 21.48738) 86.905470 21.487376
2 16086 Baragarh POLYGON ((83.79293 21.56323, 83.84026 21.52344... POINT (83.34884 21.22068) 83.348838 21.220683
3 16087 Bhadrak POLYGON ((86.82882 21.20137, 86.82379 21.13752... POINT (86.61598 20.97818) 86.615981 20.978183
4 16088 Bolangir POLYGON ((83.45259 21.05145, 83.44352 21.01535... POINT (83.16839 20.58812) 83.168393 20.588121
import plotly.express as px
import plotly.graph_objects as go
mapbox_token = open("mapbox_api_key.txt").read()
fig = go.Figure()
fig.add_trace(go.Scattermapbox(lat=gdf['lat'],
lon=gdf['lon'],
mode='text+markers',
textposition='top center',
text = [str(x) for x in data["District"]],
textfont=dict(color='blue')
))
fig.add_trace(go.Choroplethmapbox(geojson=x,
locations=data['id'],
z=data['Females'],
featureidkey="properties.ID_2",
colorscale='Reds',
zmin=0,
zmax=data['Females'].max(),
marker_opacity=0.8,
marker_line_width=0
)
)
fig.update_layout(height=600,
mapbox=dict(
center={"lat": gdf['lat'].mean(), "lon": gdf['lon'].mean()},
accesstoken=mapbox_token,
zoom=5.5,
style="light"
))
fig.show()

Adding points to pyplot choropeth map

I have created a choropleth map in python with pyplot on US census data. Now I want to add points to this map denoting the location of towns using longitude and latitude. My code below successfully renders the choropleth but not the points on top
fig1 = px.choropleth(population, locations=population['StateAbbr'], locationmode='USA-states',
color='per1910',color_continuous_scale='inferno',
range_color=(0, .15),scope='usa',labels={'StateAbbr':'per1910'},hover_name='StateAbbr',)
go.Figure(data=go.Scattergeo(
lon = champs['Lon'],
lat = champs['Lat'],
text = champs['School'],
mode = 'markers',
marker_color = 'blue',
))
fig1.update_layout(title_text = 'Census: 1910 Championships: 1872-1915')
fig1.show()

How to draw bounderies between countries and countries' states on pyplot.go.Figure with go.Scattergeo

So, I am doing a map that shows the flow of people among some cities in Brazil by drawing lines on the map, representing the path, and setting its opacity according to the count of occurrences. To do so, I am following this code (third map, the one about flights on US).
My question is, can I draw the borders between countries? And, if possible, also between Brazilian states?
In the documentation, there is an argument of the function called "geojson", but I'am not sure on how to use it, or if it is even useful for me.
Note that I have GeoJSON data for both countries and states.
Here's the code to generate the my map:
import pandas as pd
import plotly.graph_objects as go
fig = go.Figure()
for i in range(len(my_df)):
fig.add_trace(
go.Scattergeo(
lon = [my_df['res_longitude'][i], my_df['nasc_longitude'][i]],
lat = [my_df['res_latitude'][i], my_df['nasc_latitude'][i]],
mode = 'lines',
line = dict(width = 1,color = 'red'),
opacity = min(1, float(my_df['flow'][i]) / float(my_df['flow'].quantile(.95))),
)
)
fig.update_layout(
showlegend = False,
margin ={'l':0,'t':0,'b':0,'r':0},
mapbox = {
'center': {'lon': -50.3206, 'lat': -16.4984},
'style': "stamen-terrain",
'zoom': 3}
)
and here's the result:
Since I don't have the geojson data and the latitude and longitude information to draw the line, I'll use the official reference you referenced to answer your question.
Using the choropleth map, add a sum column with 0 to the data used in this sample.
Specify the geojson you obtained to geojson=usa_geo.
We associate the geojson state name with the state in the data.
I set the map fill to a light gray.
Note: The center setting of the map is automatically calculated since we are using fitbounds for the location.
from urllib import request
import json
import pandas as pd
import plotly.graph_objects as go
import plotly.express as px
# usa geojson data
# https://eric.clst.org/tech/usgeojson/
usa_json = open('./data/gz_2010_us_040_00_500k.json', 'r')
usa_geo = json.load(usa_json)
# Choropleth Maps with go.Choropleth
# https://plotly.com/python/choropleth-maps/
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/2011_us_ag_exports.csv')
# https://plotly.com/python/lines-on-maps/
df_flight_paths = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/2011_february_aa_flight_paths.csv')
# dummy data column
dfs = pd.concat([df, pd.Series([0]*len(df),name='count')], axis=1)
fig = go.Figure()
fig.add_trace(go.Choropleth(
geojson=usa_geo,
locations=df['state'],
z = dfs['count'].astype(float),
featureidkey='properties.NAME',
colorscale = [[0,'rgb(200, 200, 200)']],
showlegend=False,
coloraxis=None,
colorbar=None
))
fig.update_traces(showscale=False)
flight_paths = []
for i in range(len(df_flight_paths)):
fig.add_trace(
go.Scattergeo(
#locationmode = 'USA-states',
lon = [df_flight_paths['start_lon'][i], df_flight_paths['end_lon'][i]],
lat = [df_flight_paths['start_lat'][i], df_flight_paths['end_lat'][i]],
mode = 'lines',
line = dict(width = 1,color = 'red'),
opacity = float(df_flight_paths['cnt'][i]) / float(df_flight_paths['cnt'].max()),
showlegend=False
)
)
fig.update_layout(
autosize=False,
width=1000,
height=600,
margin={"r":0,"t":0,"l":0,"b":0},
geo=dict(
scope='north america', # you chenge 'south america'
fitbounds="locations", # It is associated width 'px.Choropleth'
visible=True,
showland=True,
#center=dict(lon=34.05795, lat=-179.25450),
# The center designation of the map has no effect as this is automatically calculated
)
)
fig.show()

plotly graph object colors to similar

I try to plot values using plotly graph objects, and use one column to set the color.
fig_1.add_trace(
go.Scattermapbox(
lat=data.latitude,
lon=data.longitude,
marker=go.scattermapbox.Marker(size=9, color=data.id_nr),
)
)
However, the values are very high numbers (id numbers, int64) and thereby, id numbers which are closer to each other (100k different rather than 1M) will appear almost as the same color.
Is there a way to set the colours as discrete colours? using
... color=data.id_nr.astype(str)
as used in Plotly express to make the coolers discrete does not work.
Invalid element(s) received for the 'color' property of
scattermapbox.marker
The basic question is: Can you set the colors that each value, however how close or distanced the delta is, gets a unique color?
EDIT:
The id values are more like:
id=[1,2,5,100004,100007,100009]
In combination with continuous coloring by plotly, the first three and the last three are kind of identically in color.
Plotly express solves this with changing the int values (of id) to strings, making them discrete.
EDIT2 :
A solution would be to separate the data by ID Then add a trace for each ID. However, this is not ..."sexy" and I would rather know a solution with plotly handling the colors discretely.
I recreated the data and created the code by adapting the example from the official reference to your assignment. The format of the data is a data frame with three columns: id column, latitude and longitude, and location name. In the definition of the marker, I used the id column to define the color, and specified 'Viridis' as the color scale, which is a continuous color map. See this for a concrete example of introducing a color scale in a scatter plot.
import pandas as pd
import plotly.express as px
lat = [38.91427,38.91538,38.91458,38.92239,38.93222,38.90842,38.91931,38.93260,38.91368,38.88516,38.921894,38.93206, 38.91275]
lon = [-77.02827,-77.02013,-77.03155,-77.04227,-77.02854,-77.02419,-77.02518,-77.03304,-77.04509,-76.99656,-77.042438,-77.02821,-77.01239]
name = ["The coffee bar","Bistro Bohem","Black Cat", "Snap","Columbia Heights Coffee","Azi's Cafe", "Blind Dog Cafe","Le Caprice","Filter","Peregrine","Tryst","The Coupe","Big Bear Cafe"]
ids = [1,2,3,4,5001,5002,5003,5004,100004,100007,100009,100010,100011]
colors = px.colors.qualitative.Alphabet[:len(lat)]
df = pd.DataFrame({'id':ids, 'lat':lat,'lon':lon,'name':name,'colors': colors})
df.head()
id lat lon name colors
0 1 38.91427 -77.02827 The coffee bar #AA0DFE
1 2 38.91538 -77.02013 Bistro Bohem #3283FE
2 3 38.91458 -77.03155 Black Cat #85660D
3 4 38.92239 -77.04227 Snap #782AB6
4 5001 38.93222 -77.02854 Columbia Heights Coffee #565656
import plotly.graph_objects as go
mapbox_access_token = open("mapbox_api_key.txt").read()
fig = go.Figure(go.Scattermapbox(
lat=df['lat'],
lon=df['lon'],
mode='markers',
marker=go.scattermapbox.Marker(
size=16,
color=df['colors'],
#colorscale='Viridis'
),
text=df['name'],
))
fig.update_layout(
autosize=False,
width=1000,
height=500,
hovermode='closest',
mapbox=dict(
accesstoken=mapbox_access_token,
bearing=0,
center=dict(
lat=38.92,
lon=-77.07
),
pitch=0,
zoom=11
),
)
fig.show()

Plotly: How to set colorbar position for a choropleth map?

I can't find anything in the documentation about controlling where to place the colorbar, just whether or not it should be shown and with what color scale, etc. Can this be done?
If it helps, I am implementing my choropleth map with Dash.
The answer:
fig.data[0].colorbar.x=-0.1
or:
fig.update_layout(coloraxis_colorbar_x=-0.1)
Some details:
You haven't provided any code so I'll refer to an example from the docs where the position of the colorbar along the x-axis defaults to 1.2. You can change this directly through, for example:
fig.data[0].colorbar.x=-0.1
And get:
Complete code:
import plotly.graph_objects as go
import pandas as pd
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/2011_us_ag_exports.csv')
fig = go.Figure(data=go.Choropleth(
locations=df['code'], # Spatial coordinates
z = df['total exports'].astype(float), # Data to be color-coded
locationmode = 'USA-states', # set of locations match entries in `locations`
colorscale = 'Reds',
colorbar_title = "Millions USD",
))
fig.update_layout(
title_text = '2011 US Agriculture Exports by State',
geo_scope='usa', # limite map scope to USA
)
fig.data[0].colorbar.x=-0.1
fig.show()

Categories