- 아니 왜 plot HTML로 바꿔 올리면 에러남...

import pandas as pd
import folium 
import json
import requests 

1

df = pd.read_html('https://ncv.kdca.go.kr/mainStatus.es?mid=a11702000000', encoding = 'utf-8')[1]
df
구분 1차접종 2차접종 3차접종
구분 당일 실적 당일 누계 당일 실적 당일 누계 당일 실적 당일 누계
0 합계 44915 42871274 54713 41568595 439915 5289734
1 서울 6632 7978215 7730 7760751 82159 988855
2 부산 3359 2740631 3523 2653933 28332 320683
3 대구 2196 1907860 2353 1845856 16526 195340
4 인천 2446 2446083 3075 2370883 26230 279748
5 광주 1480 1197383 1990 1156165 10386 147318
6 대전 1288 1180917 1639 1142424 11252 135211
7 울산 1203 914405 1171 886896 7737 85420
8 세종 304 274389 371 264195 2292 30502
9 경기 11172 11225014 11469 10888835 103816 1301726
10 강원 1411 1286431 1967 1248659 17893 181907
11 충북 1297 1359054 1874 1318878 14207 180186
12 충남 1750 1799651 2594 1741052 20880 246609
13 전북 2044 1523092 3994 1478776 21387 235253
14 전남 1728 1582830 3270 1534876 17895 276074
15 경북 2230 2171884 2790 2102489 23735 282803
16 경남 3536 2729534 4141 2639330 29592 339109
17 제주 839 553901 762 534597 5596 62990

- 합계는 필요없는것 같다

df_ = df.copy()
df_ = df_.iloc[1:,:].reset_index(drop = True) ## df와 df2의 인덱스번호를 맞춰주기 위함
global_url = 'https://raw.githubusercontent.com/southkorea/southkorea-maps/master/kostat/2018/json/skorea-provinces-2018-geo.json'
global_dict = json.loads(requests.get(global_url).text)
df_.loc[:, ('구분','구분')] = [global_dict['features'][i]['properties']['name'] for i in range(17)]
df2 = pd.read_csv('https://raw.githubusercontent.com/guebin/2021DV/master/_notebooks/2021-11-22-prov.csv')
df2
행정구역(시군구)별 총인구수 (명)
0 서울특별시 9532428
1 부산광역시 3356311
2 대구광역시 2390721
3 인천광역시 2945009
4 광주광역시 1442454
5 대전광역시 1454228
6 울산광역시 1122566
7 세종특별자치시 368276
8 경기도 13549577
9 강원도 1537717
10 충청북도 1596948
11 충청남도 2118977
12 전라북도 1789770
13 전라남도 1834653
14 경상북도 2627925
15 경상남도 3318161
16 제주특별자치도 676569
df2['prob'] = df_[('2차접종', '당일 누계')] / df2['총인구수 (명)']
df2 = df2.rename(columns = {'행정구역(시군구)별':'prov'}).drop('총인구수 (명)', axis = 1)
df2
prov prob
0 서울특별시 0.814142
1 부산광역시 0.790729
2 대구광역시 0.772092
3 인천광역시 0.805051
4 광주광역시 0.801526
5 대전광역시 0.785588
6 울산광역시 0.790061
7 세종특별자치시 0.717383
8 경기도 0.803629
9 강원도 0.812021
10 충청북도 0.825874
11 충청남도 0.821647
12 전라북도 0.826238
13 전라남도 0.836603
14 경상북도 0.800057
15 경상남도 0.795420
16 제주특별자치도 0.790159
m = folium.Map(scrollWheelZoom = False,
               location = [36,128],
               zoom_start = 8.2)
folium.Choropleth(
    data = df2,
    geo_data = global_dict,
    columns = ['prov', 'prob'],
    key_on = 'feature.properties.name'
).add_to(m)

# m
<folium.features.Choropleth at 0x215edd70f70>

2

df = pd.read_csv('https://raw.githubusercontent.com/guebin/2021DV/master/_notebooks/covid19_20211202.csv')
df
일자 계(명) 서울 부산 대구 인천 광주 대전 울산 세종 경기 강원 충북 충남 전북 전남 경북 경남 제주 검역
0 누적(명) 457,612 158,774 16,555 19,114 25,299 6,353 8,809 5,675 1,588 136,546 8,889 8,942 13,174 6,453 4,498 11,471 15,236 3,762 6,474
1 2020-01-20 1 - - - 1 - - - - - - - - - - - - - -
2 2020-01-21 0 - - - - - - - - - - - - - - - - - -
3 2020-01-22 0 - - - - - - - - - - - - - - - - - -
4 2020-01-23 0 - - - - - - - - - - - - - - - - - -
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
679 2021-11-28 3,925 1,673 148 106 278 52 53 4 5 1,090 63 25 121 45 25 103 89 35 10
680 2021-11-29 3,308 1,393 144 88 233 61 43 2 15 910 56 33 52 49 28 68 86 44 3
681 2021-11-30 3,032 1,186 79 78 192 52 43 3 22 909 84 59 81 50 36 68 60 22 8
682 2021-12-01 5,123 2,222 143 86 326 29 88 17 20 1,582 105 48 96 50 40 97 127 27 20
683 2021-12-02 5,266 2,268 158 70 355 39 166 18 8 1,495 145 49 149 71 39 106 94 31 5

684 rows × 20 columns

