Skip to content

Commit fc49770

Browse files
committed
9.3 zadani
1 parent 6c71eb4 commit fc49770

3 files changed

Lines changed: 207 additions & 191 deletions

File tree

vizualizace-xarray/analyza.py

Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
import numpy as np
2+
import matplotlib.pyplot as plt
3+
from scipy.stats import binned_statistic_2d, ttest_ind
4+
from scipy.interpolate import griddata
5+
import pywt
6+
import warnings
7+
warnings.filterwarnings('ignore')
8+
9+
def create_binned_grid(x, y, values, num_bins=20):
10+
bins = (num_bins, num_bins)
11+
binned = binned_statistic_2d(x, y, values, statistic='mean', bins=bins)
12+
return binned.statistic, binned.x_edge, binned.y_edge
13+
14+
def bin_single_field(X_coords, data_var, num_bins=20):
15+
x = X_coords.sel(i_dim="x").values
16+
y = X_coords.sel(i_dim="y").values
17+
grid, x_edges, y_edges = create_binned_grid(x, y, data_var.values, num_bins)
18+
return grid, x_edges, y_edges
19+
20+
def bin_all_samples(X_coords, data_var, num_bins=20):
21+
x = X_coords.sel(i_dim="x").values
22+
y = X_coords.sel(i_dim="y").values
23+
n_samples = data_var.shape[1]
24+
25+
grid_3d = np.zeros((num_bins, num_bins, n_samples))
26+
for i in range(n_samples):
27+
grid_3d[:, :, i], x_edges, y_edges = create_binned_grid(x, y, data_var.values[:, i], num_bins)
28+
29+
return grid_3d, x_edges, y_edges
30+
31+
def plot_means_two_columns(x_edges, y_edges, grid_mean_A, grid_mean_B):
32+
fig, axes = plt.subplots(1, 2, figsize=(12, 5))
33+
34+
im1 = axes[0].pcolormesh(x_edges, y_edges, grid_mean_A.T, cmap='viridis', shading='flat')
35+
axes[0].set_title("Průměr pole A")
36+
plt.colorbar(im1, ax=axes[0])
37+
38+
im2 = axes[1].pcolormesh(x_edges, y_edges, grid_mean_B.T, cmap='viridis', shading='flat')
39+
axes[1].set_title("Průměr pole B")
40+
plt.colorbar(im2, ax=axes[1])
41+
42+
plt.tight_layout()
43+
return fig
44+
45+
def perform_ttest(grid_A, grid_B):
46+
t_stat, p_value = ttest_ind(grid_A, grid_B, axis=-1, equal_var=False, alternative='two-sided')
47+
return t_stat, p_value
48+
49+
def plot_ttest_results(x_edges, y_edges, t_stat, p_value):
50+
fig, axes = plt.subplots(1, 2, figsize=(12, 5))
51+
52+
im1 = axes[0].pcolormesh(x_edges, y_edges, t_stat.T, cmap='coolwarm', shading='flat')
53+
axes[0].set_title("T-statistika")
54+
plt.colorbar(im1, ax=axes[0])
55+
56+
im2 = axes[1].pcolormesh(x_edges, y_edges, p_value.T, cmap='RdYlGn', shading='flat', vmin=0, vmax=0.1)
57+
axes[1].set_title("p-hodnota")
58+
plt.colorbar(im2, ax=axes[1])
59+
60+
plt.tight_layout()
61+
return fig
62+
63+
def multiscale_analysis(x, y, q_a_vals, q_b_vals):
64+
grid_sizes = [2, 4, 8]
65+
p_values_all = {'arith': [], 'geom': [], 'harm': []}
66+
67+
fig1, axes1 = plt.subplots(len(grid_sizes), 3, figsize=(15, 5 * len(grid_sizes)))
68+
69+
for idx, gs in enumerate(grid_sizes):
70+
dx = 1.0 / gs
71+
dy = 1.0 / gs
72+
73+
p_map_arith = np.full((gs, gs), np.nan)
74+
p_map_geom = np.full((gs, gs), np.nan)
75+
p_map_harm = np.full((gs, gs), np.nan)
76+
77+
for i in range(gs):
78+
for j in range(gs):
79+
mask = (x >= i*dx) & (x < (i+1)*dx) & (y >= j*dy) & (y < (j+1)*dy)
80+
81+
if np.sum(mask) > 0:
82+
qa_w = q_a_vals[mask, :]
83+
qb_w = q_b_vals[mask, :]
84+
85+
qa_arith = np.mean(qa_w, axis=0)
86+
qb_arith = np.mean(qb_w, axis=0)
87+
88+
qa_w_safe = np.clip(qa_w, 1e-10, None)
89+
qb_w_safe = np.clip(qb_w, 1e-10, None)
90+
91+
qa_geom = np.exp(np.mean(np.log(qa_w_safe), axis=0))
92+
qb_geom = np.exp(np.mean(np.log(qb_w_safe), axis=0))
93+
94+
qa_harm = 1.0 / np.mean(1.0 / qa_w_safe, axis=0)
95+
qb_harm = 1.0 / np.mean(1.0 / qb_w_safe, axis=0)
96+
97+
_, p_a = ttest_ind(qa_arith, qb_arith, equal_var=False)
98+
_, p_g = ttest_ind(qa_geom, qb_geom, equal_var=False)
99+
_, p_h = ttest_ind(qa_harm, qb_harm, equal_var=False)
100+
101+
p_map_arith[j, i] = p_a
102+
p_map_geom[j, i] = p_g
103+
p_map_harm[j, i] = p_h
104+
105+
p_values_all['arith'].append(np.nanmean(p_map_arith))
106+
p_values_all['geom'].append(np.nanmean(p_map_geom))
107+
p_values_all['harm'].append(np.nanmean(p_map_harm))
108+
109+
im_a = axes1[idx, 0].imshow(p_map_arith, origin='lower', extent=[0, 1, 0, 1], cmap='RdYlGn', vmin=0, vmax=1)
110+
axes1[idx, 0].set_ylabel(f"Mřížka {gs}x{gs}")
111+
if idx == 0: axes1[idx, 0].set_title("Aritmetický")
112+
plt.colorbar(im_a, ax=axes1[idx, 0])
113+
114+
im_g = axes1[idx, 1].imshow(p_map_geom, origin='lower', extent=[0, 1, 0, 1], cmap='RdYlGn', vmin=0, vmax=1)
115+
if idx == 0: axes1[idx, 1].set_title("Geometrický")
116+
plt.colorbar(im_g, ax=axes1[idx, 1])
117+
118+
im_h = axes1[idx, 2].imshow(p_map_harm, origin='lower', extent=[0, 1, 0, 1], cmap='RdYlGn', vmin=0, vmax=1)
119+
if idx == 0: axes1[idx, 2].set_title("Harmonický")
120+
plt.colorbar(im_h, ax=axes1[idx, 2])
121+
122+
plt.tight_layout()
123+
124+
fig2, ax2 = plt.subplots(figsize=(8, 5))
125+
ax2.plot(grid_sizes, p_values_all['arith'], marker='o', label='Aritmetický')
126+
ax2.plot(grid_sizes, p_values_all['geom'], marker='s', label='Geometrický')
127+
ax2.plot(grid_sizes, p_values_all['harm'], marker='^', label='Harmonický')
128+
ax2.set_xticks(grid_sizes)
129+
ax2.set_xlabel("Velikost okna (počet dělení)")
130+
ax2.set_ylabel("Průměrná p-hodnota")
131+
ax2.set_title("Závislost p-hodnoty na velikosti okna")
132+
plt.legend()
133+
134+
return fig1, fig2
135+

