都道府県別の出生数・出生率を評価 総務省統計局データをPythonで加工 e-Stat with Python(4)

 このグラフは都道府県別の「人口千人あたりの出生率」を地図上に表示したものです。
 沖縄が突出しています。全体的に見ると北日本は低い傾向、大都市圏や中国・九州地方は高めです。

 Next, I will show the plot of the map of Japanese prefectures by each prefecture birth number and birth rate per one thouzand peole.

 e-Statの「Search for field(分野から探す)」のfrom population and household(人口・世帯) 'Population move survey'(人口動態調査)をselectし、birth(出生)のyearlyのDataBaseから「each prefecture yearly birth number and birth rate(都道府県別にみた年次別出生数・出生率)のDataBaseにaccessします。statsDataIdは0003411597です。

 the libraries need to be import are below.

# Import the required libralies
!pip install geopandas
import geopandas as gpd
import pathlib
import requests
import pandas as pd
import matplotlib.pyplot as plt
!pip install mapclassify
import mapclassify

#matplotlibで日本語を表示するためのおまじない
!pip install japanize_matplotlib
import japanize_matplotlib

 In this time, three typical function was defined. Please see below code.

 The first function called 'fn_create_jp_pref_map' . This function icreate the map of every prefectures in japan from Land Numerical Information by Japan Gov.

#Import the required libralies
#!pip install geopandas
#import geopandas as gpd
#import pathlib

#都道府県別日本地図のGeoDataFrameを作成する関数japan_pref_map()を定義
# Define the function  'japana_pref_map()' which create the Japanese map including each prefecture Geo data
def fn_creat_jp_pref_map():

# Create the data saving directory
#    NOTEBOOK_PATH = pathlib.Path().resolve()
#    DATA_DIRECTORY = NOTEBOOK_PATH / "data"

# Download the Japan Map Data at Zip style
# Sorce: National Land Numerical Information released by MILT
    JapanMap_url = 'https://nlftp.mlit.go.jp/ksj/gml/data/N03/N03-2023/N03-20230101_GML.zip'
    # From Country Lands Numerical Infomation System by Japanese Gavornment
    gdf_jp = gpd.read_file(JapanMap_url, encoding='shift-jis')

#    jp_gdf.head()

# Concentrate each prefecture from many city's geometry
# pref_gdf = jp_gdf.dissolve("N03_001") #ERROR CODE
# japan_gdfをN03_001列(都道府県名)でグループ化して、各都道府県のジオメトリを結合する
    gdf_jp_pref = gdf_jp.dissolve("N03_001", aggfunc='first')

# reset_index()を使って元の "N03_001" 列を新しい列として復元する
    gdf_jp_pref = gdf_jp_pref.reset_index()

#CRSを(EPSG:6690)に変換
    gdf_jp_pref_EPSG6690 = gdf_jp_pref.to_crs("EPSG:6690")

#都道府県ごとに面積を計算し、GeoDataFrameに追加
    gdf_jp_pref_EPSG6690["面積(m2)"] = gdf_jp_pref_EPSG6690.area

#    print(gdf_japan)
#    print(gdf_jp_pref_EPSG6690)

    return gdf_jp_pref_EPSG6690

#gdf_jp_pref = fn_creat_jp_pref_map()

 The second function is called 'fn_get_estat_data'.This function get the required data from e-Stat.

# Import the required libralies
#import requests
#import pandas as pd

def fn_get_estat_data(APP_ID, API_URL, statsDataId, cdTime, column_rename, tree):
# e-Stat APIから指定されたDataBaseを取得してPandasDataFrameに変換し、
# column_nameを置き換えて、SourceCodeにReturnするFunction'fn_get_e-stat_data'

    params = {
        "appId": APP_ID,
        "statsDataId": statsDataId, #人口推計-総務省-都道府県、男女別人口(総人口、日本人人口)のstatDataID
        "lang": "J",  # Order Japanese
        "cdTime": cdTime # Subjected year Order 2021
    }

#人口推計の当該DataをDownLoad
    response = requests.get(API_URL, params=params)

# Process the response
    data = response.json()

# Exchange JSON Data to Pandas DataFrame
# Please consider the risk when eval() function is used
    df = pd.DataFrame(eval('data' + tree))