df3 = pd.read_csv('https://raw.githubusercontent.com/guebin/2021DV/master/_notebooks/2021-11-22-prov.csv')
df3
행정구역(시군구)별 총인구수 (명)
0 서울특별시 9532428
1 부산광역시 3356311
2 대구광역시 2390721
3 인천광역시 2945009
4 광주광역시 1442454
5 대전광역시 1454228
6 울산광역시 1122566
7 세종특별자치시 368276
8 경기도 13549577
9 강원도 1537717
10 충청북도 1596948
11 충청남도 2118977
12 전라북도 1789770
13 전라남도 1834653
14 경상북도 2627925
15 경상남도 3318161
16 제주특별자치도 676569
df3 = df3.rename(columns = {'행정구역(시군구)별':'prov', '총인구수 (명)':'pop'})

- 검역은 지도에 표시 안할거니 제외

df_ = df.copy()
df_.iloc[1:, 1:] = df_.iloc[1:, 1:].applymap(lambda x: int(x.replace(',', '')) if x != '-' else 0)
df_ = df_.iloc[1:, :-1].drop('계(명)', axis = 1)
df_['일자'] = df_['일자'].apply(lambda x: str(x)[:-3])
df_
일자 서울 부산 대구 인천 광주 대전 울산 세종 경기 강원 충북 충남 전북 전남 경북 경남 제주
1 2020-01 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
2 2020-01 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
3 2020-01 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
4 2020-01 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
5 2020-01 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
679 2021-11 1673 148 106 278 52 53 4 5 1090 63 25 121 45 25 103 89 35
680 2021-11 1393 144 88 233 61 43 2 15 910 56 33 52 49 28 68 86 44
681 2021-11 1186 79 78 192 52 43 3 22 909 84 59 81 50 36 68 60 22
682 2021-12 2222 143 86 326 29 88 17 20 1582 105 48 96 50 40 97 127 27
683 2021-12 2268 158 70 355 39 166 18 8 1495 145 49 149 71 39 106 94 31

683 rows × 18 columns

_df = df_.groupby('일자').agg('sum').reset_index().\
rename(columns = dict(zip(df_.columns, ['ym'] + [global_dict['features'][i]['properties']['name'] for i in range(17)]))).\
query('"2021-01" <= ym <= "2021-10"').\
melt(id_vars = 'ym').rename(columns = {'variable':'prov', 'value':'confirmed'})
_df = _df.assign(pop = [df3.query('prov == @_df["prov"][@i]')['pop'].pipe(int) for i in range(len(_df))]).\
eval('prop = confirmed / pop')
_df
ym prov confirmed pop prop
0 2021-01 서울특별시 5160 9532428 0.000541
1 2021-02 서울특별시 4080 9532428 0.000428
2 2021-03 서울특별시 3794 9532428 0.000398
3 2021-04 서울특별시 5807 9532428 0.000609
4 2021-05 서울특별시 6078 9532428 0.000638
... ... ... ... ... ...
165 2021-06 제주특별자치도 234 676569 0.000346
166 2021-07 제주특별자치도 468 676569 0.000692
167 2021-08 제주특별자치도 870 676569 0.001286
168 2021-09 제주특별자치도 273 676569 0.000404
169 2021-10 제주특별자치도 225 676569 0.000333

170 rows × 5 columns

- 지금까지 고생해서 만든 데이터프레임은 시도별 월별 코로나수 확진자 수이다

# from IPython.display import HTML
# fig = px.choropleth_mapbox(_df, 
#                      geojson = global_dict, 
#                      color = 'prop',
#                      locations = 'prov', 
#                      animation_frame = 'ym',
#                      featureidkey = 'properties.name',
#                      center = {"lat": 36, "lon": 128},
#                      mapbox_style = 'carto-positron', 
#                      range_color = (0, _df.prop.max()),
#                      height = 1200,
#                      zoom = 6.5)
# fig.update_layout(margin = {"r":0, "t":0, "l":0, "b":0})
# _html = fig.to_html(include_mathjax = False, config = dict({'scrollZoom':False}))
# HTML(_html)

- 위 코드를 실행하면 컴퓨터가 맛이가서 전부 주석처리했다

3

df4 = pd.read_csv('https://raw.githubusercontent.com/guebin/2021DV/master/_notebooks/covid19_20211202.csv')
df4
일자 계(명) 서울 부산 대구 인천 광주 대전 울산 세종 경기 강원 충북 충남 전북 전남 경북 경남 제주 검역
0 누적(명) 457,612 158,774 16,555 19,114 25,299 6,353 8,809 5,675 1,588 136,546 8,889 8,942 13,174 6,453 4,498 11,471 15,236 3,762 6,474
1 2020-01-20 1 - - - 1 - - - - - - - - - - - - - -
2 2020-01-21 0 - - - - - - - - - - - - - - - - - -
3 2020-01-22 0 - - - - - - - - - - - - - - - - - -
4 2020-01-23 0 - - - - - - - - - - - - - - - - - -
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
679 2021-11-28 3,925 1,673 148 106 278 52 53 4 5 1,090 63 25 121 45 25 103 89 35 10
680 2021-11-29 3,308 1,393 144 88 233 61 43 2 15 910 56 33 52 49 28 68 86 44 3
681 2021-11-30 3,032 1,186 79 78 192 52 43 3 22 909 84 59 81 50 36 68 60 22 8
682 2021-12-01 5,123 2,222 143 86 326 29 88 17 20 1,582 105 48 96 50 40 97 127 27 20
683 2021-12-02 5,266 2,268 158 70 355 39 166 18 8 1,495 145 49 149 71 39 106 94 31 5