vizualizace-xarray/generovani.py

Lines changed: 72 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
@app.cell(hide_code=True)
88
def _():
99
import marimo as mo
10+
1011
return (mo,)
1112

1213

@@ -21,11 +22,6 @@ def _(mo):
2122
- `i_point`: Index konkrétního bodu v nepravidelné síti.
2223
- `i_sample`: Index vzorku (realizace) náhodného pole.
2324
- `i_dim`: Označení prostorové osy (např. 'x', 'y').
24-
25-
**Datové proměnné (data_vars):**
26-
- `X`: Matice prostorových souřadnic bodů. Má tvar `[i_dim, i_point]`.
27-
- `QA`: První vygenerované náhodné pole. Má tvar `[i_point, i_sample]`.
28-
- `QB`: Druhé vygenerované náhodné pole. Má tvar `[i_point, i_sample]`.
2925
""")
3026
return
3127

@@ -34,132 +30,93 @@ def _(mo):
3430
def _():
3531
import xarray as xr
3632
import numpy as np
37-
import matplotlib.pyplot as plt
38-
from scipy.stats import binned_statistic_2d
33+
import analyza
3934

4035
n_points = 1000
41-
n_samples = 100
36+
n_samples_A = 10
37+
n_samples_B = 20
4238
n_dim = 2
4339

4440
X_data = np.random.rand(n_dim, n_points)
45-
QA_data = np.random.uniform(0.01, 1.0, size=(n_points, n_samples))
46-
QB_data = np.random.normal(loc=0.5, scale=0.15, size=(n_points, n_samples))
47-
QB_data = np.clip(QB_data, 0.01, None)
41+
42+
# Testovací pole = 10**( np.random.normal(N, loc = -10, scale=3))
43+
QA_data = 10**(np.random.normal(loc=-10, scale=3, size=(n_points, n_samples_A)))
44+
45+
# případně zvětšit scale pro větší rozdíl průměrů polí
46+
QB_data = 10**(np.random.normal(loc=-10, scale=5, size=(n_points, n_samples_B)))
4847

4948
ds = xr.Dataset(
5049
data_vars={
5150
"X": (("i_dim", "i_point"), X_data),
52-
"QA": (("i_point", "i_sample"), QA_data),
53-
"QB": (("i_point", "i_sample"), QB_data),
51+
"QA": (("i_point", "i_sample_A"), QA_data),
52+
"QB": (("i_point", "i_sample_B"), QB_data),
5453
},
5554
coords={
5655
"i_point": np.arange(n_points),
57-
"i_sample": np.arange(n_samples),
56+
"i_sample_A": np.arange(n_samples_A),
57+
"i_sample_B": np.arange(n_samples_B),
5858
"i_dim": ["x", "y"]
5959
}
6060
)
61+
return analyza, ds
62+
63+
64+
@app.cell(hide_code=True)
65+
def _(ds):
66+
# Průměry pro každé ze dvou polí. Průměry do samostatné buňky.
67+
mean_QA = ds["QA"].mean(dim="i_sample_A")
68+
mean_QB = ds["QB"].mean(dim="i_sample_B")
69+
return mean_QA, mean_QB
70+
71+
72+
@app.cell(hide_code=True)
73+
def _(analyza, ds, mean_QA, mean_QB):
74+
grid_mean_A, x_edges, y_edges = analyza.bin_single_field(ds["X"], mean_QA)
75+
grid_mean_B, _, _ = analyza.bin_single_field(ds["X"], mean_QB)
76+
77+
fig_means = analyza.plot_means_two_columns(x_edges, y_edges, grid_mean_A, grid_mean_B)
78+
fig_means
79+
return x_edges, y_edges
80+
81+
82+
@app.cell(hide_code=True)
83+
def _(analyza, ds):
84+
grid_A, _, _ = analyza.bin_all_samples(ds["X"], ds["QA"])
85+
grid_B, _, _ = analyza.bin_all_samples(ds["X"], ds["QB"])
86+
87+
t_stat, p_value = analyza.perform_ttest(grid_A, grid_B)
88+
return p_value, t_stat
6189

62-
ds["QA"].attrs["long_name"] = "Porovnávaná veličina A"
63-
ds["QA"].attrs["units"] = "-"
64-
ds["QB"].attrs["long_name"] = "Porovnávaná veličina B"
65-
ds["QB"].attrs["units"] = "-"
66-
67-
stats = xr.Dataset({
68-
"mean_QA": ds["QA"].mean(dim="i_sample"),
69-
"var_QA": ds["QA"].var(dim="i_sample"),
70-
"mean_QB": ds["QB"].mean(dim="i_sample"),
71-
"var_QB": ds["QB"].var(dim="i_sample")
72-
})
73-
74-
x = ds["X"].sel(i_dim="x").values
75-
y = ds["X"].sel(i_dim="y").values
76-
77-
# Pro grafy průměru a rozptylu použít imgshow nebo podobnou funkci
78-
num_bins = 20
79-
bins = (num_bins, num_bins)
80-
81-
binned_mean_QA = binned_statistic_2d(x, y, stats["mean_QA"].values, statistic='mean', bins=bins)
82-
binned_var_QA = binned_statistic_2d(x, y, stats["var_QA"].values, statistic='mean', bins=bins)
83-
binned_mean_QB = binned_statistic_2d(x, y, stats["mean_QB"].values, statistic='mean', bins=bins)
84-
binned_var_QB = binned_statistic_2d(x, y, stats["var_QB"].values, statistic='mean', bins=bins)
85-
86-
x_edges = binned_mean_QA.x_edge
87-
y_edges = binned_mean_QA.y_edge
88-
89-
fig, axes = plt.subplots(2, 3, figsize=(15, 10))
90-
91-
im1 = axes[0, 0].pcolormesh(x_edges, y_edges, binned_mean_QA.statistic.T, cmap='viridis', shading='flat')
92-
axes[0, 0].set_title("QA: Mapa průměru")
93-
axes[0, 0].set_aspect('equal')
94-
plt.colorbar(im1, ax=axes[0, 0])
95-
96-
im2 = axes[0, 1].pcolormesh(x_edges, y_edges, binned_var_QA.statistic.T, cmap='magma', shading='flat')
97-
axes[0, 1].set_title("QA: Mapa rozptylu")
98-
axes[0, 1].set_aspect('equal')
99-
plt.colorbar(im2, ax=axes[0, 1])
100-
101-
axes[0, 2].hist(ds["QA"].values.flatten(), bins=30, color='skyblue', edgecolor='black')
102-
axes[0, 2].set_title("QA: Histogram")
103-
104-
im3 = axes[1, 0].pcolormesh(x_edges, y_edges, binned_mean_QB.statistic.T, cmap='viridis', shading='flat')
105-
axes[1, 0].set_title("QB: Mapa průměru")
106-
axes[1, 0].set_aspect('equal')
107-
plt.colorbar(im3, ax=axes[1, 0])
108-
109-
im4 = axes[1, 1].pcolormesh(x_edges, y_edges, binned_var_QB.statistic.T, cmap='magma', shading='flat')
110-
axes[1, 1].set_title("QB: Mapa rozptylu")
111-
axes[1, 1].set_aspect('equal')
112-
plt.colorbar(im4, ax=axes[1, 1])
113-
114-
axes[1, 2].hist(ds["QB"].values.flatten(), bins=30, color='salmon', edgecolor='black')
115-
axes[1, 2].set_title("QB: Histogram")
116-
117-
plt.tight_layout()
118-
plt.show()
119-
120-
# Vypočtěte různé druhy průměrů (aritmetický, geometrický, harmonický) na podčtvercích (multi-scale) pro různé velikosti oken. Zatím pro jednu velikost okna.
121-
q_values = stats["mean_QA"].values
122-
grid_size = 10
123-
A_arith = np.zeros((grid_size, grid_size))
124-
A_geom = np.zeros((grid_size, grid_size))
125-
A_harm = np.zeros((grid_size, grid_size))
126-
127-
dx = 1.0 / grid_size
128-
dy = 1.0 / grid_size
129-
130-
for i in range(grid_size):
131-
for j in range(grid_size):
132-
mask = (x >= i*dx) & (x < (i+1)*dx) & (y >= j*dy) & (y < (j+1)*dy)
133-
q_in_window = q_values[mask]
134-
135-
if len(q_in_window) > 0:
136-
A_arith[j, i] = np.mean(q_in_window)
137-
A_geom[j, i] = np.exp(np.mean(np.log(q_in_window)))
138-
A_harm[j, i] = 1.0 / np.mean(1.0 / q_in_window)
139-
else:
140-
A_arith[j, i] = np.nan
141-
A_geom[j, i] = np.nan
142-
A_harm[j, i] = np.nan
143-
144-
fig2, axes2 = plt.subplots(1, 3, figsize=(15, 5))
145-
146-
im5 = axes2[0].imshow(A_arith, origin='lower', extent=[0, 1, 0, 1], cmap='viridis')
147-
axes2[0].set_title("Aritmetický průměr")
148-
plt.colorbar(im5, ax=axes2[0])
149-
150-
im6 = axes2[1].imshow(A_geom, origin='lower', extent=[0, 1, 0, 1], cmap='viridis')
151-
axes2[1].set_title("Geometrický průměr")
152-
plt.colorbar(im6, ax=axes2[1])
153-
154-
im7 = axes2[2].imshow(A_harm, origin='lower', extent=[0, 1, 0, 1], cmap='viridis')
155-
axes2[2].set_title("Harmonický průměr")
156-
plt.colorbar(im7, ax=axes2[2])
157-
158-
plt.tight_layout()
159-
plt.show()
160-
161-
return ds, fig, fig2
90+
91+
@app.cell(hide_code=True)
92+
def _(analyza, p_value, t_stat, x_edges, y_edges):
93+
fig_test = analyza.plot_ttest_results(x_edges, y_edges, t_stat, p_value)
94+
fig_test
95+
return
96+
97+
98+
@app.cell(hide_code=True)
99+
def _(analyza, ds):
100+
x_vals = ds["X"].sel(i_dim="x").values
101+
y_vals = ds["X"].sel(i_dim="y").values
102+
q_a_vals = ds["QA"].values
103+
q_b_vals = ds["QB"].values
104+
105+
fig_multiscale_maps, fig_multiscale_line = analyza.multiscale_analysis(x_vals, y_vals, q_a_vals, q_b_vals)
106+
return fig_multiscale_line, fig_multiscale_maps
107+
108+
109+
@app.cell(hide_code=True)
110+
def _(fig_multiscale_maps):
111+
fig_multiscale_maps
112+
return
113+
114+
115+
@app.cell(hide_code=True)
116+
def _(fig_multiscale_line):
117+
fig_multiscale_line
118+
return
162119

163120

164121
if __name__ == "__main__":
165-
app.run()
122+
app.run()

0 commit comments

Comments
 (0)