Python:在留外国人の詳細を円グラフで表示する

在留外国人数を国籍別、在留資格別に円グラフ化する。我が国日本は、在留外国人数が順調に増加しているのが微笑ましい。私が生きている間に早く1000万人の大台を超えてもらいたいものである。多くの日本人がそれを願っているはずである。

スポンサーリンク

国籍別在留外国人数

import tabula

df = tabula.read_pdf("http://www.moj.go.jp/content/001289225.pdf",
             output_format='dataframe',
             pages = '1',
             encoding='utf-8',
             java_options=None,
             pandas_options=None,
             multiple_tables=False)
df[4:6].head(2)
Unnamed: 0 Unnamed: 1 Unnamed: 2 平成20年末 平成21年末 平成22年末 平成23年末 平成24年末 平成25年末 平成26年末 平成27年末 平成28年末 平成29年末 平成30年末 Unnamed: 14 Unnamed: 15
4 NaN NaN NaN (2008) (2009) (2010) (2011) (2012) (2013) (2014) (2015) (2016) (2017) (2018) NaN NaN
5 NaN 総 数 NaN 2,144,682 2,125,571 2,087,261 2,047,349 2,033,656 2,066,445 2,121,831 2,232,189 2,382,822 2,561,848 2,731,093 100.0 6.6
df1 = df[['Unnamed: 1','平成30年末']][6:18].drop(7)
df1 = df1.set_index(['Unnamed: 1'])
df1
平成30年末
Unnamed: 1
764,720
449,634
ト ナ ム 330,835
ィ リ ピ ン 271,289
ラ ジ ル 201,865
パ ー ル 88,951
60,684
57,500
NaN 56,346
52,323
の 他 396,946
df1.index=['中国','韓国','ベトナム','フィリピン','ブラジル','ネパール','台湾','米国',\
          'インドネシア','タイ','その他'] 
df1
平成30年末
中国 764,720
韓国 449,634
ベトナム 330,835
フィリピン 271,289
ブラジル 201,865
ネパール 88,951
台湾 60,684
米国 57,500
インドネシア 56,346
タイ 52,323
その他 396,946
for i, col in enumerate(df1.columns):
    df1.iloc[:, i] = df1.iloc[:, i].str.replace(',', '')
df1 = df1.apply(pd.to_numeric, errors="coerce").astype(int)
%matplotlib inline
from matplotlib.pyplot import *
from matplotlib.font_manager import FontProperties
from matplotlib import rcParams

style.use('classic')
fp = FontProperties(fname='/usr/share/fonts/opentype/ipaexfont-gothic/ipaexg.ttf', size=54)
rcParams['font.family'] = fp.get_name()
c      = [(x/22.0, x/77.0, .9) for x in range(len(df1))] 

fig, ax = subplots(figsize=(18,10))
_,texts,autotexts = ax.pie(df1['平成30年末'],labels=df1.index,colors=c,shadow=True,\
 explode=(0,0.1,0,0,0,0.1,0,0.1,0.,0.1,0.),autopct='%1.2f%%',wedgeprops = {'linewidth': 3},\
  textprops={'fontsize': 25},startangle=65,pctdistance=.85,labeldistance=1.1,radius=1.2);
#texts.set_fontsize(50)
setp(autotexts, size=20, weight="bold");
setp(texts, size=25, weight="bold");
for autotext in autotexts:
    autotext.set_color('white')
スポンサーリンク

在留資格別在留外国人数

import tabula

df2 = tabula.read_pdf("http://www.moj.go.jp/content/001289225.pdf",
             output_format='dataframe',
             pages = '4',
             encoding='utf-8',
             java_options=None,
             pandas_options=None,
             multiple_tables=False)
df3 = df2[1:2]
df3
日本人の国籍・地域 計 特別永住者 中長期在留者 永住者 留学 技能実習 技術・ 人文知識・ Unnamed: 7 定住者 家族滞在 Unnamed: 10 特定活動 その他
1 総 数 2,731,093 321,416 2,409,677 771,568 337,000 328,360 225,724 NaN 192,014 182,452 142,381 62,956 167,222
df3.drop(['中長期在留者','Unnamed: 7'], axis=1,inplace=True)
df3.rename(columns={'日本人の国籍・地域 計':'総数','技術・ 人文知識・':'技術・人文知識・国際業務','Unnamed: 10':'日本人の配偶者等'},inplace=True)
df3
総数 特別永住者 永住者 留学 技能実習 技術・人文知識・国際業務 定住者 家族滞在 日本人の配偶者等 特定活動 その他
1 総 数 2,731,093 321,416 771,568 337,000 328,360 225,724 192,014 182,452 142,381 62,956 167,222
for i, col in enumerate(df3.columns):
    df3.iloc[:, i] = df3.iloc[:, i].str.replace('総 数','').str.replace(',','')
