|
1 | | -""" pyplots.ai |
| 1 | +"""pyplots.ai |
2 | 2 | band-basic: Basic Band Plot |
3 | | -Library: plotnine 0.15.2 | Python 3.13.11 |
4 | | -Quality: 92/100 | Created: 2025-12-23 |
| 3 | +Library: plotnine 0.15.3 | Python 3.14 |
| 4 | +Quality: /100 | Updated: 2026-02-23 |
5 | 5 | """ |
6 | 6 |
|
7 | 7 | import numpy as np |
|
10 | 10 | aes, |
11 | 11 | element_blank, |
12 | 12 | element_line, |
| 13 | + element_rect, |
13 | 14 | element_text, |
14 | 15 | geom_line, |
15 | 16 | geom_ribbon, |
|
20 | 21 | ) |
21 | 22 |
|
22 | 23 |
|
23 | | -# Data - time series with 95% confidence interval (model predictions) |
| 24 | +# Data - sensor readings with 95% confidence interval |
24 | 25 | np.random.seed(42) |
25 | | -n_points = 50 |
26 | | -x = np.linspace(0, 10, n_points) |
| 26 | +n_points = 60 |
| 27 | +days = np.linspace(0, 30, n_points) |
27 | 28 |
|
28 | | -# Generate central trend with curvature |
29 | | -y_center = 3 * np.sin(0.5 * x) + 0.3 * x + 5 |
30 | | - |
31 | | -# Uncertainty grows with x (heteroscedastic - realistic for forecasts) |
32 | | -uncertainty = 0.5 + 0.15 * x |
| 29 | +# Central trend: temperature rising then stabilizing (realistic sensor pattern) |
| 30 | +temperature = 18 + 4 * (1 - np.exp(-0.15 * days)) + 1.5 * np.sin(0.4 * days) |
33 | 31 | noise = np.random.normal(0, 0.3, n_points) |
34 | | -y_center = y_center + noise |
| 32 | +temperature = temperature + noise |
| 33 | + |
| 34 | +# Uncertainty narrows as model calibrates, then widens for extrapolation |
| 35 | +uncertainty = 1.8 * np.exp(-0.08 * days) + 0.3 + 0.04 * np.maximum(days - 20, 0) |
35 | 36 |
|
36 | | -# Confidence band boundaries (95% CI uses 1.96 standard errors) |
37 | | -y_lower = y_center - 1.96 * uncertainty |
38 | | -y_upper = y_center + 1.96 * uncertainty |
| 37 | +# Confidence band boundaries (95% CI) |
| 38 | +temp_lower = temperature - 1.96 * uncertainty |
| 39 | +temp_upper = temperature + 1.96 * uncertainty |
39 | 40 |
|
40 | | -df = pd.DataFrame({"x": x, "y_center": y_center, "y_lower": y_lower, "y_upper": y_upper}) |
| 41 | +df = pd.DataFrame({"days": days, "temperature": temperature, "temp_lower": temp_lower, "temp_upper": temp_upper}) |
41 | 42 |
|
42 | 43 | # Plot |
43 | 44 | plot = ( |
44 | | - ggplot(df, aes(x="x")) |
45 | | - + geom_ribbon(aes(ymin="y_lower", ymax="y_upper"), fill="#306998", alpha=0.3) |
46 | | - + geom_line(aes(y="y_center"), color="#306998", size=2) |
| 45 | + ggplot(df, aes(x="days")) |
| 46 | + + geom_ribbon(aes(ymin="temp_lower", ymax="temp_upper"), fill="#306998", alpha=0.25) |
| 47 | + + geom_line(aes(y="temperature"), color="#306998", size=2.5) |
47 | 48 | + labs( |
48 | | - x="Time", |
49 | | - y="Predicted Value", |
50 | | - title="Model Forecast with 95% Confidence Interval · band-basic · plotnine · pyplots.ai", |
| 49 | + x="Time (days)", |
| 50 | + y="Temperature (\u00b0C)", |
| 51 | + title="Sensor Calibration Forecast \u00b7 band-basic \u00b7 plotnine \u00b7 pyplots.ai", |
51 | 52 | ) |
52 | 53 | + theme_minimal() |
53 | 54 | + theme( |
|
56 | 57 | axis_title=element_text(size=20), |
57 | 58 | axis_text=element_text(size=16), |
58 | 59 | plot_title=element_text(size=24), |
59 | | - panel_grid_major=element_line(color="#cccccc", size=0.5, alpha=0.3), |
| 60 | + panel_grid_major_y=element_line(color="#cccccc", size=0.5, alpha=0.2), |
| 61 | + panel_grid_major_x=element_blank(), |
60 | 62 | panel_grid_minor=element_blank(), |
| 63 | + panel_border=element_blank(), |
| 64 | + axis_line_x=element_line(color="#333333", size=0.5), |
| 65 | + axis_line_y=element_line(color="#333333", size=0.5), |
| 66 | + plot_background=element_rect(fill="white", color="none"), |
61 | 67 | ) |
62 | 68 | ) |
63 | 69 |
|
|
0 commit comments