ラベル matplotlib の投稿を表示しています。 すべての投稿を表示
ラベル matplotlib の投稿を表示しています。 すべての投稿を表示

2025年6月18日水曜日

NBA選手シーズンごとの平均リバウンド

NBA選手のシーズン当たりのリバウンド

シーズン毎の得点に続き、シーズン毎のリバウンドを可視化してみます。

外れ値を省くために、1シーズン40試合以上出場した選手で構成しています。

#! /usr/bin/env python

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

sns.set()

fn = "data/player_per_game.csv"
df = pd.read_csv(fn)

df2 = df[df["g"] >= 40] 

desc = df2.groupby("season")["TRB"].describe()
print(desc)

count mean std min 25% 50% 75% max
season
1951 108.0 4.960185 2.849986 1.3 2.900 4.35 6.525 16.4
1952 94.0 5.255319 3.140770 1.0 2.925 4.55 6.950 13.5
1953 102.0 5.138235 3.093143 0.9 3.000 4.25 6.875 14.4
1954 91.0 5.126374 3.164871 0.9 2.800 4.30 6.900 15.3
1955 81.0 5.669136 3.186952 1.2 3.400 4.60 7.600 15.1
1956 80.0 5.626250 3.401479 0.9 3.175 4.45 7.650 16.3
1957 83.0 5.906024 3.658580 1.8 3.400 4.60 8.050 19.6
1958 78.0 6.698718 4.116217 1.7 3.850 5.50 9.550 22.7
1959 85.0 6.207059 3.708510 1.8 3.600 5.30 7.900 23.0
1960 87.0 6.686207 4.410774 1.8 3.800 5.30 8.450 27.0
1961 83.0 6.719277 4.765052 1.2 3.750 5.70 8.200 27.2
1962 100.0 6.430000 4.680488 0.4 3.025 5.80 8.050 25.7
1963 94.0 6.020213 4.181155 0.9 3.000 5.15 7.175 24.3
1964 102.0 5.810784 4.364481 1.1 2.925 4.45 7.350 24.7
1965 94.0 6.128723 4.669637 1.0 2.725 4.75 8.050 24.1
1966 103.0 6.262136 4.472599 1.3 3.200 5.20 7.800 24.6
1967 108.0 6.163889 4.304040 1.1 3.300 5.15 7.650 24.2
1968 136.0 5.927206 4.252833 0.5 2.800 4.70 7.625 23.8
1969 146.0 6.357534 4.192914 0.9 3.500 4.85 8.800 21.1
1970 154.0 5.625974 3.667144 0.9 3.025 4.50 7.475 17.7
1971 181.0 5.475138 3.671193 0.5 3.000 4.50 7.000 18.2
1972 189.0 5.408466 3.859353 0.4 2.800 4.10 6.900 19.2
1973 194.0 5.215464 3.676542 0.8 2.600 4.15 6.450 18.6
1974 184.0 4.972283 3.410149 0.7 2.700 4.00 6.225 18.1
1975 210.0 4.678095 3.153868 0.6 2.200 3.90 6.175 14.8
1976 199.0 4.830151 3.142201 0.6 2.600 4.00 6.250 16.9
1977 260.0 4.676923 3.061885 0.6 2.475 3.80 6.400 14.4
1978 259.0 4.747490 3.039906 0.8 2.600 3.60 6.550 15.7
1979 247.0 4.559514 3.029057 0.8 2.300 3.60 6.050 17.6
1980 248.0 4.656048 2.829866 0.7 2.375 4.00 6.425 15.0
1981 262.0 4.246947 2.670696 0.7 2.100 3.60 5.875 14.8
1982 270.0 4.197778 2.653551 0.6 2.100 3.40 5.700 14.7
1983 277.0 4.253069 2.669222 0.9 2.300 3.60 5.700 15.3
1984 262.0 4.107252 2.664220 0.7 2.100 3.45 5.700 13.4
1985 263.0 4.207224 2.625547 0.6 2.300 3.40 5.650 13.1
1986 260.0 4.213846 2.669888 0.7 2.075 3.45 5.725 13.1
1987 267.0 4.242697 2.804114 0.5 2.000 3.50 5.750 14.6
1988 275.0 4.285455 2.693871 0.6 2.300 3.50 6.050 13.0
1989 292.0 4.261301 2.623311 0.5 2.300 3.55 5.900 13.5
1990 312.0 4.235577 2.640006 0.5 2.375 3.60 5.800 14.0
1991 304.0 4.334539 2.647963 0.6 2.300 3.50 5.825 13.8
1992 310.0 4.260968 2.847617 0.4 2.225 3.45 5.800 18.7
1993 308.0 4.208766 2.792828 0.3 2.275 3.50 5.500 18.3
1994 304.0 4.294737 2.786668 0.7 2.300 3.60 5.500 17.3
1995 314.0 4.174522 2.698690 0.5 2.225 3.30 5.600 16.8
1996 343.0 4.156560 2.615095 0.6 2.250 3.40 5.500 14.9
1997 337.0 4.225223 2.714871 0.4 2.200 3.50 5.500 16.1
1998 342.0 4.232164 2.577404 0.7 2.200 3.50 5.600 15.0
1999 217.0 4.602304 2.575066 1.0 2.700 3.80 6.000 13.0
2000 327.0 4.210398 2.465097 0.6 2.250 3.70 5.700 14.1
2001 335.0 4.276418 2.538543 0.5 2.500 3.70 5.500 14.1
2002 332.0 4.287048 2.386337 0.8 2.600 3.90 5.400 13.0
2003 324.0 4.251235 2.390933 0.4 2.500 3.75 5.525 15.4
2004 348.0 4.263506 2.419223 0.6 2.500 3.80 5.300 13.9
2005 361.0 4.198061 2.427029 0.5 2.400 3.50 5.500 13.5
2006 345.0 4.140290 2.346627 0.4 2.300 3.60 5.200 12.7
2007 348.0 4.118391 2.485521 0.7 2.300 3.40 5.400 12.8
2008 342.0 4.285380 2.571218 0.5 2.400 3.55 5.300 14.2
2009 350.0 4.182857 2.400595 0.8 2.325 3.60 5.300 13.8
2010 348.0 4.204310 2.562793 0.6 2.300 3.50 5.500 13.2
2011 380.0 4.027105 2.375063 0.6 2.400 3.40 5.100 15.2
2012 305.0 4.275410 2.394776 0.8 2.500 3.70 5.300 14.5
2013 365.0 3.986301 2.405506 0.4 2.200 3.30 5.200 12.4
2014 366.0 4.127596 2.449787 0.8 2.400 3.50 5.200 13.6
2015 385.0 4.177143 2.338558 0.7 2.400 3.60 5.300 15.0
2016 360.0 4.134167 2.400563 0.7 2.400 3.50 5.325 14.8
2017 369.0 4.204878 2.443109 0.6 2.600 3.50 5.500 14.1
2018 355.0 4.243944 2.435144 0.4 2.500 3.80 5.400 16.0
2019 391.0 4.353964 2.510497 0.7 2.600 3.80 5.300 15.6
2020 335.0 4.497015 2.457030 1.0 2.700 4.10 5.700 15.8
2021 335.0 4.457612 2.446517 0.9 2.700 3.90 5.600 14.3
2022 384.0 4.383073 2.424720 0.8 2.675 3.90 5.400 14.7
2023 385.0 4.244416 2.354335 0.8 2.600 3.70 5.300 12.5
2024 376.0 4.213298 2.353943 0.8 2.600 3.70 5.200 13.7

