Created
August 9, 2023 08:18
-
-
Save TomMarius/8b198069ebe492951a29f3d5ba76f60d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| package main | |
| import ( | |
| "log" | |
| "net/http" | |
| "sort" | |
| "strconv" | |
| "github.com/360EntSecGroup-Skylar/excelize/v2" | |
| "gonum.org/v1/plot" | |
| "gonum.org/v1/plot/plotter" | |
| "gonum.org/v1/plot/plotutil" | |
| "gonum.org/v1/plot/vg" | |
| ) | |
| func main() { | |
| // Step 1: Download the Excel file. | |
| resp, err := http.Get("http://portal.chmi.cz/files/portal/docs/meteo/ok/files/PKLM_pro_portal.xlsx") | |
| if err != nil { | |
| log.Fatal(err) | |
| } | |
| defer resp.Body.Close() | |
| // Step 2: Read the Excel file. | |
| f, err := excelize.OpenReader(resp.Body) | |
| if err != nil { | |
| log.Fatal(err) | |
| } | |
| // Assuming data starts from 3rd row, and columns are 'A' for year and 'B' for TMI. | |
| rows, err := f.GetRows("Sheet1") | |
| if err != nil { | |
| log.Fatal(err) | |
| } | |
| yearlyData := make(map[int]float64) | |
| var total float64 | |
| count := 0 | |
| for _, row := range rows[2:] { | |
| year, err := strconv.Atoi(row[0]) | |
| if err != nil { | |
| continue | |
| } | |
| if year < 1889 { | |
| continue | |
| } | |
| tmi, err := strconv.ParseFloat(row[1], 64) | |
| if err != nil { | |
| continue | |
| } | |
| yearlyData[year] = tmi | |
| total += tmi | |
| count++ | |
| } | |
| avg := total / float64(count) | |
| rollingAvgData := rollingAverage(yearlyData, 10) | |
| ptsRolling := make(plotter.XYs, len(rollingAvgData)) | |
| i = 0 | |
| for year, tmi := range rollingAvgData { | |
| ptsRolling[i].X = float64(year) | |
| ptsRolling[i].Y = tmi - avg | |
| i++ | |
| } | |
| err = plotutil.AddLinePoints(p, "Rolling Change", ptsRolling) | |
| if err != nil { | |
| log.Fatal(err) | |
| } | |
| // Plotting. | |
| p, err := plot.New() | |
| if err != nil { | |
| log.Fatal(err) | |
| } | |
| p.Title.Text = "Change in daily temperatures in Prague, Czechia since 1900" | |
| p.X.Label.Text = "Year" | |
| p.Y.Label.Text = "Change in temperature [°C]" | |
| pts := make(plotter.XYs, count) | |
| i := 0 | |
| for year, tmi := range yearlyData { | |
| pts[i].X = float64(year) | |
| pts[i].Y = tmi - avg | |
| i++ | |
| } | |
| err = plotutil.AddLinePoints(p, "Change", pts) | |
| if err != nil { | |
| log.Fatal(err) | |
| } | |
| if err := p.Save(12*vg.Inch, 8*vg.Inch, "output.png"); err != nil { | |
| log.Fatal(err) | |
| } | |
| } | |
| func rollingAverage(data map[int]float64, window int) map[int]float64 { | |
| sortedYears := make([]int, 0, len(data)) | |
| for year := range data { | |
| sortedYears = append(sortedYears, year) | |
| } | |
| sort.Ints(sortedYears) | |
| result := make(map[int]float64) | |
| halfWindow := window / 2 | |
| for i, year := range sortedYears { | |
| start := i - halfWindow | |
| if start < 0 { | |
| start = 0 | |
| } | |
| end := i + halfWindow | |
| if end >= len(sortedYears) { | |
| end = len(sortedYears) - 1 | |
| } | |
| sum := 0.0 | |
| count := 0 | |
| for j := start; j <= end; j++ { | |
| sum += data[sortedYears[j]] | |
| count++ | |
| } | |
| result[year] = sum / float64(count) | |
| } | |
| return result | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment