helboukkouri's picture
initial commit
09447d8
raw
history blame
5.98 kB
import gradio as gr
import numpy as np
import sympy as sp
import seaborn as sns
from matplotlib import pyplot as plt
sns.set_style(style="darkgrid")
sns.set_context(context="notebook", font_scale=1.2)
MAX_NOISE = 20
DEFAULT_NOISE = 6
SLIDE_NOISE_STEP = 2
MAX_POINTS = 100
DEFAULT_POINTS = 20
SLIDE_POINTS_STEP = 5
def generate_equation(process_params):
process_params = process_params.astype(float).values.tolist()
# Define symbols
x = sp.symbols('x')
coefficients = sp.symbols('a b c d e')
# Create the polynomial expression
polynomial_expression = None
for i, coef in enumerate(reversed(coefficients)):
polynomial_expression = polynomial_expression + coef * x**i if polynomial_expression else coef * x**i
# Parameter mapping
parameters = {coef: value for coef, value in zip(coefficients, process_params[0])}
# Substitute parameter values into the expression
polynomial_with_values = polynomial_expression.subs(parameters)
latex_representation = sp.latex(polynomial_with_values)
return fr"$${latex_representation}$$"
def true_process(x, process_params):
"""The true process we want to model."""
process_params = process_params.astype(float).values.tolist()
return (
process_params[0][0] * (x ** 4)
+ process_params[0][1] * (x ** 3)
+ process_params[0][2] * (x ** 2)
+ process_params[0][3] * x
+ process_params[0][4]
)
def generate_data(num_points, noise_level, process_params):
# x is the list of input values
input_values = np.linspace(-5, 2, num_points)
input_values_dense = np.linspace(-5, 2, MAX_POINTS)
# y = f(x) is the underlying process we want to model
y = [true_process(x, process_params) for x in input_values]
y_dense = [true_process(x, process_params) for x in input_values_dense]
# however, we can only observe a noisy version of f(x)
noise = np.random.normal(0, noise_level, len(input_values))
y_noisy = y + noise
return input_values, input_values_dense, y, y_dense, y_noisy
def make_plot(
num_points, noise_level, process_params,
show_true_process, show_original_points, show_added_noise, show_noisy_points,
):
x, x_dense, y, y_dense, y_noisy = generate_data(num_points, noise_level, process_params)
fig = plt.figure(figsize=(10, 10), dpi=300)
if show_true_process:
plt.plot(
x_dense, y_dense, "-", color="#363A4F",
label="True Process",
)
if show_added_noise:
plt.vlines(
x, y, y_noisy, color="#556D9A",
linestyles="dashed",
alpha=0.75,
lw=1.2,
label="Added Noise",
)
if show_original_points:
plt.plot(
x, y, "-o", color="none",
ms=8,
markerfacecolor="white",
markeredgecolor="#556D9A",
markeredgewidth=1.5,
label="Original Points",
)
if show_noisy_points:
plt.plot(
x, y_noisy, "-o", color="none",
ms=8.5,
markerfacecolor="#556D9A",
markeredgecolor="none",
markeredgewidth=1.5,
alpha=1,
label="Noisy Points",
)
plt.xlabel("\nX")
plt.ylabel("\nY")
plt.legend(fontsize=11)
plt.tight_layout()
plt.show()
return fig
with gr.Blocks() as demo:
with gr.Row():
with gr.Column():
with gr.Row():
process_params = gr.DataFrame(
value=[[0.5, 2, -0.5, -2, 1]],
label="Underlying Process Coefficients",
type="pandas",
column_widths=("2", "1", "1", "1", "1w"),
headers=["x ** 4", "x ** 3", "x ** 2", "x", "1"],
interactive=True
)
equation = gr.Markdown()
with gr.Row():
with gr.Column():
num_points = gr.Slider(
minimum=5,
maximum=MAX_POINTS,
value=DEFAULT_POINTS,
step=SLIDE_POINTS_STEP,
label="Number of Points"
)
with gr.Column():
noise_level = gr.Slider(
minimum=0,
maximum=MAX_NOISE,
value=DEFAULT_NOISE,
step=SLIDE_NOISE_STEP,
label="Noise Level"
)
show_params = []
with gr.Row():
with gr.Column():
show_params.append(gr.Checkbox(label="Show Underlying Process", value=True))
show_params.append(gr.Checkbox(label="Show Original Points", value=True))
with gr.Column():
show_params.append(gr.Checkbox(label="Show Added Noise", value=True))
show_params.append(gr.Checkbox(label="Show Noisy Points", value=True))
scatter_plot = gr.Plot(scale=1)
num_points.change(fn=make_plot, inputs=[num_points, noise_level, process_params, *show_params], outputs=scatter_plot)
noise_level.change(fn=make_plot, inputs=[num_points, noise_level, process_params, *show_params], outputs=scatter_plot)
process_params.change(fn=make_plot, inputs=[num_points, noise_level, process_params, *show_params], outputs=scatter_plot)
process_params.change(fn=generate_equation, inputs=[process_params], outputs=equation)
for component in show_params:
component.change(fn=make_plot, inputs=[num_points, noise_level, process_params, *show_params], outputs=scatter_plot)
demo.load(fn=make_plot, inputs=[num_points, noise_level, process_params, *show_params], outputs=scatter_plot)
demo.load(fn=generate_equation, inputs=[process_params], outputs=equation)
if __name__ == "__main__":
demo.launch()