684 rows × 20 columns

- 위의 데이터프레임을 전처리한것이 아래다

- 누적과 합계를 제외하고 검역도 제외했다

- 관찰치를 int형으로 바꾸고 -은 0으로 처리했다

df4.iloc[1:, 1:] = df4.iloc[1:, 1:].applymap(lambda x: int(x.replace(',', '')) if x != '-' else 0)
df4 = df4.iloc[1:, :-1].drop('계(명)', axis = 1)
df4.columns = ['date'] + [global_dict['features'][i]['properties']['name_eng'] for i in range(17)]
df4
date Seoul Busan Daegu Incheon Gwangju Daejeon Ulsan Sejongsi Gyeonggi-do Gangwon-do Chungcheongbuk-do Chungcheongnam-do Jeollabuk-do Jeollanam-do Gyeongsangbuk-do Gyeongsangnam-do Jeju-do
1 2020-01-20 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
2 2020-01-21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
3 2020-01-22 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
4 2020-01-23 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
5 2020-01-24 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
679 2021-11-28 1673 148 106 278 52 53 4 5 1090 63 25 121 45 25 103 89 35
680 2021-11-29 1393 144 88 233 61 43 2 15 910 56 33 52 49 28 68 86 44
681 2021-11-30 1186 79 78 192 52 43 3 22 909 84 59 81 50 36 68 60 22
682 2021-12-01 2222 143 86 326 29 88 17 20 1582 105 48 96 50 40 97 127 27
683 2021-12-02 2268 158 70 355 39 166 18 8 1495 145 49 149 71 39 106 94 31

683 rows × 18 columns

(1) matplotlib

import matplotlib.pyplot as plt
df4.plot.line(x = 'date', subplots = True, layout = (9, 2), figsize = (15, 15))
plt.tight_layout()

(2) plotly

- 데이터프레임을 tidy하게 만들면된다

df4 ## 현재 데이터프레임 상태
date Seoul Busan Daegu Incheon Gwangju Daejeon Ulsan Sejongsi Gyeonggi-do Gangwon-do Chungcheongbuk-do Chungcheongnam-do Jeollabuk-do Jeollanam-do Gyeongsangbuk-do Gyeongsangnam-do Jeju-do
1 2020-01-20 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
2 2020-01-21 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
3 2020-01-22 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
4 2020-01-23 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
5 2020-01-24 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
679 2021-11-28 1673 148 106 278 52 53 4 5 1090 63 25 121 45 25 103 89 35
680 2021-11-29 1393 144 88 233 61 43 2 15 910 56 33 52 49 28 68 86 44
681 2021-11-30 1186 79 78 192 52 43 3 22 909 84 59 81 50 36 68 60 22
682 2021-12-01 2222 143 86 326 29 88 17 20 1582 105 48 96 50 40 97 127 27
683 2021-12-02 2268 158 70 355 39 166 18 8 1495 145 49 149 71 39 106 94 31

683 rows × 18 columns

df4_ = df4.melt(id_vars = 'date').rename(columns = {'variable':'prov'})
df4_
date prov value
0 2020-01-20 Seoul 0
1 2020-01-21 Seoul 0
2 2020-01-22 Seoul 0
3 2020-01-23 Seoul 0
4 2020-01-24 Seoul 1
... ... ... ...
11606 2021-11-28 Jeju-do 35
11607 2021-11-29 Jeju-do 44
11608 2021-11-30 Jeju-do 22
11609 2021-12-01 Jeju-do 27
11610 2021-12-02 Jeju-do 31

11611 rows × 3 columns

# fig = df4_.plot.line(backend = 'plotly',
#                  x = 'date',
#                  y = 'value',
#                  color = 'prov',
#                  facet_col = 'prov',
#                  facet_col_wrap = 3, 
#                  height = 1000)
# fig.update_yaxes(matches = None)
# HTML(fig.to_html(include_mathjax = False, config = dict({'scrollZoom':False})))

4

(1)

df5 = pd.read_csv('https://raw.githubusercontent.com/guebin/2021DV/master/_notebooks/2021-10-25-FIFA22_official_data.csv')
df5.head()
ID Name Age Photo Nationality Flag Overall Potential Club Club Logo ... SlidingTackle GKDiving GKHandling GKKicking GKPositioning GKReflexes Best Position Best Overall Rating Release Clause DefensiveAwareness
0 212198 Bruno Fernandes 26 https://cdn.sofifa.com/players/212/198/22_60.png Portugal https://cdn.sofifa.com/flags/pt.png 88 89 Manchester United https://cdn.sofifa.com/teams/11/30.png ... 65.0 12.0 14.0 15.0 8.0 14.0 CAM 88.0 €206.9M 72.0
1 209658 L. Goretzka 26 https://cdn.sofifa.com/players/209/658/22_60.png Germany https://cdn.sofifa.com/flags/de.png 87 88 FC Bayern München https://cdn.sofifa.com/teams/21/30.png ... 77.0 13.0 8.0 15.0 11.0 9.0 CM 87.0 €160.4M 74.0
2 176580 L. Suárez 34 https://cdn.sofifa.com/players/176/580/22_60.png Uruguay https://cdn.sofifa.com/flags/uy.png 88 88 Atlético de Madrid https://cdn.sofifa.com/teams/240/30.png ... 38.0 27.0 25.0 31.0 33.0 37.0 ST 88.0 €91.2M 42.0
3 192985 K. De Bruyne 30 https://cdn.sofifa.com/players/192/985/22_60.png Belgium https://cdn.sofifa.com/flags/be.png 91 91 Manchester City https://cdn.sofifa.com/teams/10/30.png ... 53.0 15.0 13.0 5.0 10.0 13.0 CM 91.0 €232.2M 68.0
4 224334 M. Acuña 29 https://cdn.sofifa.com/players/224/334/22_60.png Argentina https://cdn.sofifa.com/flags/ar.png 84 84 Sevilla FC https://cdn.sofifa.com/teams/481/30.png ... 82.0 8.0 14.0 13.0 13.0 14.0 LB 84.0 €77.7M 80.0

5 rows × 65 columns

abilities = ['Crossing', 'Finishing', 'HeadingAccuracy', 'ShortPassing',
           'Volleys', 'Dribbling', 'Curve', 'FKAccuracy',
           'LongPassing', 'BallControl', 'Acceleration', 'SprintSpeed',
           'Agility', 'Reactions', 'Balance', 'ShotPower', 
           'Jumping', 'Stamina', 'Strength', 'LongShots',
           'Aggression', 'Interceptions', 'Positioning', 'Vision',
           'Penalties', 'Composure', 'StandingTackle', 'SlidingTackle']

- 일단 Korea Republic을 Korea로 바꾼다

df5['Nationality'] = df5['Nationality'].replace('Korea Republic', 'Korea')
mean_ = ['mean'] * len(abilities)
df5_ = df5.query('Nationality == "Korea" or Nationality == "Japan"').\
groupby('Nationality').agg(dict(zip(abilities, mean_))).\
stack().reset_index().rename(columns = {'level_1':'aility', 0:'value'})
df5_['value'] = round(df5_['value'], 2)
df5_
Nationality aility value
0 Japan Crossing 54.42
1 Japan Finishing 50.67
2 Japan HeadingAccuracy 51.07
3 Japan ShortPassing 62.35
4 Japan Volleys 46.54
5 Japan Dribbling 59.53
6 Japan Curve 51.18
7 Japan FKAccuracy 46.57
8 Japan LongPassing 57.50
9 Japan BallControl 62.29
10 Japan Acceleration 67.31
11 Japan SprintSpeed 66.84
12 Japan Agility 68.63
13 Japan Reactions 62.05
14 Japan Balance 68.37
15 Japan ShotPower 59.14
16 Japan Jumping 67.12
17 Japan Stamina 66.35
18 Japan Strength 62.54
19 Japan LongShots 51.57
20 Japan Aggression 54.74
21 Japan Interceptions 46.55
22 Japan Positioning 55.34
23 Japan Vision 58.00
24 Japan Penalties 48.74
25 Japan Composure 58.93
26 Japan StandingTackle 48.48
27 Japan SlidingTackle 45.37
28 Korea Crossing 49.76
29 Korea Finishing 47.74
30 Korea HeadingAccuracy 51.69
31 Korea ShortPassing 58.76
32 Korea Volleys 43.68
33 Korea Dribbling 55.82
34 Korea Curve 48.52
35 Korea FKAccuracy 45.63
36 Korea LongPassing 53.37
37 Korea BallControl 57.70
38 Korea Acceleration 65.85
39 Korea SprintSpeed 66.11
40 Korea Agility 67.11
41 Korea Reactions 61.94
42 Korea Balance 66.66
43 Korea ShotPower 56.83
44 Korea Jumping 64.88
45 Korea Stamina 64.63
46 Korea Strength 65.23
47 Korea LongShots 48.94
48 Korea Aggression 56.08
49 Korea Interceptions 47.47
50 Korea Positioning 54.62
51 Korea Vision 57.27
52 Korea Penalties 47.97
53 Korea Composure 58.48
54 Korea StandingTackle 46.63
55 Korea SlidingTackle 44.28
#                     y = 'aility',
#                     x = 'value',
#                     barmode = 'group',
#                     color = 'Nationality',
#                     text = 'value',  
#                     height = 1500,
#                     width = 800)

# HTML(fig.to_html(include_mathjax = False, config = dict({'scrollZoom':False})))

- plotly는 따로 barh가 없으니 x와 y를 바꾸자

(2)

_df5 = df5.copy()
players = _df5.groupby('Nationality').agg('size').reset_index().\
sort_values(0, ascending = False).iloc[:20, 0].pipe(set)
players
{'Argentina',
 'Belgium',
 'Brazil',
 'Colombia',
 'Denmark',
 'England',
 'France',
 'Germany',
 'Italy',
 'Japan',
 'Mexico',
 'Netherlands',
 'Norway',
 'Poland',
 'Portugal',
 'Republic of Ireland',
 'Scotland',
 'Spain',
 'Sweden',
 'United States'}

- 위는 선수 수가 많은 상위 20개 나라

overall = set(_df5.groupby('Nationality').agg({'Overall':'mean'}).\
sort_values('Overall', ascending = False).iloc[:20,:].T.columns.tolist())
overall
{'Algeria',
 'Argentina',
 'Brazil',
 'Cape Verde Islands',
 'Central African Republic',
 'Croatia',
 'Czech Republic',
 'Egypt',
 'Fiji',
 'Gabon',
 'Libya',
 'Mozambique',
 'Namibia',
 'Portugal',
 'Russia',
 'Serbia',
 'Syria',
 'Tanzania',
 'Ukraine',
 'Uruguay'}

- 위는 Overall이 높은 상위 20개 나라

best = list(overall.intersection(players))
best
['Argentina', 'Brazil', 'Portugal']

- 위는 overall과 players의 교집합

