ifk-smhi, a Python package for interfacing a subset of SMHI APIs, has been released. The docs can be found here.
You can use it to get data from the supported SMHI APIs. Note that, most answers from the API are in Swedish and that the code on this page is using version 0.1.1 of ifk-smhi.
Metobs
For example, we can fetch the historic temperature data for Göteborg as
from smhi.metobs import Parameters, Stations, Periods, Data
parameter = Parameters()
parameter.show
which will output
('1', 'Lufttemperatur', 'momentanvärde, 1 gång/tim')
('2', 'Lufttemperatur', 'medelvärde 1 dygn, 1 gång/dygn, kl 00')
('3', 'Vindriktning', 'medelvärde 10 min, 1 gång/tim')
...
('11', 'Global Irradians (svenska stationer)', 'medelvärde 1 timme, 1 gång/tim')
...
To get all stations for parameter 1
we run
stations = Stations(parameter, 1)
stations.show
which will show a list with 968 entries
(1, 'Akalla')
(2, 'Högdalen')
(3, 'Sigtuna')
(4, 'Jönköping')
(7, 'Gävle')
...
(71420, 'Göteborg A')
...
(72630, 'Göteborg')
...
Next, we want to get all available periods of the "Göteborg A"
station
periods = Periods(stations, station_name="Göteborg A")
periods.show
which lists the available periods
corrected-archive
latest-day
latest-hour
latest-months
Finally, to get the data we can call (which implicitly asks for
the "corrected-archive"
period)
data = Data(periods)
data.data
which outputs a Pandas DataFrame
Lufttemperatur
1961-01-01 06:00:00 0.8
1961-01-01 12:00:00 1.0
1961-01-01 18:00:00 1.4
1961-01-02 06:00:00 1.8
1961-01-02 12:00:00 2.2
... ...
2022-12-01 02:00:00 2.5
2022-12-01 03:00:00 2.4
2022-12-01 04:00:00 2.3
2022-12-01 05:00:00 2.1
2022-12-01 06:00:00 1.9
[303469 rows x 1 columns]
Note that, usually the last three months are missing from the
"corrected-archive"
period. We can plot this data in a scatter plot.
Here, only the daily average is shown to limit the data, see Plot code details.
Plot code
import plotly.graph_objects as go
data_agg_day = data.data.resample("D").mean()
fig = go.Figure()
fig.add_trace(
go.Scattergl(
x=data_agg_day.index,
y=data_agg_day["Lufttemperatur"],
mode="markers",
name="Göteborg A station"
)
)
fig.update_layout(
title="Air temperature in Göteborg A",
xaxis_title="Year",
yaxis_title="Air temperature [°C]",
legend={"orientation": "h"},
margin={"l": 0, "r": 0, "b": 80, "t": 100},
paper_bgcolor="rgba(250, 250, 250, 1)",
)
fig.show()
Strang
What if we wanted to get a sense of the global irradiance over
Sweden's geographic area? We could try fetching the global irradiance
(parameter 11
) from Metobs as
stations = Stations(parameter, 11)
stations.show
which will output
(53445, 'Lund Sol')
(64565, 'Växjö Sol')
(68545, 'Hoburg Sol')
(71415, 'Göteborg Sol')
(77215, 'Ölands norra udde Sol')
(78645, 'Visby Sol')
(81525, 'Nordkoster Sol')
(86655, 'Norrköping Sol')
(93235, 'Karlstad Sol')
(98735, 'Stockholm Sol')
(99275, 'Svenska Högarna Sol')
(105285, 'Borlänge Sol')
(132165, 'Storlien-Visjövalen Sol')
(134615, 'Östersund Sol')
(140615, 'Umeå Sol')
(147655, 'Gunnarn Sol')
(162015, 'Luleå Sol')
(178985, 'Tarfala Sol')
(180025, 'Kiruna Sol')
This only gives us the 19 stations that are measuring global irradiance. To increase the spatial resolution we could instead use the STRÅNG API which is a simulation model of the global irradiance. We can use it as
from smhi.strang import Strang
strang = Strang()
parameters = strang.parameters
which will print out all possible parameters
parameter: 116, info: CIE UV irradiance [mW/m²]
parameter: 117, info: Global irradiance [W/m²]
parameter: 118, info: Direct normal irradiance [W/m²]
parameter: 120, info: PAR [W/m²]
parameter: 121, info: Direct horizontal irradiance [W/m²]
parameter: 122, info: Diffuse irradiance [W/m²]
We are interested in parameter 117 here. First, let's find out how far back in time we can get the data from
strang.available_parameters[117].time_from
which tells us
datetime.datetime(1999, 1, 1, 0, 0, tzinfo=tzutc())
Now, we can get a multi-point response from the API for that
day aggregated daily
data = strang.get_multipoint(117, "1999-01-01", "daily")
data
which gives us a Pandas DataFrame
lat lon Global irradiance [W/m²] 1999-01-01T00:00:00+00:00 daily
0 74.945244 1.212198 0.0
1 74.910484 1.942287 0.0
2 74.873570 2.669121 0.0
3 74.834520 3.392533 0.0
4 74.793340 4.112356 0.0
... ... ... ...
11827 46.503345 23.264704 1561.9
11828 46.408020 23.516861 1655.8
11829 46.312065 23.768070 1717.9
11830 46.215477 24.018330 1701.7
11831 46.118263 24.267643 1673.6
[11832 rows x 3 columns]
We can again visualise this data in a scatter plot.
Scatter plot code
import plotly.graph_objects as go
fig = go.Figure()
fig.add_trace(
go.Scattergl(
x=data["lon"],
y=data["lat"],
mode="markers",
name="Global irradiance 1999-01-01 daily",
marker={
"color": data["Global irradiance [W/m²] 1999-01-01T00:00:00+00:00 daily"],
"colorbar": {"title": "[W/m²]"},
},
)
)
fig.update_layout(
title="Global irradiance 1999-01-01 daily",
xaxis_title="Longitude",
yaxis_title="Latitude",
legend={"orientation": "h"},
margin={"l": 0, "r": 0, "b": 80, "t": 100},
paper_bgcolor="rgba(250, 250, 250, 1)",
)
fig.update_yaxes(
scaleanchor="x",
scaleratio=1,
)
fig.show()