Black Lives Matter. Please consider donating to Black Girls Code today.
Learn how to use COVID-19 data in open source Dash apps. Register for the Sept 23rd webinar with IQT!

City level map with mapbox

I am working with plotly maps and trying to implement it at city level which is not one of the default options. I followed the tutorial https://plot.ly/python/county-level-choropleth/

The layout is generated but my data is not getting populated. I think I know why that is happening but I am not sure. One the above link under data section, the lat lon of Montrel is mentioned. On my map I can see Montreal. Guessing that is a typo in the documentation. The data should instead be red_data and blue_data.

I checked the documentation of scattermapbox, trying to understand how to pass a list of cities? Do I have to pass lat lon for each of those cities? I have attached my sample code.

import pandas as pd
import numpy as np
import xlsxwriter as xw
import cufflinks as cf
import plotly
import plotly.offline as py
import plotly.graph_objs as go
import string
import json

cf.go_offline() # required to use plotly offline
py.init_notebook_mode() # graphs charts inline (IPython)

mapbox_access_token=‘pk.my_long_free_public_token’

with open(‘abc.json’, ‘r’) as f: #downloaded from http://catalog.opendata.city/dataset/new-york-cities-polygon
ny_data = json.load(f)

#get all cities in NY state
city_names = []
city_names_dict = {}
for city in ny_data[‘features’]:
city_names.append(city[‘properties’][‘name’][0:-3])
city_names_dict[city[‘properties’][‘name’][0:-3]] = city[‘properties’][‘name’]

#For test purpose, assigning first half as red and the other half as green
red_cities = city_names[len(city_names)/2:]
green_cities= city_names[:len(city_names)/2]

red_data = {“type”: “FeatureCollection”}
red_data[‘features’] = red_cities
green_data = {“type”: “FeatureCollection”}
green_data[‘features’] = green_cities

data = [go.Scattermapbox(lat=[‘45.5017’],lon=[’-73.5673’],mode=‘markers’)]

layers=[
dict(
sourcetype = ‘geojson’,
source = red_data,
type = ‘fill’,
color = ‘rgba(163,22,19,0.8)’
),
dict(
sourcetype = ‘geojson’,
source = green_data,
type = ‘fill’,
color = ‘rgba(40,0,113,0.8)’
)
]

layout = go.Layout(
height=600,
autosize=True,
hovermode=‘closest’,
mapbox=dict(
layers=layers,
accesstoken=mapbox_access_token,
bearing=0,
center=dict(lat=43.3,lon=-74.2),
pitch=0,
zoom=5.2,
style=‘light’
),
)

fig = dict(data=data, layout=layout)
py.iplot(fig, filename=‘city-level-choropleths-python’)

@sukhada.kulkarni This is a python question, change the category, please.

Your red_data and green_data should be dicts having the same structure as a geojson file, but
your dicts don’t have that structure. Each subdict

red_data['features'][k] 

in the list red_data['features'] is lacking the key ‘geometry’.
You copied from the json file only the ‘properties’ information.

1 Like

Awesome, thank you. I was using geoJson data for the first time, it took a while to understand the data structure. Another question here, I see the actual is data is defined in layers element and not data element. This is how I defined my data elements:
data = [go.Scattermapbox()]

This takes away the ability to add hover option as the actual data is not passed there and it won’t let me allow hovertext in layers. Overall, seems complicated with many element, functions, options.