|
| 1 | +from pathlib import Path |
| 2 | + |
| 3 | + |
1 | 4 | import pandas as pd |
2 | | -from matplotlib import pyplot as plt |
| 5 | +import matplotlib.pyplot as plt |
3 | 6 | import pytest |
4 | 7 | import click |
5 | 8 |
|
6 | 9 |
|
7 | | -def plot_data(data, mean, xlabel, ylabel, file_name): |
8 | | - plt.plot(data, "r-") |
9 | | - plt.xlabel(xlabel) |
10 | | - plt.ylabel(ylabel) |
11 | | - plt.axhline(y=mean, color="b", linestyle="--") |
12 | | - plt.savefig(file_name) |
13 | | - plt.clf() |
| 10 | +def read_data(file_name): |
| 11 | + data = pd.read_csv(file_name) |
| 12 | + |
| 13 | + # combine 'date' and 'time' into a single datetime column |
| 14 | + data["datetime"] = pd.to_datetime(data["date"] + " " + data["time"]) |
| 15 | + |
| 16 | + # set datetime as index for convenience |
| 17 | + data = data.set_index("datetime") |
14 | 18 |
|
| 19 | + return data |
15 | 20 |
|
16 | | -def compute_mean(data): |
17 | | - mean = sum(data) / len(data) |
18 | | - return mean |
19 | 21 |
|
| 22 | +def arithmetic_mean(values): |
| 23 | + mean_value = sum(values) / len(values) |
| 24 | + return mean_value |
20 | 25 |
|
21 | | -def test_compute_mean(): |
22 | | - result = compute_mean([1.0, 2.0, 3.0, 4.0]) |
| 26 | + |
| 27 | +def test_arithmetic_mean(): |
| 28 | + result = arithmetic_mean([1.0, 2.0, 3.0, 4.0]) |
23 | 29 | assert result == pytest.approx(2.5) |
24 | 30 |
|
25 | 31 |
|
26 | | -def read_data(file_name, nrows, column): |
27 | | - data = pd.read_csv(file_name, nrows=nrows) |
28 | | - return data[column] |
| 32 | +def plot(date_range, values, label, location, color, compute_mean, file_name): |
| 33 | + fig, ax = plt.subplots() |
| 34 | + |
| 35 | + # time series |
| 36 | + ax.plot( |
| 37 | + date_range, |
| 38 | + values, |
| 39 | + label=label, |
| 40 | + color=color, |
| 41 | + ) |
| 42 | + |
| 43 | + if compute_mean: |
| 44 | + mean_value = arithmetic_mean(values) |
| 45 | + |
| 46 | + # mean (as horizontal dashed line) |
| 47 | + ax.axhline( |
| 48 | + y=mean_value, |
| 49 | + label=f"mean {label}: {mean_value:.1f}", |
| 50 | + color=color, |
| 51 | + linestyle="--", |
| 52 | + ) |
| 53 | + |
| 54 | + ax.set_title(f"{label} at {location}") |
| 55 | + ax.set_xlabel("date and time") |
| 56 | + ax.set_ylabel(label) |
| 57 | + ax.legend() |
| 58 | + ax.grid(True) |
| 59 | + |
| 60 | + # format x-axis for better date display |
| 61 | + fig.autofmt_xdate() |
| 62 | + |
| 63 | + fig.savefig(file_name) |
29 | 64 |
|
30 | 65 |
|
31 | 66 | @click.command() |
| 67 | +@click.option("--month", required=True, type=str, help="Which month (YYYY-MM)?") |
32 | 68 | @click.option( |
33 | | - "--num-measurements", required=True, type=int, help="Number of measurements." |
| 69 | + "--data-file", |
| 70 | + required=True, |
| 71 | + type=click.Path(exists=True, path_type=Path), |
| 72 | + help="Data is read from this file.", |
34 | 73 | ) |
35 | | -@click.option("--in-file", required=True, help="File name where we read from.") |
36 | | -@click.option("--out-file", required=True, help="File name where we write to.") |
37 | | -def main(num_measurements, in_file, out_file): |
38 | | - |
39 | | - temperatures = read_data( |
40 | | - file_name=in_file, |
41 | | - nrows=num_measurements, |
42 | | - column="Air temperature (degC)", |
43 | | - ) |
| 74 | +@click.option( |
| 75 | + "--output-directory", |
| 76 | + required=True, |
| 77 | + type=click.Path(exists=True, path_type=Path), |
| 78 | + help="Figures are written to this directory.", |
| 79 | +) |
| 80 | +def main( |
| 81 | + month, |
| 82 | + data_file, |
| 83 | + output_directory, |
| 84 | +): |
| 85 | + data = read_data(data_file) |
44 | 86 |
|
45 | | - mean = compute_mean(temperatures) |
| 87 | + data_month = data.loc[month] |
| 88 | + date_range = data_month.index |
46 | 89 |
|
47 | | - plot_data( |
48 | | - data=temperatures, |
49 | | - mean=mean, |
50 | | - xlabel="measurements", |
51 | | - ylabel="air temperature (deg C)", |
52 | | - file_name=out_file, |
| 90 | + plot( |
| 91 | + date_range, |
| 92 | + data_month["air_temperature_celsius"].values, |
| 93 | + "air temperature (C)", |
| 94 | + "Helsinki airport", |
| 95 | + "red", |
| 96 | + compute_mean=True, |
| 97 | + file_name=output_directory / f"{month}-temperature.png", |
| 98 | + ) |
| 99 | + plot( |
| 100 | + date_range, |
| 101 | + data_month["precipitation_mm"].values, |
| 102 | + "precipitation (mm)", |
| 103 | + "Helsinki airport", |
| 104 | + "blue", |
| 105 | + compute_mean=False, |
| 106 | + file_name=output_directory / f"{month}-precipitation.png", |
53 | 107 | ) |
54 | 108 |
|
55 | 109 |
|
|
0 commit comments