ESIMERKKI: Ultraviolettisäteily#

Työn rakenne#

Yksinkertainen projekti noudattaa yleensä simppeliä perusrakennetta:

  1. Määritetään kiinnostuksen kohde (tutkimuskysymys)

  2. Etsitään aineistoa (datankeruu)

  3. Tarkastellaan löydöksiä (analyysi)

  4. Arvioidaan, kritisoidaan (tulokset ja johtopäätökset)

  5. 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()
../_images/b18b424f7ad9964961d35527ed77835001ccb8f21606feca6fe2be9491abf5f8.png

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()
../_images/941714a9d823625a16a6137818d65d6e166d860651d215ede973e6f45445f771.png

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()
../_images/094021e79ea1af0df14130d3f6d4106163ae481d53233b55b5e0e61387a9a9d4.png

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?
../_images/9e354321463a8a8b5dc21c3bb7aa17300a5c22a849525dd1257dfddd50ddc1be.png
# 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()
../_images/290c1f039d2e581d8f12679072379f248387ac45da00a747f554583caabf7ae1.png

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