Средњошколци у Републици Србији¶
Geopandas библиотека коју ћемо користити у овој свесци може бити проблематична за инсталацију на различитим системима и, како бисте избегли потенцијалне проблеме, препоручујемо да ову свеску отворите помоћу сервиса binder тако што ћеш отићи на овај линк https://mybinder.org/v2/gh/Petlja/JupyterRadneSveskeSrb-files/master.
У овом, последњем сегменту на тему средњошколског образовања у Србији, наставићемо да радимо на отвореним подацима Министарства за просвету, науку и технолошки развој: http://opendata.mpn.gov.rs. Циљ нам је да визуализујемо претходно обрађене и припремљене податаке у којима смо видели везу између образовања и географских ентитета попут општина и округа. Специјално:
- користићемо податке о просторним јединицама Националне инфраструктуре геопросторних података: https://opendata.geosrbija.rs/
- упознаћемо се са новом библиотеком функција geopandas
- упознаћемо се са новим типом визуализација на мапама.
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import geopandas as gpd
Нова библиотека geopandas биће нам од користи за учитавање табела у којима очекујемо да ће се наћи подаци који садрже геометријске облике. Генерално, иако у пајтону можемо читати податке из фајлова на много различитих начина, предности коришћења библиотека попут библиотеке pandas или geopandas леже у томе што је са подацима аутоматски учитан и препознат и њихов формат, као и чињеница да обе библиотеке садрже прегршт функција оптимизованих за податке са којима знају да баратају. Тако када у подацима који су нам на располагању имамо податке о геометрији, geopandas је одличан избор.
Фајл 'okrug.csv' садржи информације о облику округа (фајл је преузет са платформе https://opendata.geosrbija.rs/ уз минималне измене у називима округа зарад слагања са подацима које ћемо користити у наставку) и учитаћемо га користећи функцију read_file:
srbmapa_df = gpd.read_file('data/srednjoskolci data/okrug.csv', encoding='UTF-8')
Као и у библиотеци pandas, на исте начине можемо завирити у учитане податке:
srbmapa_df.head(2)
Првих пар колона садржи податке о имену округа и региона ћириличним и латиничним писмом, и имамо пар колона са индексима округа и региона. Међутим, последње две колоне изгледају мање познато (у односу на табеле са којима смо се сусретали раије) и то су заправо колоне које нам дају информације о геометријском облику округа. Користећи опцију .info() можемо испитати како су те колоне препознате:
srbmapa_df.info()
Последња колона препозната је као посебан геометријски тип података, овде можете прочитати више о томе.
Једна од практичнијих повластица коришћења ове библиотеке је што цртање Србије и управних округа можемо урадити врло једноставно:
srbmapa_df.plot()
plt.show()
Али, ми не желимо да цртамо само Србију и њене округе, већ бисмо волели да одређене округе обојимо у складу са подацима по окрузима, за то учитавамо ретходно припремљене податке о образовању по окрузима:
prosvetni_podaci_okruzi = pd.read_csv('data/srednjoskolci data/MPNTR_podaci_po_okruzima.csv',encoding='UTF-16')
prosvetni_podaci_okruzi.head(2)
Како се колона о окрузима разликује у ове две табеле map_df и df, морамо их усагласити пре него што их спојимо. Примећујемо да су називи колона другачији - у једном случају Okrug а у другом okrug_imel, али и садржај - у само једној од табела називи округа су исписани свим великим словима.
prosvetni_podaci_okruzi['Okrug'] = [text.upper() for text in list(prosvetni_podaci_okruzi['Okrug'])]
prosvetni_podaci_okruzi = prosvetni_podaci_okruzi.rename(columns={'Okrug':'okrug_imel'})
prosvetni_podaci_okruzi.head(2)
Када смо усагласили табеле, можемо наставити и спојити их по колони која је заједничка, сада се она зове 'okrug_imel':
srbmapa_podaci = pd.merge(srbmapa_df,prosvetni_podaci_okruzi,on='okrug_imel')
srbmapa_podaci.head(2)
Нова табела сада за сваки округ поред геометријског облика садржи и информације о образовању. Додаћемо још пар колона које можемо визуализовати:
srbmapa_podaci['Procenat gimnazijalaca'] = round(100*srbmapa_podaci['Ukupno gimnazijalaca']/srbmapa_podaci['Broj učenika'],2)
srbmapa_podaci['Broj ucenika po nastavniku'] = srbmapa_podaci['Broj učenika']/srbmapa_podaci['Broj nastavnika - bez zamena']
srbmapa_podaci['Procenat devojcica'] = round(100*srbmapa_podaci['Broj devojčica']/srbmapa_podaci['Broj učenika'],2)
Сада број образовних профила доступних по округу можемо нацртати доста једноставно:
srbmapa_podaci.plot(column='Obrazovni profil')
plt.show()
Али за корисну и читљиву визуализацију ово није довољно - није јасно шта су различите боје и колика разлика у бројевима води разлици од жуте боје до тамно плаве, такође, уз мапу нам нису потребне х и у оса, али би наслов могао бити од користи, то ћемо урадити у наредним редовима:
srbmapa_podaci.plot(column='Obrazovni profil', legend=True)
plt.axis('off')
plt.title('Broj obrazovnih profila po okruzima u Srbiji\n\n', fontdict={'fontsize': '15', 'fontweight': '3'})
plt.annotate(' Izvori podataka: \n http://opendata.mpn.gov.rs/\n https://opendata.geosrbija.rs/',xy=(0.15, 0.15), xycoords='figure fraction', horizontalalignment='left', verticalalignment='top', fontsize=12, color='#555555');
Можемо и да променимо величину слике, и дефинишемо неку другу палету боја, за избор доступних палета видети нпр. https://scipy-cookbook.readthedocs.io/items/Matplotlib_Show_colormaps.html
fig, ax = plt.subplots(1,figsize=(10,6))
srbmapa_podaci.plot(column='Obrazovni profil', ax=ax, legend=True, cmap='Purples', linewidth=1, edgecolor='0.9')
ax.axis('off')
ax.set_title('Broj obrazovnih profila po okruzima u Srbiji\n\n', fontdict={'fontsize': '15', 'fontweight': '3'})
ax.annotate(' Izvori podataka: \n http://opendata.mpn.gov.rs/\n https://opendata.geosrbija.rs/',xy=(0.15, 0.15), xycoords='figure fraction', horizontalalignment='left', verticalalignment='top', fontsize=12, color='#555555');
Претходних пар линија кода можемо спаковати у функцију, тако да само навођењем варијабле коју хоћемо да унесемо на мапу можемо да истражимо како претходни подаци изгледају:
def nacrtajmapu(podaci, variable):
fig, ax = plt.subplots(1,figsize=(10,6))
podaci.plot(column=variable, ax=ax, legend=True, cmap='Purples', linewidth=1, edgecolor='0.9')
ax.axis('off')
ax.set_title(variable+' u Srbiji', fontdict={'fontsize': '15', 'fontweight': '3'})
ax.annotate(' Izvori podataka: \n http://opendata.mpn.gov.rs/\n https://opendata.geosrbija.rs/',xy=(0.15, 0.15), xycoords='figure fraction', horizontalalignment='left', verticalalignment='top', fontsize=12, color='#555555');
nacrtajmapu(srbmapa_podaci, 'Područje rada')
nacrtajmapu(srbmapa_podaci, 'Procenat gimnazijalaca')
nacrtajmapu(srbmapa_podaci, 'Broj ucenika po nastavniku')
Задаци¶
1. Израчунајте проценат девојчица у средњим школама за сваки округ и визуализујте податке на мапи.
2. Израчунајте просечан број ђака по одељењу у сваком округу и представите те податке на мапи и варирајте палету боја за најјасније представљање резултата.