Google search volumes for 2024 solar eclipse¶

Input file downloaded manually from https://trends.google.com/ because of API rate limits.

In [3]:
import pandas as pd

df_eclipse_2024 = pd.read_csv('geoMap_eclipse_2024.csv',skiprows=0)
df_eclipse_2024
Out[3]:
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).

In [4]:
google_dma = pd.read_csv('GoogleTrends_CountyDMA_Mapping.csv')
google_dma
Out[4]:
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:

In [5]:
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
Out[5]:
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:

In [6]:
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.

In [8]:
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.

In [ ]:
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.

In [36]:
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:

In [37]:
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/