結果


1950年代から60年代がレギュラー選手当たり1試合平均5リバウンド以上と高いですね。maxは歴代シーズンリバウンド王です。
ウィルト・チェンバレン選手やビル・ラッセル選手が1試合当たり20リバウンド以上と今では考えられない数値を叩き出しています。
3ポイントが導入された1980年以降は平均4リバウンド台を安定して推移しています。

現代バスケは3ポイントが重視され、戦略や平均得点が変わっていく中、レギュラー選手たちの平均リバウンド回数は1980年から意外に安定していることが分かります。

2025年6月15日日曜日

NBA選手シーズンごとの平均得点

NBA選手のシーズン当たりの得点

 データを元にシーズン毎の平均得点の推移をグラフ化してみます。

外れ値を省くために、1シーズン40試合以上出場した選手で構成しています。

#! /usr/bin/env python  
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns


fn = "data/player_per_game.csv"
df = pd.read_csv(fn, index_col=0)

df2 = df[df["g"] >= 40]

des = df2.groupby("season")["PPG"].describe()
print(des)

count mean std min 25% 50% 75% max
season
1950 183.0 8.178142 4.114657 1.7 5.000 7.40 10.800 27.4
1951 108.0 8.976852 4.619314 2.1 5.975 8.10 11.325 28.4
1952 94.0 9.263830 4.777610 1.3 6.100 8.75 12.000 25.4
1953 102.0 9.023529 4.408142 2.2 5.525 8.85 11.275 22.3
1954 91.0 8.651648 4.246943 1.6 5.900 8.20 10.450 24.4
1955 81.0 10.046914 5.192087 2.4 5.900 9.60 13.100 22.7
1956 80.0 10.177500 5.222056 2.4 6.525 8.85 13.225 25.7
1957 83.0 10.397590 5.245439 2.2 6.600 9.70 12.400 25.6
1958 78.0 11.506410 5.798216 3.4 7.400 9.40 16.400 27.8
1959 85.0 11.260000 5.994466 3.5 6.500 9.80 14.400 29.2
1960 87.0 11.886207 6.852264 3.0 7.350 9.90 14.350 37.6
1961 83.0 12.225301 7.547199 2.2 6.400 10.20 15.350 38.4
1962 100.0 12.348000 8.555221 1.5 6.050 10.35 15.950 50.4
1963 94.0 12.045745 7.262833 2.2 7.200 10.50 14.300 44.8
1964 102.0 11.489216 6.883585 1.7 5.775 9.90 15.775 36.9
1965 94.0 11.620213 6.724751 2.5 6.300 11.00 14.575 34.7
1966 103.0 11.838835 6.569899 2.6 7.300 10.70 15.350 33.5
1967 108.0 12.126852 6.489396 3.0 7.225 10.55 17.400 35.6
1968 136.0 11.949265 6.489273 2.0 6.550 11.65 16.625 29.2
1969 146.0 12.370548 6.392174 2.3 7.325 11.50 17.350 28.4
1970 154.0 12.246753 6.560719 2.1 7.200 11.50 15.550 31.2
1971 181.0 11.462431 6.616757 1.5 5.900 9.70 16.000 31.7
1972 189.0 11.605820 6.817438 1.5 5.900 11.10 15.700 34.8
1973 194.0 10.764433 6.656815 1.6 5.700 9.05 14.800 34.0
1974 184.0 10.810326 6.559276 1.8 5.575 9.30 14.975 30.6
1975 210.0 10.341429 6.244741 1.3 5.700 9.00 13.375 34.5
1976 199.0 10.492462 5.890430 1.7 5.900 9.20 13.850 31.1
1977 260.0 10.482308 5.847033 1.4 6.000 9.05 13.225 31.1
1978 259.0 10.945174 5.930006 2.0 6.250 9.60 14.750 27.2
1979 247.0 11.290283 6.263495 1.5 6.500 10.10 15.650 29.6
1980 248.0 11.283065 5.887415 2.5 6.600 10.25 14.900 33.1
1981 262.0 10.632824 5.939516 0.7 5.800 9.55 14.400 30.7
1982 270.0 10.534815 6.001231 1.3 5.700 9.80 14.350 32.3
1983 277.0 10.419134 6.093150 1.5 5.300 8.90 14.100 28.4
1984 262.0 10.524809 6.278965 1.3 5.425 9.00 14.500 30.6
1985 263.0 10.649810 6.560726 1.3 5.400 9.30 14.800 32.9
1986 260.0 10.577692 6.095973 0.6 5.375 9.25 14.300 30.3
1987 267.0 10.570412 6.424687 1.7 5.600 9.20 14.500 37.1
1988 275.0 10.619636 6.160800 1.1 6.000 9.50 14.200 35.0
1989 292.0 10.566438 6.399106 0.7 5.375 9.20 15.000 32.5
1990 312.0 10.410897 6.379762 1.1 5.175 8.95 14.700 33.6
1991 304.0 10.608224 6.295456 1.3 5.300 9.25 14.925 31.5
1992 310.0 10.226129 6.052927 1.1 5.100 9.20 14.175 30.1
1993 308.0 10.318831 6.016749 0.7 5.700 8.80 14.400 32.6
1994 304.0 10.280592 5.696689 1.7 5.675 9.25 14.125 29.8
1995 314.0 10.038854 5.879826 1.2 5.000 9.20 13.550 29.3
1996 343.0 9.868513 5.705394 0.3 5.100 9.10 13.300 30.4
1997 337.0 9.747478 5.926339 1.2 4.800 8.00 13.800 29.6
1998 342.0 9.711988 5.496349 1.1 5.300 9.00 13.275 28.7
1999 217.0 10.335945 5.207891 1.2 6.400 9.30 13.300 26.8
2000 327.0 9.568807 5.702088 0.8 5.400 8.10 12.500 29.7
2001 335.0 9.408955 5.914256 0.6 4.950 7.90 12.000 31.1
2002 332.0 9.771988 5.841670 1.1 5.100 8.40 12.950 31.4
2003 324.0 9.716667 6.016440 0.8 5.175 8.10 13.125 32.1
2004 348.0 9.454885 5.631074 0.9 4.900 7.95 13.225 28.0
2005 361.0 9.865097 5.911378 1.0 5.300 8.40 13.000 30.7
2006 345.0 9.857681 6.261762 1.1 5.000 8.60 13.000 35.4
2007 348.0 10.052299 6.163668 1.1 5.200 8.85 13.325 31.6
2008 342.0 10.047076 5.904616 0.9 5.725 8.65 13.100 30.0
2009 350.0 10.225143 5.957750 0.8 5.200 9.05 14.175 30.2
2010 348.0 10.136782 5.666940 0.7 6.000 8.90 13.800 30.1
2011 380.0 9.819211 5.582670 1.1 5.300 8.70 13.225 27.7
2012 305.0 9.887541 5.262952 1.0 5.500 9.30 12.700 28.0
2013 365.0 9.390959 5.262332 0.5 5.200 8.60 12.800 28.7
2014 366.0 9.807923 5.548187 1.6 5.525 9.05 13.200 32.0
2015 385.0 9.748052 5.014614 1.8 5.900 8.70 12.700 28.1
2016 360.0 9.875833 5.395877 1.3 5.900 8.70 12.700 30.1
2017 369.0 10.226016 5.935251 1.7 6.100 8.70 13.200 31.6
2018 355.0 10.488451 5.692110 1.4 6.050 9.20 13.500 30.4
2019 391.0 10.691560 5.802060 1.0 6.500 9.30 13.700 36.1
2020 335.0 11.280896 6.125054 1.5 6.600 9.80 15.050 34.3
2021 335.0 11.455224 6.338176 1.9 6.750 9.70 14.600 32.0
2022 384.0 10.966927 5.995893 2.2 6.400 9.25 14.450 30.6
2023 385.0 11.378701 6.651446 2.1 6.600 9.50 14.700 33.1
2024 376.0 11.025532 6.538390 1.7 5.975 9.35 14.700 33.9