df5.query('Nationality in @best').\
groupby('Nationality').agg({'Age':'mean'}).\
sort_values('Age', ascending = False).\
plot.bar()
<AxesSubplot:xlabel='Nationality'>

- Argentina 선수들의 평균 연령이 제일 높고 그 다음은 Brazil 마지막은 Portugal 이다

5

- 내가 임의로 만든 데이터

from plotnine import *
gdp = [500, 600, 620, 700, 900, 800, 770, 765, 1102, 1155, 1320, 1500, 1900, 1950, 2200]
year = list(range(1990, 2005))
unfair = [58, 60, 61, 57, 58.2, 59.7, 63.5, 62.7, 57.5, 56.8, 60.2, 59.2, 58.2, 57.8, 61.3]
govern = ['A'] * 5 + ['B'] * 5 + ['C'] * 5
Data = pd.DataFrame({'gdp':gdp, 'year':year, 'unfair':unfair, 'govern':govern})
Data
gdp year unfair govern
0 500 1990 58.0 A
1 600 1991 60.0 A
2 620 1992 61.0 A
3 700 1993 57.0 A
4 900 1994 58.2 A
5 800 1995 59.7 B
6 770 1996 63.5 B
7 765 1997 62.7 B
8 1102 1998 57.5 B
9 1155 1999 56.8 B
10 1320 2000 60.2 C
11 1500 2001 59.2 C
12 1900 2002 58.2 C
13 1950 2003 57.8 C
14 2200 2004 61.3 C
a = Data.loc[[5]]
b = Data.loc[[10]]
a['govern'] = 'A'
b['govern'] = 'B'
Data = pd.concat([Data.loc[:4], a, Data.loc[5:9], b, Data.loc[10:]])
Data
gdp year unfair govern
0 500 1990 58.0 A
1 600 1991 60.0 A
2 620 1992 61.0 A
3 700 1993 57.0 A
4 900 1994 58.2 A
5 800 1995 59.7 A
5 800 1995 59.7 B
6 770 1996 63.5 B
7 765 1997 62.7 B
8 1102 1998 57.5 B
9 1155 1999 56.8 B
10 1320 2000 60.2 B
10 1320 2000 60.2 C
11 1500 2001 59.2 C
12 1900 2002 58.2 C
13 1950 2003 57.8 C
14 2200 2004 61.3 C

- C만 5개여서 불편...

ggplot(Data, aes(x = 'gdp', y = 'unfair')) + geom_point() +\
geom_text(aes(label = 'year'), size = 8, va = 'bottom', ha = 'left') +\
geom_path(aes(color = 'govern'), size = 2, alpha = 0.7)
<ggplot: (194634680408)>
ggplot(Data, aes(x = 'gdp', y = 'unfair')) + geom_point() +\
geom_text(aes(label = 'year'), size = 8, va = 'bottom', ha = 'left') +\
geom_line(aes(color = 'govern'), size = 2, alpha = 0.7)
<ggplot: (194634631623)>

- geom_line과 geom_path의 차이

- geom_path는 선이 year를 따라간다

- geom_line는 선이 왼쪽에서 오른쪽으로 간다(예컨대 1993다음은 1994이지만 1993 바로 오른쪽(같은 색깔중)에 1995가 있어서 1995로 간다)

(1)

- 실제 문제

from plotnine import *
df = pd.read_csv('https://raw.githubusercontent.com/guebin/2021DV/master/_notebooks/gdp_df1.csv')
df
GDP Inequality Government
0 500 56 A
1 550 58 A
2 530 59 A
3 480 61 A
4 550 64 A
5 550 64 B
6 750 66 B
7 560 68 B
8 800 70 B
9 900 65 B
10 900 65 C
11 910 62 C
12 1100 61 C
13 1250 58 C
14 1350 63 C
15 1350 63 D
16 1500 57 D
17 1660 55 D
df2 = pd.read_csv('https://raw.githubusercontent.com/guebin/2021DV/master/_notebooks/gdp_df2.csv', index_col = 0)
df2
A B C D
pop 54232.213 48823.432 46823.453 45232.119
df_ = df2.T.reset_index().rename(columns = {'index':'Government'}).merge(df)
df_
Government pop GDP Inequality
0 A 54232.213 500 56
1 A 54232.213 550 58
2 A 54232.213 530 59
3 A 54232.213 480 61
4 A 54232.213 550 64
5 B 48823.432 550 64
6 B 48823.432 750 66
7 B 48823.432 560 68
8 B 48823.432 800 70
9 B 48823.432 900 65
10 C 46823.453 900 65
11 C 46823.453 910 62
12 C 46823.453 1100 61
13 C 46823.453 1250 58
14 C 46823.453 1350 63
15 D 45232.119 1350 63
16 D 45232.119 1500 57
17 D 45232.119 1660 55
ggplot(df_) + geom_path(aes(x = 'GDP', y = 'Inequality', size = 'pop', color = 'Government'))
<ggplot: (194634670827)>

(2)

