Input file downloaded manually from https://trends.google.com/ because of API rate limits.
import pandas as pd
df_eclipse_2024 = pd.read_csv('geoMap_eclipse_2024.csv',skiprows=0)
df_eclipse_2024
| Zone | volume | |
|---|---|---|
| 0 | Burlington VT-Plattsburgh NY | 100 |
| 1 | Presque Isle ME | 96 |
| 2 | Paducah KY-Cape Girardeau MO-Harrisburg-Mount ... | 88 |
| 3 | Bangor ME | 85 |
| 4 | Portland-Auburn ME | 84 |
| ... | ... | ... |
| 205 | Seattle-Tacoma WA | 27 |
| 206 | Anchorage AK | 26 |
| 207 | Honolulu HI | 25 |
| 208 | Juneau AK | 23 |
| 209 | Fairbanks AK | 22 |
210 rows × 2 columns
Now we need to find the geographical area corresponding to every "Zone". Google Trends uses zones (Designated Market Areas = DMAs) that do not follow exactly US counties or particular administrative divisions. Somewhere through Kaggle I found a list of all US counties, with the DMA they belong to. I had to manually edit it because it switches Portland (Oregon) and Portland (Maine).
google_dma = pd.read_csv('GoogleTrends_CountyDMA_Mapping.csv')
google_dma
| STATE | COUNTY | STATEFP | CNTYFP | CNTYTVHH | DMAINDEX | DMA | GOOGLE_DMA | |
|---|---|---|---|---|---|---|---|---|
| 0 | AK | Anchorage Borough | 2 | 20 | 95010 | 156 | ANCHORAGE (AK) ... | Anchorage AK |
| 1 | AK | Kenai Peninsula Borough | 2 | 122 | 17600 | 156 | ANCHORAGE (AK) ... | Anchorage AK |
| 2 | AK | Matanuska-Susitna Borough | 2 | 170 | 20130 | 156 | ANCHORAGE (AK) ... | Anchorage AK |
| 3 | AK | Fairbanks North Star Borough | 2 | 90 | 31860 | 203 | FAIRBANKS (AK) ... | Fairbanks AK |
| 4 | AK | Juneau Borough | 2 | 110 | 25270 | 206 | JUNEAU (AK) ... | Juneau AK |
| ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 3115 | WY | Weston | 56 | 45 | 2460 | 175 | RAPID CITY (SD) ... | Rapid City SD |
| 3116 | WY | Lincoln | 56 | 23 | 5240 | 36 | SALT LAKE CITY (UT) ... | Salt Lake City UT |
| 3117 | WY | Sublette | 56 | 35 | 2260 | 36 | SALT LAKE CITY (UT) ... | Salt Lake City UT |
| 3118 | WY | Sweetwater | 56 | 37 | 13530 | 36 | SALT LAKE CITY (UT) ... | Salt Lake City UT |
| 3119 | WY | Uinta | 56 | 41 | 6800 | 36 | SALT LAKE CITY (UT) ... | Salt Lake City UT |
3120 rows × 8 columns
Every US county has a 5-digit FIPS code, whose first two digits represent the US state. In the above table, the numbers corresponding to the state and to the county are given in separate columns, so we merge them:
fips = [ str(google_dma['STATEFP'][iii]).zfill(2) + str(google_dma['CNTYFP'][iii]).zfill(3) for iii in range(len(google_dma)) ]
google_dma['fips'] = fips
google_dma
| STATE | COUNTY | STATEFP | CNTYFP | CNTYTVHH | DMAINDEX | DMA | GOOGLE_DMA | fips | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | AK | Anchorage Borough | 2 | 20 | 95010 | 156 | ANCHORAGE (AK) ... | Anchorage AK | 02020 |
| 1 | AK | Kenai Peninsula Borough | 2 | 122 | 17600 | 156 | ANCHORAGE (AK) ... | Anchorage AK | 02122 |
| 2 | AK | Matanuska-Susitna Borough | 2 | 170 | 20130 | 156 | ANCHORAGE (AK) ... | Anchorage AK | 02170 |
| 3 | AK | Fairbanks North Star Borough | 2 | 90 | 31860 | 203 | FAIRBANKS (AK) ... | Fairbanks AK | 02090 |
| 4 | AK | Juneau Borough | 2 | 110 | 25270 | 206 | JUNEAU (AK) ... | Juneau AK | 02110 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 3115 | WY | Weston | 56 | 45 | 2460 | 175 | RAPID CITY (SD) ... | Rapid City SD | 56045 |
| 3116 | WY | Lincoln | 56 | 23 | 5240 | 36 | SALT LAKE CITY (UT) ... | Salt Lake City UT | 56023 |
| 3117 | WY | Sublette | 56 | 35 | 2260 | 36 | SALT LAKE CITY (UT) ... | Salt Lake City UT | 56035 |
| 3118 | WY | Sweetwater | 56 | 37 | 13530 | 36 | SALT LAKE CITY (UT) ... | Salt Lake City UT | 56037 |
| 3119 | WY | Uinta | 56 | 41 | 6800 | 36 | SALT LAKE CITY (UT) ... | Salt Lake City UT | 56041 |
3120 rows × 9 columns
Now for each county we add the search volume in its DMA:
search_eclipse_2024 = []
for iii in range(len(google_dma)):
dma_here = google_dma['GOOGLE_DMA'][iii]
value_here = df_eclipse_2024['volume'][ df_eclipse_2024['Zone']==dma_here ]
try:
search_eclipse_2024.append( int(value_here) )
except:
search_eclipse_2024.append( None )
google_dma['eclipse_2024'] = search_eclipse_2024
We need to download the shape of each county.
Here we load a GeoJSON file containing the geometry information for US counties, given as a list of polygons, where feature.id is a FIPS code.
from urllib.request import urlopen
import json
with urlopen('https://raw.githubusercontent.com/plotly/datasets/master/geojson-counties-fips.json') as response:
counties = json.load(response)
And use this in a map. choropleth_mapbox displays it on top of a Mapbox map.
import plotly
plotly.offline.init_notebook_mode()
The last two lines are not necessary, but adding them allows you to save the notebook as a standalone HTML file via File --> Download Notebook as... --> Export Notebook to HTML.
import plotly.express as px
fig = px.choropleth_mapbox(google_dma, geojson=counties, locations='fips', color='eclipse_2024',
color_continuous_scale="Greys",
range_color=(20, 80),
mapbox_style="carto-positron", # use "white-bg" for blank
zoom=3, center = {"lat": 37.0902, "lon": -95.7129},
opacity=1.,
)
fig.update_layout(margin={"r":0,"t":0,"l":0,"b":0})
fig.show()
It can also be done on top of a world map, in any projection (see documentation https://plotly.github.io/plotly.py-docs/generated/plotly.express.choropleth.html). Using scope='usa' produces this view:
import plotly.express as px
fig = px.choropleth(google_dma, geojson=counties, locations='fips', color='eclipse_2024',
color_continuous_scale="Greys",
range_color=(20, 80),
scope='usa',
)
fig.update_layout(margin={"r":0,"t":0,"l":0,"b":0})
fig.show()
More examples at https://plotly.com/python/choropleth-maps/