#    df = pd.DataFrame(data['GET_STATS_DATA']['STATISTICAL_DATA']['DATA_INF']['VALUE'])

    df.rename(columns=column_rename, inplace=True)
# 'inplace=True' is mean that the column names of the original DataFrame is changed
# if 'inplace=False' is orded, a new DataFrame would be created

    return df
#    人口推計-総務省-都道府県、男女別人口(総人口、日本人人口)の場合、
#    287行のデータが存在しており、全国+都道府県=48で割ると6setのデータがある。
#    このうち総人口の男女計は分類@cat01=000,@cat02=001が該当している模様
#    e-StatのDataViewにて代表的な数値の合致で確認
    #ちなみに末尾の@cat01=002, @cat02=002は日本人の女性人口

 The last function is called 'fn_create_color_map' . This function create the color map based on some prefectural data(values)

# 都道府県別のColorBarMapを図化するfn_create_color_map()関数を作成
def fn_create_color_map(gdf_jp_pref, style, data_column, size):

    ax = gdf_jp_pref.plot(
        figsize=size,
        column=data_column,
        cmap=map_style,
        markersize=15,
        legend=False
)

# カラーバーの作成
    sm = plt.cm.ScalarMappable(cmap=map_style)
    sm.set_array(gdf_jp_pref[data_column])
    cbar = plt.colorbar(sm, ax=ax, shrink=0.7, location='right', pad=-0.2, fraction=0.1)
# Below cbar parameters
# 'shrink' is color bar size
# 'locatioin' is color bar location(ex. 'upper right', 'horizontal etc.)
# 'pad' is color bar relative position for graph
# 'fraction' is the division rate of colorbar(ex. fraction=0.1 is 10% division)

# Graph TitleをSet
    ax.set_title("都道府県別 " + data_column)

    plt.show()

    return

####################

# Main Code Description

#map_style = 'cool'
#data_column = "森林率(%)"
#size = (10,10)

#fn_create_color_map(gdf_jp_pref, map_style, data_column, size)

 Finally we are ready to show the color map about the birth number and birth rate of each prefecture.

Using above functions, we get the birth number and birth rate as DataFrame below codes. In below codes, we add the eace prefecture name to DataFrame.

################################################
#国土数値情報から日本都道府県地図のGISDataをGet
################################################

gdf_jp_pref = fn_creat_jp_pref_map()

################################
# e-StatAPIからRequiredDataをGet
################################

# e-StatAPIのDataBaseが格納されているURL
API_URL = "http://api.e-stat.go.jp/rest/3.0/app/json/getStatsData"

# e-StatDataID(対象DataBaseに固有のID
statsDataId = "0003411597"

# 対象期間
cdTime = "2021000000"

# Processing Pandas data and change the column name
column_rename = {
    '@tab': 'DataType',
#    '@cat01': '性別(000:男女計,001:男性,002:女性)',
#    '@cat02': '001:総人口, 002:日本人人口',
    '@area': '都道府県コード',
    '@time': '対象年',
    '@unit': '単位',
    '$': '出生数(人)'
}

tree = "['GET_STATS_DATA']['STATISTICAL_DATA']['DATA_INF']['VALUE']"

df = fn_get_estat_data(APP_ID, API_URL, statsDataId, cdTime, column_rename, tree)

df.head()

##########################################
# 都道府県コードを都道府県の名称に置き換え
##########################################

#Dataの構造が格納されているMetaInfoを取得
API_URL = "http://api.e-stat.go.jp/rest/3.0/app/json/getMetaInfo?"

params = {
    "appId": APP_ID,
    "statsDataId": statsDataId,
    "limit": 2,
    "lang": "J"  # 日本語を指定
}

response = requests.get(API_URL, params=params)
data = response.json()
data

#辞書の構造を表示
#import pprint
#pprint.pprint(data)

# META_INFOの中から都道府県コードと都道府県名を対比している箇所を取得
values = data['GET_META_INFO']['METADATA_INF']['CLASS_INF']['CLASS_OBJ']
#pprint.pprint(values)

#type(values) #CLASS_OBJにはlist形式でデータが格納されていることを確認

for dictionary in values:
#    print('dictionary = ', dictionary)
    if dictionary['@id'] == 'area':
        pref_list = dictionary['CLASS']

prefectures_list = {}
for pref_code in pref_list:
#    print(pref_code)
    prefectures_list[pref_code['@code']] = pref_code['@name']

