ESIMERKKI: Ultraviolettisäteily#
Työn rakenne#
Yksinkertainen projekti noudattaa yleensä simppeliä perusrakennetta:
Määritetään kiinnostuksen kohde (tutkimuskysymys)
Etsitään aineistoa (datankeruu)
Tarkastellaan löydöksiä (analyysi)
Arvioidaan, kritisoidaan (tulokset ja johtopäätökset)
Selitetään tarpeen mukaan käytetyt aineistot (lähteet)
1. Tutkimuskysymys#
Maapallon elinkelpoisuus on kiinni jatkuvasta energiavuosta, joka syntyy Auringossa ja vaeltaa avaruuden halki planeetallemme. Tuo jatkuva energian hyökyaalto koostuu kuitenkin monenlaisista aallonpituuksista ja hiukkasista, joiden suhteet eivät ole välttämättä lainkaan intuitiivisia satunnaiselle tarkastelijalle.
Esimerkiksi, onko päivänvalon UV-indeksillä ja ilmaston lämpötilakäytöksellä yhteyttä toisiinsa?
UV-indeksistä voi lukea lisää https://www.ilmatieteenlaitos.fi/ultraviolettisateily. Relevanttia on, että arvon ylittäessä kolme alkaa olla tarpeellista suojata ihoaan ja yli kuusi kertoo voimakkaasta säteilystä.
2. Aineisto#
# Tuodaan tarvittavat työkalukirjastot.
import pandas as pd
import matplotlib.pyplot as plt
Käytetään tarkasteluun Helsingin Kumpulassa sijaitsevan havaintoaseman aineistoja Ilmatieteen laitokselta. Tiedot saatavilla täältä: https://www.ilmatieteenlaitos.fi/havaintojen-lataus
Säteilyaineisto mitataan tiuhaan, joten tiedostoista tulee helposti isoja lyhyilläkin aikaväleillä. Ilmatieteen laitoksen portaali tuntuu rajoittavan lataamisen alle 20000 riviin kerrallaan, joten ladataan aineisto vuosi kerrallaan (~9000 tuntimittausta per) ja liitetään sitten yhteen isommaksi tarkastelua varten.
# Tuodaan haluttu säteilydata palasina.
# Huomaa lukukomennon sisään lisätty 'parse'-parametri, jolla luodaan tiedostoon yhdistelmä päivämääräsarakkeista,
# jolloin saadaan juoksevasti kasvava luku tulevan visualisoinnin aika-akseliksi.
K20 = pd.read_csv("https://raw.githubusercontent.com/opendata-education/Tyopajat/main/materiaali/data/Kum2020.csv",
parse_dates = {"Aika":["Vuosi", "Kk", "Pv", "Klo"]}, keep_date_col = True)
K19 = pd.read_csv("https://raw.githubusercontent.com/opendata-education/Tyopajat/main/materiaali/data/Kum2019.csv",
parse_dates = {"Aika":["Vuosi", "Kk", "Pv", "Klo"]}, keep_date_col = True)
K18 = pd.read_csv("https://raw.githubusercontent.com/opendata-education/Tyopajat/main/materiaali/data/Kum2018.csv",
parse_dates = {"Aika":["Vuosi", "Kk", "Pv", "Klo"]}, keep_date_col = True)
K17 = pd.read_csv("https://raw.githubusercontent.com/opendata-education/Tyopajat/main/materiaali/data/Kum2017.csv",
parse_dates = {"Aika":["Vuosi", "Kk", "Pv", "Klo"]}, keep_date_col = True)
K16 = pd.read_csv("https://raw.githubusercontent.com/opendata-education/Tyopajat/main/materiaali/data/Kum2016.csv",
parse_dates = {"Aika":["Vuosi", "Kk", "Pv", "Klo"]}, keep_date_col = True)
K15 = pd.read_csv("https://raw.githubusercontent.com/opendata-education/Tyopajat/main/materiaali/data/Kum2015.csv",
parse_dates = {"Aika":["Vuosi", "Kk", "Pv", "Klo"]}, keep_date_col = True)
K14 = pd.read_csv("https://raw.githubusercontent.com/opendata-education/Tyopajat/main/materiaali/data/Kum2014.csv",
parse_dates = {"Aika":["Vuosi", "Kk", "Pv", "Klo"]}, keep_date_col = True)
K13 = pd.read_csv("https://raw.githubusercontent.com/opendata-education/Tyopajat/main/materiaali/data/Kum2013.csv",
parse_dates = {"Aika":["Vuosi", "Kk", "Pv", "Klo"]}, keep_date_col = True)
K12 = pd.read_csv("https://raw.githubusercontent.com/opendata-education/Tyopajat/main/materiaali/data/Kum2012.csv",
parse_dates = {"Aika":["Vuosi", "Kk", "Pv", "Klo"]}, keep_date_col = True)
K11 = pd.read_csv("https://raw.githubusercontent.com/opendata-education/Tyopajat/main/materiaali/data/Kum2011.csv",
parse_dates = {"Aika":["Vuosi", "Kk", "Pv", "Klo"]}, keep_date_col = True)
K10 = pd.read_csv("https://raw.githubusercontent.com/opendata-education/Tyopajat/main/materiaali/data/Kum2010.csv",
parse_dates = {"Aika":["Vuosi", "Kk", "Pv", "Klo"]}, keep_date_col = True)
K09 = pd.read_csv("https://raw.githubusercontent.com/opendata-education/Tyopajat/main/materiaali/data/Kum2009.csv",
parse_dates = {"Aika":["Vuosi", "Kk", "Pv", "Klo"]}, keep_date_col = True)
K08 = pd.read_csv("https://raw.githubusercontent.com/opendata-education/Tyopajat/main/materiaali/data/Kum2008.csv",
parse_dates = {"Aika":["Vuosi", "Kk", "Pv", "Klo"]}, keep_date_col = True)
K07 = pd.read_csv("https://raw.githubusercontent.com/opendata-education/Tyopajat/main/materiaali/data/Kum2007.csv",
parse_dates = {"Aika":["Vuosi", "Kk", "Pv", "Klo"]}, keep_date_col = True)
K06 = pd.read_csv("https://raw.githubusercontent.com/opendata-education/Tyopajat/main/materiaali/data/Kum2006.csv",
parse_dates = {"Aika":["Vuosi", "Kk", "Pv", "Klo"]}, keep_date_col = True)
# Tarkastetaan miltä vuositiedot näyttävät. Miten tiheään havainnot on kerätty?
K20.head(10)
Aika | Vuosi | Kk | Pv | Klo | Aikavyöhyke | Hajasäteily (W/m2) | Suorasäteily (W/m2) | Kokonaissäteily (W/m2) | Ilmakehän pitkäaaltosäteily (W/m2) | Maanpinnan pitkäaaltosäteily (W/m2) | Säteilytase (W/m2) | Heijastunutsäteily (W/m2) | Paisteaika (s) | UV-B-säteily (index) | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 2020-01-01 00:00:00 | 2020 | 1 | 1 | 00:00 | UTC | -2.2 | 0.5 | -2.1 | 220.4 | NaN | NaN | NaN | 0.0 | 0.0 |
1 | 2020-01-01 01:00:00 | 2020 | 1 | 1 | 01:00 | UTC | -2.1 | 0.3 | -2.0 | 225.3 | NaN | NaN | NaN | 0.0 | 0.0 |
2 | 2020-01-01 02:00:00 | 2020 | 1 | 1 | 02:00 | UTC | -2.0 | 0.7 | -1.9 | 230.0 | NaN | NaN | NaN | 0.0 | 0.0 |
3 | 2020-01-01 03:00:00 | 2020 | 1 | 1 | 03:00 | UTC | -1.8 | 0.4 | -1.8 | 239.8 | NaN | NaN | NaN | 0.0 | 0.0 |
4 | 2020-01-01 04:00:00 | 2020 | 1 | 1 | 04:00 | UTC | -2.2 | -0.4 | -2.0 | 254.9 | NaN | NaN | NaN | 0.0 | 0.0 |
5 | 2020-01-01 05:00:00 | 2020 | 1 | 1 | 05:00 | UTC | -1.4 | 1.0 | -1.4 | 240.8 | NaN | NaN | NaN | 0.0 | 0.0 |
6 | 2020-01-01 06:00:00 | 2020 | 1 | 1 | 06:00 | UTC | -1.7 | -0.3 | -1.5 | 266.7 | NaN | NaN | NaN | 0.0 | 0.0 |
7 | 2020-01-01 07:00:00 | 2020 | 1 | 1 | 07:00 | UTC | 0.0 | 1.0 | 0.3 | 313.9 | NaN | NaN | NaN | 0.0 | 0.0 |
8 | 2020-01-01 08:00:00 | 2020 | 1 | 1 | 08:00 | UTC | 11.3 | 0.5 | 11.5 | 283.3 | NaN | NaN | NaN | 0.0 | 0.1 |
9 | 2020-01-01 09:00:00 | 2020 | 1 | 1 | 09:00 | UTC | 23.4 | 0.4 | 23.6 | 317.3 | NaN | NaN | NaN | 0.0 | 0.1 |
# Yhdistetään äskeiset tiedot yhdeksi pidemmäksi aikasarjaksi. 'Concatenate' yhdistää asiat oletusarvoisesti
# luetellussa järjestyksessä, joten annetaan sille vuositiedot kronologisesti.
KumSat = pd.concat([K06, K07, K08, K09, K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K20])
# Korjataan äskeisen liitoksen rivien järjestysluvut estetiikan nimissä.
KumSat = KumSat.reset_index(drop = True)
# Tarkastetaan kokonaisuuden yhä näyttävän miltä kuuluukin.
print("Uudessa muuttujassa on " + repr(len(KumSat)) + " riviä tietoja.")
KumSat.tail(5)
Uudessa muuttujassa on 131511 riviä tietoja.
Aika | Vuosi | Kk | Pv | Klo | Aikavyöhyke | Hajasäteily (W/m2) | Suorasäteily (W/m2) | Kokonaissäteily (W/m2) | Ilmakehän pitkäaaltosäteily (W/m2) | Maanpinnan pitkäaaltosäteily (W/m2) | Säteilytase (W/m2) | Heijastunutsäteily (W/m2) | Paisteaika (s) | UV-B-säteily (index) | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
131506 | 2020-12-31 20:00:00 | 2020 | 12 | 31 | 20:00 | UTC | -1.4 | 0.4 | -1.1 | 293.7 | NaN | NaN | NaN | 0.0 | 0.0 |
131507 | 2020-12-31 21:00:00 | 2020 | 12 | 31 | 21:00 | UTC | -2.3 | -0.1 | -2.1 | 234.7 | NaN | NaN | NaN | 0.0 | 0.0 |
131508 | 2020-12-31 22:00:00 | 2020 | 12 | 31 | 22:00 | UTC | -1.3 | 0.9 | -1.2 | 281.4 | NaN | NaN | NaN | 0.0 | 0.0 |
131509 | 2020-12-31 23:00:00 | 2020 | 12 | 31 | 23:00 | UTC | -1.2 | 1.2 | -0.6 | 301.6 | NaN | NaN | NaN | 0.0 | 0.0 |
131510 | 2021-01-01 00:00:00 | 2021 | 1 | 1 | 00:00 | UTC | -0.9 | 1.3 | -0.4 | 316.7 | NaN | NaN | NaN | 0.0 | 0.0 |
3. Analyysi#
# Tarkastellaan miltä kokonaisuus näyttää kuvaajassa.
plt.figure(figsize = (40, 10))
plt.scatter( KumSat["Aika"], KumSat["UV-B-säteily (index)"])
plt.axhline(3, linestyle='--', label = "UVI 3+", color='k', alpha = 0.5) # Raja suojautumistarpeelle.
plt.axhline(6, linestyle='--', label = "UVI 6+", color='k', alpha = 0.5) # Raja voimakkaalle säteilylle.
plt.title("UV-B-säteilyindeksi Helsingin Kumpulassa 2006-2020 \n", fontsize = 20)
plt.show()
Hyvältä näyttää, kertymän olettaisi osuvan kesäajalle ja keskelle päivää. Osuuko silmiisi poikkeavia ajankohtia joita voisi olla kiinnostavaa tarkastella lähemmin?
# Vertailuksi kokonaissäteilyn vuo. Mikä ero näillä suureilla on?
plt.figure(figsize = (40, 10))
plt.scatter( KumSat["Aika"], KumSat["Kokonaissäteily (W/m2)"])
plt.title("Kokonaissäteily (W/m2) Helsingin Kumpulassa 2006-2020 \n", fontsize = 20)
plt.show()
Vuositasolla asiat ovat kohtalaisen vakaita, joten kaivaudutaan yksityiskohtaisempiin kuvauksiin vaihtelujen havainnollistamiseksi.
# Yksittäisten kuukausien kohdalla.
# Jaetaan data. Hakutermi on tässä hipsuissa, koska Kk-sarake ei ole tyypiltään numero. Tämän voisi halutessaan
# korjata muuttamalla mokomat luvuiksi string-tekstin sijaan.
Maa = K20.query("Kk == '3'")
Hei = K20.query("Kk == '7'")
# Luodaan vertailuun soveltuva kuvaaja.
plt.figure(figsize = (30, 10))
plt.plot(Maa["Aika"], Maa["UV-B-säteily (index)"], alpha = 0.5, c = "y")
plt.scatter(Maa["Aika"], Maa["UV-B-säteily (index)"], label = "Maaliskuu", c = "r")
plt.twiny() # Lisätään toinen aika-akseli, koska käytetyt arvot eivät ole yhteneviä.
plt.plot(Hei["Aika"], Hei["UV-B-säteily (index)"], alpha = 0.5, c = "b")
plt.scatter(Hei["Aika"], Hei["UV-B-säteily (index)"], label = "Heinäkuu", c = "g")
# Vaakaviiva kolmen kohdalle kuvaamaan merkittävää rajaa UV-indeksissä.
plt.axhline(3, linestyle='--', label = "UVI 3+", color='k', alpha = 0.5)
plt.title("UV-B-säteilyindeksi Helsingin Kumpulassa 2020 \n", fontsize = 30)
plt.figlegend(loc = "center right", fontsize = 25)
plt.show()
Tätä näkymää voidaan nyt verrata muihin aineistoihin, kuten lämpötilaan tai pilvisyyteen kunakin päivänä.
# Tuodaan säätietoja samalta mittausasemalta.
Saa20 = pd.read_csv("https://raw.githubusercontent.com/opendata-education/Tyopajat/main/materiaali/data/KumSaa2020.csv",
parse_dates = {"Aika":["Vuosi", "Kk", "Pv", "Klo"]}, keep_date_col = True)
# Tarkastellaan miltä data näyttää.
Saa20.head()
Aika | Vuosi | Kk | Pv | Klo | Aikavyöhyke | Pilvien määrä (1/8) | Ilmanpaine (msl) (hPa) | Sademäärä (mm) | Suhteellinen kosteus (%) | Sateen intensiteetti (mm/h) | Lumensyvyys (cm) | Ilman lämpötila (degC) | Kastepistelämpötila (degC) | Näkyvyys (m) | Tuulen suunta (deg) | Puuskanopeus (m/s) | Tuulen nopeus (m/s) | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 2020-01-01 00:00:00 | 2020 | 1 | 1 | 00:00 | UTC | 0.0 | 1011.5 | 0.0 | 90.0 | 0.0 | 0.0 | -1.7 | -3.1 | 22520.0 | 242.0 | 5.7 | 3.7 |
1 | 2020-01-01 01:00:00 | 2020 | 1 | 1 | 01:00 | UTC | 0.0 | 1011.3 | 0.0 | 89.0 | 0.0 | 0.0 | -1.1 | -2.7 | 41970.0 | 249.0 | 6.5 | 4.9 |
2 | 2020-01-01 02:00:00 | 2020 | 1 | 1 | 02:00 | UTC | 0.0 | 1010.9 | 0.0 | 86.0 | 0.0 | 0.0 | -0.5 | -2.5 | 50000.0 | 263.0 | 8.6 | 5.7 |
3 | 2020-01-01 03:00:00 | 2020 | 1 | 1 | 03:00 | UTC | 1.0 | 1010.7 | 0.0 | 85.0 | 0.0 | 0.0 | -0.2 | -2.4 | 50000.0 | 260.0 | 8.7 | 5.4 |
4 | 2020-01-01 04:00:00 | 2020 | 1 | 1 | 04:00 | UTC | 1.0 | 1010.1 | 0.0 | 85.0 | 0.0 | 0.0 | -0.1 | -2.2 | 50000.0 | 241.0 | 6.6 | 4.8 |
# Lämpötilan kanssa koko vuodelta.
plt.figure(figsize = (200, 10))
plt.plot(K20["Aika"], K20["UV-B-säteily (index)"], alpha = 0.5, c = "y")
plt.scatter(K20["Aika"], K20["UV-B-säteily (index)"], label = "UVI", c = "r")
plt.axhline(3, linestyle='--', label = "UVI 3+", color='k', alpha = 0.5)
plt.twinx() # Lisätään toinen arvoakseli, koska käytetyt arvot eivät ole yhteneviä.
plt.plot(Saa20["Aika"], Saa20["Ilman lämpötila (degC)"], alpha = 0.5, c = "b")
plt.scatter(Saa20["Aika"], Saa20["Ilman lämpötila (degC)"], label = "Tuntilämpötila", c = "g")
plt.axhline(0, linestyle='--', label = "0 deg C", color='pink', alpha = 0.5)
plt.title("UV-B-säteilyindeksi ja ilman lämpötila Helsingin Kumpulassa 2020 \n", fontsize = 30)
plt.figlegend(loc = "upper right", fontsize = 25)
plt.show()
# Kuva on iso, sitä kannattaa tarkastella uudessa välilehdessä. Entä jos vaihdat alun "figsize" arvoja?
# Myös pilvien kanssa heinäkuulta.
plt.figure(figsize = (40, 15))
UV = K20.query("Kk == '7'")
C = Saa20.query("Kk == '7'")
plt.subplot(2,1,1)
plt.plot(UV["Aika"], UV["UV-B-säteily (index)"], alpha = 0.5, c = "y")
plt.scatter(UV["Aika"], UV["UV-B-säteily (index)"], label = "UVI", c = "r")
plt.axhline(3, linestyle='--', label = "UVI 3+", color='k', alpha = 0.5)
plt.twinx() # Lisätään toinen arvoakseli, koska käytetyt arvot eivät ole yhteneviä.
plt.plot(C["Aika"], C["Ilman lämpötila (degC)"], alpha = 0.5, c = "b")
plt.scatter(C["Aika"], C["Ilman lämpötila (degC)"], label = "Tuntilämpötila", c = "g")
plt.axhline(0, linestyle='--', label = "0 deg C", color='pink', alpha = 0.5)
plt.subplot(2,1,2)
plt.plot(C["Aika"], C["Pilvien määrä (1/8)"], alpha = 0.5, c = "black")
plt.scatter(C["Aika"], C["Pilvien määrä (1/8)"], label = "Pilvisyys", c = "blue")
plt.suptitle("UV-B-säteilyindeksi, ilman lämpötila ja pilvisyys Helsingin Kumpulassa heinäkuussa 2020 \n", fontsize = 30)
plt.figlegend(loc = "center right", fontsize = 25)
plt.show()
Voiko UVI:n ja lämpötilan välille vetää suoraa johtopäätöstä? Voiko korkeiden tai matalien UVI-päivien kohdalta todeta jotain yhteyttä lämpötilan käytökseen?
4. Arviointi#
Kumpulan säähavaintoaseman aurinkosäteilymittareita työssään.
Ilmatieteen laitoksen sivuilta voi vilkaista koeasemien asetelmia. Auringon säteilyn mittaaminen on kohtalaisen suoraviivaista energian ja ajan havainnointia, mutta pilvisyyden mittauksen huomaamme jännittävän arkaaiseksi: yllä käytetty 0-8 asteikko pohjaa yksinkertaisesti visuaaliseen havaintoon siitä, miten suuri osa taivaankannesta on peitossa.
Havaintojen määrä ja tiheys antaa tässä tapauksessa kohtalaisesti luottoa niiden paikkaansapitävyyteen (olettaen mahdollisten systemaattisten virheiden poiston IL:n toimesta). Havaitut ilmiöt myös toistuvat useissa paikoissa.
Entä jos mukaan ottaisi tuulen? Ilmankosteuden?
5. Lähteet#
https://www.ilmatieteenlaitos.fi/havaintojen-lataus
https://www.ilmatieteenlaitos.fi/ultraviolettisateily
https://www.stuk.fi/aiheet/uv-sateily-aurinko-ja-solarium/auringon-ultraviolettisateily
https://www.ilmatieteenlaitos.fi/havaintosuureet#auringonsateily