plt.figure(figsize=(20, 6))
plt.xlim(1950, 2024)
plt.title("points per season")
sns.lineplot(data=des[["mean", "min", "max"]])
plt.show()

結果



最高得点(max)はシーズン得点王なのでよく知られている通りです。
1962年のウィルト・チェンバレン選手や1987年のマイケル・ジョーダン選手はグラフの山を作っています。
平均を見ると概ね10点超える辺りがレギュラー選手の得点と言えます。
1960〜70年代一時12点台と高く、2000年代に一時落ちてますが3Pが増えた現在は11点台となっています。

2024年10月18日金曜日

Pythonで地図空間データを扱う⑤

ベースの地図が出来た所で、他のデータを被せてみます。

国土地理院の 500mメッシュ別将来推計人口データ を使用します。

同じく神奈川県のデータ 500m_mesh_suikei_2018_shape_14.zip をダウンロードします。

ベースの地図データと同じ場所に展開します。

そして同じようにread_fileで読み込みます。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

#
import geopandas as gpd
import matplotlib.pyplot as plt
import japanize_matplotlib

fn = "../data/N03-20240101_14.shp"
gdf = gpd.read_file(fn)
fn2 = "../data/500m_mesh_2018_14.shp"
pdf = gpd.read_file(fn2)

