How to use plotly and geopandas to draw a map of the United States according to the US zip code (Zip-Code)

For myself, this requirement comes from analyzing the user data of the Movielens-1m dataset:

UserID::Gender::Age::Occupation::Zip-code
1::F::1::10::48067
2::M::56::16::70072
3::M::25::15::55117
4::M::45::7::02460
5::M::25::20::55455
6::F::50::9::55117

I want to calculate the state where the user is based on the Zip-code, and then display the number of users in each state on the map.

Then the code should be written like this:

import pandas as pd
import geopandas as gpd
import plotly.express as px
from uszipcode import SearchEngine

# 创建 SearchEngine 实例
search = SearchEngine()

# 读取用户数据集
data = pd.read_csv('./users.dat', sep='::', engine='python',
                   names=['UserID', 'Gender', 'Age', 'Occupation', 'Zip-code'])
data = data.dropna(subset=['Zip-code'])

def get_state_name(zipcode):
    result = search.by_zipcode(zipcode)
    if result is None:
        return None
    else:
        state_abbr = result.state
        return state_abbr
data['STATE_ABBR'] = data['Zip-code'].apply(get_state_name)

# 计算每个Zip-code的用户数量
zip_counts = data['STATE_ABBR'].value_counts()
zip_counts_df = zip_counts.reset_index() # 将Series转换为DataFrame
zip_counts_df.columns = ['STATE_ABBR', 'COUNT'] # 重新命名列

# 读取美国地图的shapefile
usa_map = gpd.read_file('./shapefile/USA_States.shp')

# 将Zip-code数据与地图数据进行合并
# 简称合并使用STATE_ABBR,全称合并使用STATE_NAME
zip_geo = pd.merge(usa_map, zip_counts_df, on='STATE_ABBR')

# 绘制地图
fig = px.choropleth(zip_geo,
                    locations='STATE_ABBR',
                    locationmode='USA-states',
                    color='COUNT',
                    scope='usa',
                    hover_data=['COUNT'],
                    color_continuous_scale='Reds',
                    range_color=(0, zip_geo['COUNT'].max()),
                    labels={
    
    'STATE_ABBR': 'User Count'})
fig.update_layout(title_text='Movielens User Distribution by State')
fig.show()

In the code above, USA_States.shpit can be downloaded at efrainmaps (https://www.efrainmaps.es/english-version/free-downloads/united-states/).

The effect is as follows, when the mouse hovers over a state, the name of the state and the corresponding number of users can be displayed:

insert image description here

If you don't want to display the abbreviation of the state, you can create a mapping between the abbreviation and the full name of the state, then map the Zip-code to the full name of the state, and then display the map:

# 创建州的简称与全称的映射
# 该映射字典涵盖了50个州、哥伦比亚特区、5个美国领土以及3个军邮邮编简称。
state_name_dict = {
    
    
    "AL": "Alabama",
    "AK": "Alaska",
    "AZ": "Arizona",
    "AR": "Arkansas",
    "CA": "California",
    "CO": "Colorado",
    "CT": "Connecticut",
    "DE": "Delaware",
    "FL": "Florida",
    "GA": "Georgia",
    "HI": "Hawaii",
    "ID": "Idaho",
    "IL": "Illinois",
    "IN": "Indiana",
    "IA": "Iowa",
    "KS": "Kansas",
    "KY": "Kentucky",
    "LA": "Louisiana",
    "ME": "Maine",
    "MD": "Maryland",
    "MA": "Massachusetts",
    "MI": "Michigan",
    "MN": "Minnesota",
    "MS": "Mississippi",
    "MO": "Missouri",
    "MT": "Montana",
    "NE": "Nebraska",
    "NV": "Nevada",
    "NH": "New Hampshire",
    "NJ": "New Jersey",
    "NM": "New Mexico",
    "NY": "New York",
    "NC": "North Carolina",
    "ND": "North Dakota",
    "OH": "Ohio",
    "OK": "Oklahoma",
    "OR": "Oregon",
    "PA": "Pennsylvania",
    "RI": "Rhode Island",
    "SC": "South Carolina",
    "SD": "South Dakota",
    "TN": "Tennessee",
    "TX": "Texas",
    "UT": "Utah",
    "VT": "Vermont",
    "VA": "Virginia",
    "WA": "Washington",
    "WV": "West Virginia",
    "WI": "Wisconsin",
    "WY": "Wyoming",
    "DC": "District of Columbia",
    "AS": "American Samoa",
    "GU": "Guam",
    "MP": "Northern Mariana Islands",
    "PR": "Puerto Rico",
    "UM": "United States Minor Outlying Islands",
    "VI": "Virgin Islands",
    "AA": "Armed Forces Americas",
    "AE": "Armed Forces Europe",
    "AP": "Armed Forces Pacific"
}

def get_state_name(zipcode):
    result = search.by_zipcode(zipcode)
    if result is None:
        return None
    else:
        state_abbr = result.state
        state_name = state_name_dict.get(state_abbr, None)
        return state_name
data['STATE_NAME'] = data['Zip-code'].apply(get_state_name)
# 后续代码同上,注意要将STATE_ABBR替换为STATE_NAME

Guess you like

Origin blog.csdn.net/baishuiniyaonulia/article/details/131848297