df3 = pd.read_csv('https://raw.githubusercontent.com/guebin/2021DV/master/_notebooks/gdp_df3.csv', index_col = 0)
df3
type
A prog
B cons
C prog
D cons
df__ = df3.reset_index().rename(columns = {'index':'Government'}).merge(df_)
df__
Government type pop GDP Inequality
0 A prog 54232.213 500 56
1 A prog 54232.213 550 58
2 A prog 54232.213 530 59
3 A prog 54232.213 480 61
4 A prog 54232.213 550 64
5 B cons 48823.432 550 64
6 B cons 48823.432 750 66
7 B cons 48823.432 560 68
8 B cons 48823.432 800 70
9 B cons 48823.432 900 65
10 C prog 46823.453 900 65
11 C prog 46823.453 910 62
12 C prog 46823.453 1100 61
13 C prog 46823.453 1250 58
14 C prog 46823.453 1350 63
15 D cons 45232.119 1350 63
16 D cons 45232.119 1500 57
17 D cons 45232.119 1660 55
ggplot(df__) + geom_path(aes(x = 'GDP', y = 'Inequality', size = 'pop', color = 'Government', linetype = 'type'))
<ggplot: (194634935881)>

6

df6 = pd.read_csv('https://raw.githubusercontent.com/guebin/2021DV/master/_notebooks/phone.csv')
df6
Date Samsung Apple Huawei Xiaomi Oppo Mobicel Motorola LG Others Realme Google Nokia Lenovo OnePlus Sony Asus
0 2019-10 461 324 136 109 76 81 43 37 135 28 39 14 22 17 20 17
1 2019-11 461 358 167 141 86 61 29 36 141 27 29 20 23 10 19 27
2 2019-12 426 383 143 105 53 45 51 48 129 30 20 26 28 18 18 19
3 2020-01 677 494 212 187 110 79 65 49 158 23 13 19 19 22 27 22
4 2020-02 593 520 217 195 112 67 62 71 157 25 18 16 24 18 23 20
5 2020-03 637 537 246 187 92 66 59 67 145 21 16 24 18 31 22 14
6 2020-04 647 583 222 154 98 59 48 64 113 20 23 25 19 19 23 21
7 2020-05 629 518 192 176 91 87 50 66 150 43 27 15 18 19 19 13
8 2020-06 663 552 209 185 93 69 54 60 140 39 16 16 17 29 25 16
9 2020-07 599 471 214 193 89 78 65 59 130 40 27 25 21 18 18 12
10 2020-08 615 567 204 182 105 82 62 42 129 47 16 23 21 27 23 20
11 2020-09 621 481 230 220 102 88 56 49 143 54 14 15 17 15 19 15
12 2020-10 637 555 232 203 90 52 63 49 140 33 17 20 22 9 22 21

(1)

df6.set_index('Date').\
plot.line(figsize = (10, 7))
<AxesSubplot:xlabel='Date'>

(2)

df6.set_index('Date').\
plot.line(figsize = (10, 15), subplots = True, layout = (8, 2))
plt.tight_layout()

(3)

df6.set_index('Date').stack().reset_index().rename(columns = {'level_1':'variable', 0:'value'}).\
groupby('variable').agg('sum').sort_values('value', ascending = False).\
plot.bar()
<AxesSubplot:xlabel='variable'>

(4)

df6_ = df6.copy()
df6_.Date = df6_.Date.apply(lambda x: str(x)[:4])
_df6 = df6_.query('Date == "2019"').melt(id_vars = 'Date').groupby('variable').agg('sum')
_df6['value'] = _df6['value'] / _df6.value.sum()
_df6
value
variable
Apple 0.224873
Asus 0.013302
Google 0.018581
Huawei 0.094172
LG 0.025549
Lenovo 0.015414
Mobicel 0.039485
Motorola 0.025971
Nokia 0.012669
OnePlus 0.009502
Oppo 0.045397
Others 0.085515
Realme 0.017948
Samsung 0.284628
Sony 0.012035
Xiaomi 0.074958
_df6.rename(columns = {'value':'2019'}).\
plot.pie(y = '2019', figsize = (7, 7))
<AxesSubplot:ylabel='2019'>

(5)

df7 = df6.set_index('Date').stack().reset_index().rename(columns = {'level_1':'variable', 0:'value'}).\
groupby('Date').agg('sum').reset_index()
df7
Date value
0 2019-10 1559
1 2019-11 1635
2 2019-12 1542
3 2020-01 2176
4 2020-02 2138
5 2020-03 2182
6 2020-04 2138
7 2020-05 2113
8 2020-06 2183
9 2020-07 2059
10 2020-08 2165
11 2020-09 2139
12 2020-10 2165
df7.Date = df7.Date.apply(lambda x: str(x)[:4])
df7
Date value
0 2019 1559
1 2019 1635
2 2019 1542
3 2020 2176
4 2020 2138
5 2020 2182
6 2020 2138
7 2020 2113
8 2020 2183
9 2020 2059
10 2020 2165
11 2020 2139
12 2020 2165
df7.groupby('Date').agg('mean').\
plot.bar()
<AxesSubplot:xlabel='Date'>

7

(1)