print(gdf.head(10))
print("")
print(gdf.shape)
print("")
print(pdf.head())
print("")
print(pdf.shape)
(6193, 235)と巨大なデータフレームなので、必要なデータ以外は取り除いてもいいでしょう。
# 必要な列だけ取り出し軽量化します。
pdf2 = pdf[['SHICODE', 'PTN_2020', 'geometry']]

# ベースとなる地図
bg = gdf.boundary.plot(linewidth=0.5, edgecolor="gray", figsize=(14, 8))

# 人口データのプロット
pdf2.plot(ax=bg, column="PTN_2020", cmap="jet", legend=True)

# 地域名を表示
for name, row in citys:
    if row['N03_001'].count() > 1:
        x = row["geometry"].centroid.bounds.minx.mean()
        y = row["geometry"].centroid.bounds.miny.mean()
        bg.annotate(name, xy=(x, y), color="red")
    else:
        x = row["geometry"].centroid.bounds.minx
        y = row["geometry"].centroid.bounds.miny
        bg.annotate(name, xy=(x, y), color="red")  

plt.title("神奈川県人口マップ")
plt.show()

地図データに人口データを重ね合わせることが出来ました。

2024年10月15日火曜日

Pythonで地図空間データを扱う④

日本地図データ

テストデータで概要を掴めたら、外部からshapeファイルを読み込み使用してみます。
 日本に住んでる方は、日本の地域データを活用することが多いでしょうから国土地理院のデータを読み込んでみます。