df3 = df3.apply(pd.to_numeric, errors="coerce").astype(int)
df3.index=['外国人数']
df3
総数 特別永住者 永住者 留学 技能実習 技術・人文知識・国際業務 定住者 家族滞在 日本人の配偶者等 特定活動 その他
外国人数 2731093 321416 771568 337000 328360 225724 192014 182452 142381 62956 167222
df3.drop(['総数'], axis=1,inplace=True)
df3
特別永住者 永住者 留学 技能実習 技術・人文知識・国際業務 定住者 家族滞在 日本人の配偶者等 特定活動 その他
外国人数 321416 771568 337000 328360 225724 192014 182452 142381 62956 167222
k=df3.T.sort_values('外国人数',ascending=False)
m=[]
for i in k['外国人数']:
    m.append(i)
n=[]
for i in k.T.columns:
    n.append(i)
c = cm.inferno_r(np.linspace(.2,.5, 10))

fig, ax = subplots(figsize=(18,10))
_,texts,autotexts = ax.pie(m,labels=n,colors=c,shadow=True,\
 explode=(0,0.1,0,0,.15,0.1,0,0.1,0.,0.1,),autopct='%1.2f%%',wedgeprops = {'linewidth': 3},\
  textprops={'fontsize': 25},startangle=0,pctdistance=.75,labeldistance=1.1,radius=1.2);
#texts.set_fontsize(50)
setp(autotexts, size=25, weight="black",color='black')
setp(texts, size=25, weight="heavy",color='black');

よく考えると、これだと人数が分からないので人数も表示する必要がある。

fig, ax = subplots(figsize=(18,10))
def func(pct, allvals):
    absolute = int(pct/100.*np.sum(allvals))
    return "{:.1f}%\n({:,}人)".format(pct, absolute)
c = cm.spring_r(np.linspace(0.1, 0.5, 10))
wedges,texts,autotexts = ax.pie(m,labels=n,shadow=True,colors=c,\
 explode=(0,0.1,0,0,.15,0.1,0,0.1,0.,0.1,),autopct=lambda pct: func(pct, m),wedgeprops = {'linewidth': 3},\
  textprops={'fontsize': 25},startangle=0,pctdistance=.80,labeldistance=1.1,radius=1.2);
setp(autotexts, size=16, weight="black",color='k')
setp(texts, size=25, weight="heavy",color='black');

これだと見辛いので、矢印付きで表示してみる。先ず、intをstrに変換する。

e = []
for i in m:
    e.append(str(i))
c=[]
for i in range(len(e)):
    d=e[i][:len(e[i])-4]+'万'+e[i][-4:]
    c.append(d)
f=["{}({}人)".format(n_, c_) for c_, n_ in zip(c, n)]
fig, ax = subplots(figsize=(18,10))

wedges,texts,autotexts = ax.pie(m,shadow=True,labeldistance=1,radius=1.2,\
 explode=(0.1,0.,0.1,0.,.15,0.,0.1,0.,0.1,0.,),wedgeprops = {'linewidth': 3},\
  autopct='%1.2f%%',textprops={'fontsize': 25},startangle=160,\
   pctdistance=.75,counterclock=False)

plt.setp(autotexts, size=35, weight="bold",color='w')

bbox_props = dict(boxstyle="square,pad=0.3", fc="w", ec="k", lw=0.72)
kw = dict(arrowprops=dict(arrowstyle="-"),
          bbox=bbox_props, zorder=0, va="center")

for i, p in enumerate(wedges):
    ang = (p.theta2 - p.theta1)/2 + p.theta1
    y = np.sin(np.deg2rad(ang))
    x = np.cos(np.deg2rad(ang))
    horizontalalignment = {-1: "right", 1: "left"}[int(np.sign(x))]
    connectionstyle = "angle,angleA=0,angleB={}".format(ang)
    kw["arrowprops"].update({"connectionstyle": connectionstyle})
    ax.annotate(f[i], xy=(x, y), xytext=(1.5*np.sign(x), 1.45*y),size=30,
                horizontalalignment=horizontalalignment, **kw)

移民=永住権保持者かつ市民権獲得の権利を持つ外国人を指すので、日本の場合は、定住者、日本人の配偶者、特別永住者と永住者がそれに当たるだろう。なので、本当の意味での移民に当たる外国人は、在留外国人数の半分程度であろう。今後、留学生と技能実習生が増えて、彼等が永住権を取得しやすい環境になれば、日本は、真の移民大国へと脱皮できるのではないだろうか。

参考サイトhttps://stackoverflow.com/
スポンサーリンク
スポンサーリンク

フォローする