import matplotlib
matplotlib.rcParams['font.family'] = 'Malgun Gothic' # 한글이 깨지지 않도록 설정
matplotlib.rcParams['axes.unicode_minus'] = False    # 한글이 깨지지 않도록 설정
df7 = pd.read_html('https://ko.wikipedia.org/wiki/%EB%8C%80%ED%95%9C%EB%AF%BC%EA%B5%AD%EC%9D%98_%EC%9D%B8%EA%B5%AC')[17]
df7
지역 출생아 수(천명) 조출생률 합계출산율 거주인구(2021년 주민등록 인구)
0 서울 47.4 5.0 0.64 9588711
1 부산 15.1 4.5 0.75 3369704
2 대구 11.2 4.6 0.81 2406296
3 대전 7.5 5.1 0.81 1457619
4 광주 7.3 5.1 0.81 1444787
5 인천 16.0 5.5 0.83 2936214
6 경기도 77.8 5.9 0.88 13479798
7 전라북도 8.2 4.5 0.91 1796331
8 경상남도 16.8 5.1 0.95 3329623
9 충청북도 8.6 5.4 0.98 1596303
10 울산 6.6 5.8 0.99 1128163
11 경상북도 12.9 4.9 1.00 2635896
12 제주도 4.0 6.0 1.02 674484
13 충청남도 11.9 5.7 1.03 2116452
14 강원도 7.8 5.1 1.04 1536175
15 전라남도 9.7 5.3 1.15 1844148
16 세종 3.5 10.0 1.28 361396
17 대한민국(전체) 272.4 5.3 0.84 51702100
df7.iloc[:-1, :].set_index('지역')
출생아 수(천명) 조출생률 합계출산율 거주인구(2021년 주민등록 인구)
지역
서울 47.4 5.0 0.64 9588711
부산 15.1 4.5 0.75 3369704
대구 11.2 4.6 0.81 2406296
대전 7.5 5.1 0.81 1457619
광주 7.3 5.1 0.81 1444787
인천 16.0 5.5 0.83 2936214
경기도 77.8 5.9 0.88 13479798
전라북도 8.2 4.5 0.91 1796331
경상남도 16.8 5.1 0.95 3329623
충청북도 8.6 5.4 0.98 1596303
울산 6.6 5.8 0.99 1128163
경상북도 12.9 4.9 1.00 2635896
제주도 4.0 6.0 1.02 674484
충청남도 11.9 5.7 1.03 2116452
강원도 7.8 5.1 1.04 1536175
전라남도 9.7 5.3 1.15 1844148
세종 3.5 10.0 1.28 361396
df7.iloc[:-1, :].set_index('지역').plot.pie(y = '출생아 수(천명)')
<AxesSubplot:ylabel='출생아 수(천명)'>

(2)