国土地理院

全国はデータが大きいので今回は神奈川県のデータをダウンロードしました。
データはzipファイルなので、使用する場所に移動して解凍します。

$ unzip N03-20240101_14_GML.zip 

解凍するとshapeファイルなどいくつかのファイルが出来ます。
それらをリンクして使用されるので、個別で移動させたり、ファイル名を変えたりはしないでください。

回答したshapeファイルを前回と同じように読み込みます。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import geopandas as gpd
import matplotlib.pyplot as plt
import japanize_matplotlib

fn = "../data/N03-20240101_14.shp"
gdf = gpd.read_file(fn)

print(gdf.head())
print("")
print(gdf.shape)
print("")

結果
N03_001 N03_002 N03_003 N03_004 N03_005 N03_007 geometry
0 神奈川県 None None 横浜市 鶴見区 14101 POLYGON ((139.65294 35.50000, 139.65281 35.50010, 139.65270 35.50015, 139.65221 35.50030, 139.65214 35.50034, 139.65207 35.50038,・・・
1 神奈川県 None None 横浜市 鶴見区 14101 POLYGON ((139.67394 35.46229, 139.67347 35.46329, 139.67303 35.46426, 139.67272 35.46494, 139.67259 35.46523,・・・
2 神奈川県 None None 横浜市 鶴見区 14101 POLYGON ((139.70755 35.47204, 139.70756 35.47208, 139.70719 35.47264, 139.70595 35.47454, 139.70582 35.47457, ・・・
3 神奈川県 None None 横浜市 鶴見区 14101 POLYGON ((139.71140 35.48577, 139.71141 35.48575, 139.71108 35.48560, 139.71114 35.48551, 139.71097 35.48543, 139.71091 35.48553,・・・
4 神奈川県 None None 横浜市 鶴見区 14101 POLYGON ((139.70710 35.47226, 139.70713 35.47228, 139.70715 35.47227, 139.70722 35.47216, 139.70722 35.47215,・・・

1275, 7


地図の表示

次に地図をプロットしてみます。 boundary.plotは境界線のみ描画します。
linewidthやedgecolorで線を調節します。

 
gdf.boundary.plot(linewidth=0.5, edgecolor="gray", figsize=(12, 8))
plt.title("神奈川県")
plt.show()
神奈川県の地区データが表示されました。

2024年9月30日月曜日

Pythonで地図空間データを扱う③

GeoPandasで都市データのプロット

GeoPandasのdatasetsには、naturalearth_lowresの他に主要都市のデータnaturalearth_citiesがあります。
これを使い世界地図に都市もプロットしてみましょう。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import geopandas as gpd
import matplotlib.pyplot as plt

# 世界地図のデータ
world = gpd.datasets.get_path('naturalearth_lowres')
# 主要都市のデータ
cities = gpd.datasets.get_path('naturalearth_cities')

wdf = gpd.read_file(world)
cdf = gpd.read_file(cities)

print(wdf.head())
print()
print(wdf.shape)
print()
print(cdf.head())
print()
print(cdf.shape)
結果
       pop_est      continent                      name iso_a3  gdp_md_est                                           geometry
0     889953.0        Oceania                      Fiji    FJI        5496  MULTIPOLYGON (((180.00000 -16.06713, 180.00000...
1   58005463.0         Africa                  Tanzania    TZA       63177  POLYGON ((33.90371 -0.95000, 34.07262 -1.05982...
2     603253.0         Africa                 W. Sahara    ESH         907  POLYGON ((-8.66559 27.65643, -8.66512 27.58948...
3   37589262.0  North America                    Canada    CAN     1736425  MULTIPOLYGON (((-122.84000 49.00000, -122.9742...
4  328239523.0  North America  United States of America    USA    21433226  MULTIPOLYGON (((-122.84000 49.00000, -120.0000...

(177, 6)

           name                    geometry
0  Vatican City   POINT (12.45339 41.90328)
1    San Marino   POINT (12.44177 43.93610)
2         Vaduz    POINT (9.51667 47.13372)
3       Lobamba  POINT (31.20000 -26.46667)
4    Luxembourg    POINT (6.13000 49.61166)

(243, 2)

naturalearth_citiesは主要都市の名前と位置というシンプルなデータです。
これを世界地図に乗せていきます。

世界地図のGeoDataFrameオブジェクトを変数にして、axに指定することで両方プロットすることが出来ます。
# ベースとなる世界地図
bg = wdf.plot(column='continent', figsize=(18, 8))
# 主要都市をマッピング
cdf.plot(ax=bg, marker='o', color='firebrick')

# アノテーションで主要都市の名前をマッピング
for i, (city, point) in cdf.iterrows():
    # pointオブジェクトから緯度経度を抽出
    x1, y1, x2, y2 = point.bounds
    bg.annotate(city, xy=(x1, y1))

plt.show()


都市名はannotateでプロットします。 
geomatryデータからshapely.geometry.point.Pointオブジェクトを抜き出し、 bounds変数には(minx, miny, maxx, maxy)が入っているので、xy座標に指定します。

shapely.Point
https://shapely.readthedocs.io/en/stable/reference/shapely.Point.html
世界地図に都市名も表示出来ました。

Pythonで地図空間データを扱う②

GeoPandasでコロプレスマップを表示

基本的な動作を確認したら、コロプレスマップを作ってみます。 
 naturalearth_lowresには大陸以外に人口とGDPデータがあるので、それらを色で段階的に分けて表示します。


人口マップ

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import geopandas as gpd
import matplotlib.pyplot as plt
#日本語を表示するため
import japanize_matplotlib


fn = gpd.datasets.get_path('naturalearth_lowres')
gdf = gpd.read_file(fn)

# 人口データをint型にします
gdf['population'] = gdf['pop_est'].astype("int")
# 人口の多い順にソートします
gdf = gdf.sort_values("pop_est", ascending=False)
gdf = gdf.drop("pop_est", axis=1)

print(gdf.head(10))


continent                      name iso_a3  gdp_md_est  population
139           Asia                     China    CHN    14342903  1397715000
98            Asia                     India    IND     2868929  1366417754
4    North America  United States of America    USA    21433226   328239523
8             Asia                 Indonesia    IDN     1119190   270625568
102           Asia                  Pakistan    PAK      278221   216565318
29   South America                    Brazil    BRA     1839758   211049527
56          Africa                   Nigeria    NGA      448120   200963599
99            Asia                Bangladesh    BGD      302571   163046161
18          Europe                    Russia    RUS     1699876   144373535
27   North America                    Mexico    MEX     1268870   127575529

人口を分かりやすく表示しています。
それらのデータをプロットすることで人口のコロプレスマップが出来ます。
gdf.plot(column='population', cmap="jet", legend=True, figsize=(16, 8))
plt.title("人口マップ")
plt.show()
中国、インドの人口が多いのがひと目で理解できます。

 

各国のGDPマップ


次はGDPデータを使いコロプレスマップにしてみます。
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import geopandas as gpd
import matplotlib.pyplot as plt
import japanize_matplotlib


fn = gpd.datasets.get_path('naturalearth_lowres')
gdf = gpd.read_file(fn)

gdf = gdf.rename(columns={"gdp_md_est": "gdp_md"})
# GDPの多い順に並べます
gdf = gdf.sort_values("gdp_md", ascending=False)

print(gdf.head(10))

gdf.plot(column='gdp_md', cmap="jet", legend=True, figsize=(16, 8))
plt.title("GDP")
plt.show()
各国のGDPのコロプレスマップを表示出来ました。

2024年9月27日金曜日

Pythonで地図空間データを扱う

GeoPandasを使いPythonで地図を描画

Pythonはデータ処理関係のライブラリが豊富ですが、地図とデータを組み合わせられたら地域データの詳細もより分かりやすくなります。 ここ数年で注目度が高まっているGeoPandasを使って地図データを扱ってみたいと思います。

pip install geopandas

他のライブラリにも依存してしますので適宜インストールしてください。

  GeoDataFrameに変換するにはshapeファイルやGeoJSONファイルが必要ですが、テスト用のファイルがdatasetsにあります。 
 現在は3つほどと少ないですが、気軽にGeoDataFrmeを試すにはとても良いデータです。
 naturalearth_lowresを使用してみます。
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import geopandas as gpd
import matplotlib.pyplot as plt

# ①地図データファイルのあるパスを指定
path = gpd.datasets.get_path('naturalearth_lowres')

# ②ファイルからGeoDataFrameオブジェクトを生成
gdf = gpd.read_file(path)

print(gdf.head())
print("")
print(gdf.shape)
print("")
print(gdf.crs)


結果
       pop_est      continent                      name iso_a3  gdp_md_est                                           geometry
0     889953.0        Oceania                      Fiji    FJI        5496  MULTIPOLYGON (((180.00000 -16.06713, 180.00000...
1   58005463.0         Africa                  Tanzania    TZA       63177  POLYGON ((33.90371 -0.95000, 34.07262 -1.05982...
2     603253.0         Africa                 W. Sahara    ESH         907  POLYGON ((-8.66559 27.65643, -8.66512 27.58948...
3   37589262.0  North America                    Canada    CAN     1736425  MULTIPOLYGON (((-122.84000 49.00000, -122.9742...
4  328239523.0  North America  United States of America    USA    21433226  MULTIPOLYGON (((-122.84000 49.00000, -120.0000...

(177, 6)

EPSG:4326



pandasに慣れていれば非常に扱いやすいですね。
headやshapeも同じ使い方です。
Geoデータフレームはデータにgeometryという位置データが追加されているのがpandasデータフレームとの違いです。

CRSとは座標参照系(Coordinate Reference System)のことで、位置情報のルールを表します。
文字コードのようなものです。



このデータを使ってプロットします。
gdf.plot()
plt.show()


世界地図がプロットされました。 pandasライクで簡単に地図データを扱うことが出来ます。 このままでは味気ないので、オプションをつけて、少し装飾してみます。
 columnは色分け、cmapはカラーマップを指定します。
gdf.plot(column="continent", cmap="Accent", legend=True, figsize=(16, 8))
plt.show()
綺麗になりました。

2024年8月3日土曜日

Matplotlibのグラフが表示されないエラー

matplotlibでUserWarning: Matplotlib is currently using agg, which is a non-GUI backend, so cannot show the figure.というエラーが出た場合


古いPython version-3.6を使用してmatplotlibを使用した所、UserWarning: Matplotlib is currently using agg, which is a non-GUI backend, so cannot show the figure. というエラーが出てグラフが表示されませんでした。 

 これはGUIバックエンドが入ってない事で起きるエラーで 

 pip install pyqt5 

 とすることで解決しました。

2024年7月4日木曜日

matplotlibのグラフが表示されないエラー

virtualenvで新しい環境を作成した時のエラー

 matplotlibのグラフを表示しようと実行した時、

UserWarning: FigureCanvasAgg is non-interactive, and thus cannot be shown

  plt.show()


FigureCanvasAgg は非対話型であるため、表示できません

と出てグラフが表示されませんでした。



どうやらPythonのGUIモジュールPyQt5が入ってなかった様なので

 pip install PyQt5

で解決されました。

2022年6月11日土曜日

matplotlibで一次関数グラフを作る

前回、matplotlibで方眼紙の様な正方形グリッドが作れたら、数学の関数グラフも容易に作れます。

matplotlibはデータをプロットするライブラリなので式をそのままグラフにするのはひと工夫必要です。

今度はオブジェクト指向で関数グラフを作り、一次関数をプロットします。


# オブジェクト指向でグラフ作成
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
 
# これで正方形になります。
ax.set_aspect('equal', adjustable='box')

# 表示する幅
ax.set_xlim(-10, 11)
ax.set_ylim(-10, 11)

# グラフの刻み
ax.set_xticks(np.arange(-10, 10, 5))
ax.set_yticks(np.arange(-10, 10, 5))
 
# 補助線をonにします
ax.minorticks_on() 

# グリッドの主線と補助線
ax.grid(which="major", color="black", alpha=0.5)
ax.grid(which="minor", color="gray", linestyle="--", alpha=0.5)

# 数値表示を0に合わせます。
ax.spines['bottom'].set_position("zero")
ax.spines['left'].set_position("zero")
 

今回はオブジェクト指向のプロットなので若干書き方が違います。特に正方形にするには set_aspect('equal', adjustable='box')という指定をします。 またグラフの数値を0に合わせるため、spines.set_position 関数で zero を指定します。

関数グラフの方眼紙が出来たら、後は一次関数のデータを生成する関数を作ればいいだけ。

# 一次関数のデータを作る関数 
def linear(a, b, ran=np.arange(-10,10)):

    arr = []
    for x in ran:
        y = x*a + b
        arr.append(y)

	# 式から配列データを返します。
    return arr
これを応用すれば二次関数や他の関数もプロットできますね。


[完成形]
#! /usr/bin/env python

# -*- coding:utf-8 -*-
 
 
import numpy as np
import matplotlib.pyplot as plt


# 一次関数のデータを作る関数 
def linear(a, b, ran=np.arange(-10,10)):

    arr = []
    for x in ran:
        y = x*a + b
        arr.append(y)

	# 式から配列データを返します。
    return arr

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
 
# これで正方形になります。
ax.set_aspect('equal', adjustable='box')

# 表示する幅
ax.set_xlim(-10, 11)
ax.set_ylim(-10, 11)

# グラフの刻み
ax.set_xticks(np.arange(-10, 10, 5))
ax.set_yticks(np.arange(-10, 10, 5))
 
# 補助線をonにします
ax.minorticks_on() 

# グリッドの主線と補助線
ax.grid(which="major", color="black", alpha=0.5)
ax.grid(which="minor", color="gray", linestyle="--", alpha=0.5)

# 数値表示を0に合わせます。
ax.spines['bottom'].set_position("zero")
ax.spines['left'].set_position("zero")

x = np.arange(-10, 10)

# y = 2x + 3の一次関数を生成
y = linear(2, 3, x)
ax.plot(x, y)


plt.show()

2022年6月9日木曜日

matplotlibで方眼紙のようなグリッドを作る

Pythonのmatplotlibはグラフ描画のためのライブラリですが、描画はデータによって自動的に調整されるので、時には方眼紙のように正確なグリッドが欲しい場合もあります。

正方形の方眼紙のようなグリッドは、plt.axis("square")で正方形に、ticksでマス目を刻みます。

#! /usr/bin/env python

# -*- coding:utf-8 -*-

import numpy as np
import matplotlib.pyplot as plt

# 正方形で表示
plt.axis("square")

# 表示範囲の指定
plt.xlim(-10, 10)
plt.ylim(-10, 10)

# 値の刻み
plt.xticks(np.arange(-10, 11, 5))
plt.yticks(np.arange(-10, 11, 5))

#grid マイナー線の指定をします
plt.minorticks_on()
plt.grid()
# マイナー線は破線で透明度50%
plt.grid(which="minor", color="gray", linestyle="--", alpha=0.5)

plt.show()
 
 
ポイントはaxis("square")です。これで数値通りの大きさで表示されます。
あとはxlimでX軸の、ylimでY軸のグラフの範囲、ticksで表示するメモリ数値の刻みを指定します。
グリッドの線はgrid関数で指定しますが、主線だけでなく副線も表示したい場合はminorticks_on関数を呼び出して表示します。
副線は同じgrid関数でwhich="minor"で呼び出します。
あとは"--"で破線、alphaで透明度など指定して好みの方眼紙に調整してください。



以上のようなグラフになります。


NBAの1試合平均チームスタッツ (2025-26レギュラーシーズン)

前回 の元となったデータ、チーム毎の各スタッツ平均です。   team games w l win% PTS AST BLK STL ...