#print('prefecture_list = ', prefectures_list)

# 先ほど作成した辞書を使用して、都道府県コードに基づき、
# 都道府県名の列を追加するための関数を定義
def replace_pref_name(pref_code):
    return prefectures_list.get(pref_code, None)

# 都道府県コード列を都道府県名列に置き換え
df["都道府県"] = df["都道府県コード"].apply(replace_pref_name)

print(df)

 Next step, we draw the color map for the birth number and birth rate. I use the 'RdYlBu' type color map as birth number map, and 'coolwarm' type as birth rate map

# Select the requirede data from DataFrame'df'
# Ex. 'total of meil and femeil : code=000' and 'total population(Janapese + foreigner) : code=001'
df_birth = df[df['DataType']=='10040']
df_birth_rate = df[df['DataType']=='10050']

#print(df_total_pop)

# Give the each sex population data to gdf_jp_pref
for index, row in df_birth.iterrows():
    gdf_jp_pref.loc[gdf_jp_pref['N03_001'] == row["都道府県"], "出生数(人)"] = row["出生数(人)"]

for index, row in df_birth_rate.iterrows():
    gdf_jp_pref.loc[gdf_jp_pref['N03_001'] == row["都道府県"], "出生率(人口千人あたり)"] = row["出生数(人)"]

gdf_jp_pref["出生数(人)"] = gdf_jp_pref["出生数(人)"].astype(float)
gdf_jp_pref["出生率(人口千人あたり)"] = gdf_jp_pref["出生率(人口千人あたり)"].astype(float)

#gdf_jp_pref["外国人人口(千人)"] = gdf_jp_pref["総人口(千人)"] - gdf_jp_pref["日本人人口(千人)"]

gdf_jp_pref.head()

# Show the plot of results

map_style = 'RdYlBu'
data_column = "出生数(人)"
size = (10,10)

fn_create_color_map(gdf_jp_pref, map_style, data_column, size)


map_style = 'coolwarm'
data_column = "出生率(人口千人あたり)"
size = (10,10)

fn_create_color_map(gdf_jp_pref, map_style, data_column, size)

 Show the results of the color map.



 At last, I show the plot of the barth rate by horizontal bar graph. Especially, I try to use the different color bar by the barth rate. Chat GPT tell me the way to plot the the different color bar by the band of the birth rate. 
#棒グラフの色を出生率のレンジごとで色分け

# Direct the range of the color
ranges = [7, 8, 9, 10]

# Classificate the datas by the range
def assign_color(birth_rate):
    if birth_rate>=10:
        return 'darkblue'
    elif birth_rate>=8:
        return 'blue'
    elif birth_rate>=6:
        return 'lightblue'
    else:
        return 'skyblue'

# Assign the color to the barth rates
colors = df_sorted_birth_rate['出生率(人口千人あたり)'].apply(assign_color)

# Make horizontal bar graph
fig, ax = plt.subplots(figsize=(10,20))
bars = ax.barh(df_sorted_birth_rate['N03_001'],
    df_sorted_birth_rate['出生率(人口千人あたり)'],
    color = colors)
ax.set_xlabel('出生率(人口千人あたり)')
ax.set_ylabel('都道府県')
ax.set_title('都道府県別 出生率(人口千人あたり)')

#ax.legend(['出生率(人口千人あたり)'])

# Set the customized legend
legend_labels = ['10以上', '8から10', '6から8', '4から6']
legend_colors = ['darkblue', 'blue', 'lightblue', 'skyblue']
custom_legend = [plt.Line2D([0], [0], color=color, label=label) for color, label in zip(legend_colors, legend_labels)]
ax.legend(handles=custom_legend, loc="upper right")

plt.tight_layout()
plt.show()


 改めて、沖縄県の出生率は突出して高いこと、東北地方から新潟県、茨城県あたりの出生率は比較的低いこと、東京都、愛知県、滋賀県、大阪府、岡山県、九州各県あたりは比較的高いことなどが見えてきます。
 北日本は低め、大都市圏と西日本が比較的高めかなぁ。。。
 四国地方だと、香川県が比較的高いですね。




コメント

このブログの人気の投稿

【完結】ランニング、お食事 2022年5月~2022年12月

ランニング、グルメ、ドライブ 2023年4月〜

ランニング、グルメ、クライム 2023年7月〜