import altair as alt
import numpy as np
import pandas as pd
In [1]:
Parameters:
In [2]:
= 4, 4
x_mean, y_mean = 3, 3
sigma_X, sigma_Y = 0.5
sigma_D = np.sqrt(x_mean**2 + y_mean**2) dAverage
2D Gaussian function f(x, y):
In [3]:
def f_xy(x, y):
return (
1
/ (2 * np.pi * sigma_X * sigma_Y)
* np.exp(
-(
- x_mean) ** 2) / (2 * sigma_X**2)
((x + ((y - y_mean) ** 2) / (2 * sigma_Y**2)
)
) )
Distance Gaussian f_D(d, x, y):
In [4]:
def fD(d, x, y):
return (
1
/ (np.sqrt(2 * np.pi) * sigma_D)
* np.exp(-((d - np.sqrt(x**2 + y**2)) ** 2) / (2 * sigma_D**2))
)
Combined function f(x, y, d):
In [5]:
def f_xy_d(x, y, d):
return fD(d, x, y) * f_xy(x, y)
Interactive plotting function: one panel for f(x, y), the other for f(x, y, d) with a circle of radius d.
In [6]:
def generate_common_components(font_size=12, domain=[-10, 10]):
= alt.Axis(
axis_cfg =False,
grid="Times",
labelFont=font_size,
labelFontSize="normal",
labelFontStyle="Times",
titleFont=font_size,
titleFontSize="italic",
titleFontStyle
)
= np.linspace(domain[0], domain[1], 70)
xs = np.meshgrid(xs, xs)
X, Y = xs[1] - xs[0]
step
= pd.DataFrame(
df_grid
{"x": X.ravel(),
"y": Y.ravel(),
"x2": (X + step).ravel(),
"y2": (Y + step).ravel(),
"center_x": (X + step / 2).ravel(),
"center_y": (Y + step / 2).ravel(),
"value_uncond": f_xy(X, Y).ravel(),
}
)
= alt.param(
d_slider "d",
=alt.binding_range(
bindmin=float(dAverage - 2), max=float(dAverage + 2), step=0.1, name="𝑑"
),=float(dAverage),
value
)
= alt.X("x:Q", title="x", scale=alt.Scale(domain=domain), axis=axis_cfg)
encode_x = alt.Y("y:Q", title="y", scale=alt.Scale(domain=domain), axis=axis_cfg)
encode_y
return {
"axis_cfg": axis_cfg,
"df_grid": df_grid,
"d_slider": d_slider,
"encode_x": encode_x,
"encode_y": encode_y,
}
def plot_unconditional(components):
= (
chart "df_grid"])
alt.Chart(components[
.mark_rect()
.encode(=components["encode_x"],
x="x2:Q",
x2=components["encode_y"],
y="y2:Q",
y2=alt.Color("value_uncond:Q", legend=None),
color
)=300, height=300)
.properties(width
)return chart
def plot_conditional(components):
= (
expr "datum.value_uncond / (sqrt(2 * PI) * {sd}) * "
"exp(- (pow(d - sqrt(pow(datum.center_x, 2) + pow(datum.center_y, 2)), 2)) / (2 * {sd} * {sd}))"
format(sd=sigma_D)
).
= (
density_chart "df_grid"])
alt.Chart(components[=expr)
.transform_calculate(value_cond
.mark_rect()
.encode(=components["encode_x"],
x="x2:Q",
x2=components["encode_y"],
y="y2:Q",
y2=alt.Color("value_cond:Q", legend=None),
color
)=300, height=300)
.properties(width"d_slider"])
.add_params(components[
)
= np.linspace(0, 2 * np.pi, 100)
theta = pd.DataFrame({"theta": theta, "x": np.cos(theta), "y": np.sin(theta)})
circle_df
= (
circle
alt.Chart(circle_df)
.transform_calculate(="datum.x * d",
x_scaled="datum.y * d",
y_scaled
)="gray", strokeWidth=1)
.mark_line(color
.encode(=alt.X(
x"x_scaled:Q",
=alt.Scale(domain=[-10, 10]),
scale=components["axis_cfg"],
axis
),=alt.Y(
y"y_scaled:Q",
=alt.Scale(domain=[-10, 10]),
scale=components["axis_cfg"],
axis
),=alt.Order("theta:Q"),
order
)"d_slider"])
.add_params(components[
)
return density_chart + circle
Create the interactive slider for d
In [7]:
= generate_common_components(font_size=12) components
In [11]:
plot_unconditional(components)
In [12]:
plot_conditional(components)