df8 = pd.read_html('https://ko.wikipedia.org/wiki/%EB%8C%80%ED%95%9C%EB%AF%BC%EA%B5%AD%EC%9D%98_%EC%9D%B8%EA%B5%AC')[18]
df8
Unnamed: 0 2019 2018 2017 2016 2015 2014 2013 2012 2011 2010 2009 2008 2007 2006 2005 2004 2003 2002 2001
0 전국 0.918 0.977 1.052 1.172 1.239 1.205 1.187 1.297 1.244 1.226 1.149 1.192 1.259 1.132 1.085 1.164 1.191 1.178 1.309
1 서울특별시 0.717 0.761 0.836 0.940 1.001 0.983 0.968 1.059 1.014 1.015 0.962 1.010 1.068 0.980 0.932 1.015 1.014 1.006 1.111
2 부산광역시 0.827 0.899 0.976 1.095 1.139 1.090 1.049 1.135 1.078 1.045 0.940 0.980 1.024 0.915 0.887 0.953 0.988 0.975 1.103
3 대구광역시 0.932 0.987 1.067 1.186 1.216 1.169 1.127 1.217 1.146 1.109 1.029 1.072 1.137 1.011 1.001 1.087 1.116 1.076 1.216
4 인천광역시 0.940 1.006 1.007 1.144 1.216 1.212 1.195 1.301 1.232 1.214 1.143 1.186 1.257 1.116 1.075 1.158 1.213 1.185 1.324
5 광주광역시 0.913 0.972 1.053 1.168 1.207 1.199 1.170 1.295 1.234 1.223 1.137 1.198 1.262 1.152 1.105 1.203 1.278 1.264 1.421
6 대전광역시 0.883 0.952 1.075 1.192 1.277 1.250 1.234 1.315 1.261 1.205 1.156 1.215 1.274 1.158 1.107 1.181 1.221 1.207 1.330
7 울산광역시 1.084 1.131 1.261 1.418 1.486 1.437 1.391 1.481 1.393 1.369 1.308 1.338 1.403 1.242 1.186 1.241 1.280 1.242 1.423
8 세종특별자치시 1.472 1.566 1.668 1.821 1.893 1.354 1.435 1.597 - - - - - - - - - - -
9 경기도 0.943 1.002 1.069 1.194 1.272 1.241 1.226 1.355 1.314 1.309 1.226 1.285 1.361 1.239 1.183 1.280 1.321 1.305 1.437
10 강원도 1.082 1.067 1.123 1.237 1.311 1.248 1.249 1.374 1.338 1.313 1.248 1.253 1.356 1.202 1.188 1.261 1.279 1.317 1.413
11 충청북도 1.050 1.172 1.235 1.358 1.414 1.363 1.365 1.485 1.428 1.402 1.317 1.319 1.398 1.233 1.195 1.272 1.270 1.294 1.426
12 충청남도 1.112 1.186 1.276 1.395 1.480 1.421 1.442 1.571 1.496 1.479 1.408 1.444 1.506 1.356 1.267 1.357 1.358 1.361 1.532
13 전라북도 0.971 1.044 1.151 1.251 1.352 1.329 1.320 1.440 1.405 1.374 1.279 1.305 1.380 1.213 1.184 1.239 1.274 1.275 1.426
14 전라남도 1.234 1.240 1.325 1.466 1.549 1.497 1.518 1.642 1.568 1.537 1.445 1.449 1.542 1.337 1.290 1.360 1.389 1.391 1.566
15 경상북도 1.089 1.167 1.256 1.396 1.464 1.408 1.379 1.489 1.434 1.377 1.274 1.313 1.369 1.208 1.173 1.203 1.253 1.232 1.402
16 경상남도 1.046 1.122 1.227 1.358 1.437 1.409 1.367 1.503 1.446 1.413 1.323 1.368 1.434 1.254 1.189 1.266 1.290 1.272 1.417
17 제주특별자치도 1.145 1.220 1.305 1.432 1.477 1.481 1.427 1.598 1.487 1.463 1.378 1.386 1.489 1.372 1.310 1.365 1.438 1.394 1.564
df9 = df8.rename(columns = {'Unnamed: 0':'지역'}).iloc[1:, :].\
sort_values('지역').set_index('지역').\
applymap(lambda x: float(x) if x != '-' else 0)
df9
2019 2018 2017 2016 2015 2014 2013 2012 2011 2010 2009 2008 2007 2006 2005 2004 2003 2002 2001
지역
강원도 1.082 1.067 1.123 1.237 1.311 1.248 1.249 1.374 1.338 1.313 1.248 1.253 1.356 1.202 1.188 1.261 1.279 1.317 1.413
경기도 0.943 1.002 1.069 1.194 1.272 1.241 1.226 1.355 1.314 1.309 1.226 1.285 1.361 1.239 1.183 1.280 1.321 1.305 1.437
경상남도 1.046 1.122 1.227 1.358 1.437 1.409 1.367 1.503 1.446 1.413 1.323 1.368 1.434 1.254 1.189 1.266 1.290 1.272 1.417
경상북도 1.089 1.167 1.256 1.396 1.464 1.408 1.379 1.489 1.434 1.377 1.274 1.313 1.369 1.208 1.173 1.203 1.253 1.232 1.402
광주광역시 0.913 0.972 1.053 1.168 1.207 1.199 1.170 1.295 1.234 1.223 1.137 1.198 1.262 1.152 1.105 1.203 1.278 1.264 1.421
대구광역시 0.932 0.987 1.067 1.186 1.216 1.169 1.127 1.217 1.146 1.109 1.029 1.072 1.137 1.011 1.001 1.087 1.116 1.076 1.216
대전광역시 0.883 0.952 1.075 1.192 1.277 1.250 1.234 1.315 1.261 1.205 1.156 1.215 1.274 1.158 1.107 1.181 1.221 1.207 1.330
부산광역시 0.827 0.899 0.976 1.095 1.139 1.090 1.049 1.135 1.078 1.045 0.940 0.980 1.024 0.915 0.887 0.953 0.988 0.975 1.103
서울특별시 0.717 0.761 0.836 0.940 1.001 0.983 0.968 1.059 1.014 1.015 0.962 1.010 1.068 0.980 0.932 1.015 1.014 1.006 1.111
세종특별자치시 1.472 1.566 1.668 1.821 1.893 1.354 1.435 1.597 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000 0.000
울산광역시 1.084 1.131 1.261 1.418 1.486 1.437 1.391 1.481 1.393 1.369 1.308 1.338 1.403 1.242 1.186 1.241 1.280 1.242 1.423
인천광역시 0.940 1.006 1.007 1.144 1.216 1.212 1.195 1.301 1.232 1.214 1.143 1.186 1.257 1.116 1.075 1.158 1.213 1.185 1.324
전라남도 1.234 1.240 1.325 1.466 1.549 1.497 1.518 1.642 1.568 1.537 1.445 1.449 1.542 1.337 1.290 1.360 1.389 1.391 1.566
전라북도 0.971 1.044 1.151 1.251 1.352 1.329 1.320 1.440 1.405 1.374 1.279 1.305 1.380 1.213 1.184 1.239 1.274 1.275 1.426
제주특별자치도 1.145 1.220 1.305 1.432 1.477 1.481 1.427 1.598 1.487 1.463 1.378 1.386 1.489 1.372 1.310 1.365 1.438 1.394 1.564
충청남도 1.112 1.186 1.276 1.395 1.480 1.421 1.442 1.571 1.496 1.479 1.408 1.444 1.506 1.356 1.267 1.357 1.358 1.361 1.532
충청북도 1.050 1.172 1.235 1.358 1.414 1.363 1.365 1.485 1.428 1.402 1.317 1.319 1.398 1.233 1.195 1.272 1.270 1.294 1.426
lst = df7.iloc[:-1, :].sort_values('지역').loc[:, ['지역', '합계출산율']].\
rename(columns = {'합계출산율':'2020'}).set_index('지역').index.tolist()
lst
['강원도',
 '경기도',
 '경상남도',
 '경상북도',
 '광주',
 '대구',
 '대전',
 '부산',
 '서울',
 '세종',
 '울산',
 '인천',
 '전라남도',
 '전라북도',
 '제주도',
 '충청남도',
 '충청북도']

- matplotlib 사용(untidy data)

df7.iloc[:-1, :].sort_values('지역').loc[:, ['지역', '합계출산율']].\
rename(columns = {'합계출산율':'2020'}).set_index('지역').\
rename(index = dict(zip(lst, df9.index))).reset_index().\
merge(df9.reset_index()).set_index('지역').T.\
plot.line(figsize = (10, 6))
<AxesSubplot:>

- plotly 사용(tidy data)

# rename(columns = {'합계출산율':'2020'}).set_index('지역').\
# rename(index = dict(zip(lst, df9.index))).reset_index().\
# merge(df9.reset_index()).melt(id_vars = '지역').\
# rename(columns = {'variable':'year', 'value':'birth_rate'}).\
# plot.line(x = 'year', y ='birth_rate', color = '지역', backend = 'plotly')