The function plots a 2D transformation:
$$ (x, y) \to (x', y') \text{ where } (x', y') = transform\_func(x, y)$$
The x and y grid values are defined over $$[x_{\text{min}}, x_{\text{max}}] $$
and $$ [y_{\text{min}}, y_{\text{max}}], \text{ respectively.} $$
For each grid point (x, y), the transformation is applied, and the transformed coordinates (x', y') are plotted.
The color is determined by a default function or a user-defined function, such as: hsv_to_rgb(theta, 0.8, 0.9)
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import hsv_to_rgb
import random
def transform_2d_plot(transform_func, x_range, y_range,
color_function=None, plot_points=50,
axes=True, background_color='white',
figsize=(10, 10), line_width=1):
"""
A generic function to plot 2D coordinate transformations.
Parameters:
-----------
transform_func : callable
Function that takes (x, y) and returns transformed (x', y')
x_range : tuple
(x_min, x_max) range for x coordinates
y_range : tuple
(y_min, y_max) range for y coordinates
color_function : callable, optional
Function that takes (x, y) and returns RGB color tuple
plot_points : int or tuple, optional
Number of grid lines in each dimension
axes : bool, optional
Whether to show the axes
background_color : str or tuple, optional
Color for the plot background
figsize : tuple, optional
Figure size in inches
line_width : float, optional
Width of the grid lines
Returns:
--------
fig, ax : matplotlib figure and axis
"""
x_min, x_max = x_range
y_min, y_max = y_range
if isinstance(plot_points, int):
x_points = y_points = plot_points
else:
x_points, y_points = plot_points
if color_function is None:
def default_color(x, y):
nx = (x - x_min) / (x_max - x_min)
ny = (y - y_min) / (y_max - y_min)
angle = np.arctan2(ny - 0.5, nx - 0.5) / (2 * np.pi) % 1
return hsv_to_rgb(np.array([angle, 0.8, 0.9]))
color_function = default_color
if color_function == "random":
def random_color_function(x, y):
random.seed(int((x + y) * 1000))
return (random.random(), random.random(), random.random())
color_function = random_color_function
fig, ax = plt.subplots(figsize=figsize)
fig.patch.set_facecolor(background_color)
ax.set_facecolor(background_color)
x_grid = np.linspace(x_min, x_max, x_points)
y_grid = np.linspace(y_min, y_max, y_points)
interp_factor = 10
for y_val in y_grid:
x_vals = np.linspace(x_min, x_max, x_points * interp_factor)
points = [(x, y_val) for x in x_vals]
transformed = [transform_func(p[0], p[1]) for p in points]
x_trans, y_trans = zip(*transformed)
mid_x = (x_min + x_max) / 2
color = color_function(mid_x, y_val)
ax.plot(x_trans, y_trans, color=color, linewidth=line_width)
for x_val in x_grid:
y_vals = np.linspace(y_min, y_max, y_points * interp_factor)
points = [(x_val, y) for y in y_vals]
transformed = [transform_func(p[0], p[1]) for p in points]
x_trans, y_trans = zip(*transformed)
mid_y = (y_min + y_max) / 2
color = color_function(x_val, mid_y)
ax.plot(x_trans, y_trans, color=color, linewidth=line_width)
if not axes:
ax.axis('off')
else:
ax.set_aspect('equal')
plt.tight_layout()
return fig, ax
# This was also generated by claude
def random_rgb_color_function_generator(seed=None):
"""
Generate a random RGB color function similar to Mathematica's
RandomRGBColorFunctionGenerator
Parameters:
-----------
seed : int, optional
Random seed for reproducibility
Returns:
--------
color_function : callable
Function that takes (x, y) and returns RGB color tuple
"""
if seed is not None:
random.seed(seed)
np.random.seed(seed)
num_terms = random.randint(2, 5)
r_coeffs = [(random.uniform(-5, 5), random.uniform(-5, 5),
random.uniform(0, 2*np.pi)) for _ in range(num_terms)]
g_coeffs = [(random.uniform(-5, 5), random.uniform(-5, 5),
random.uniform(0, 2*np.pi)) for _ in range(num_terms)]
b_coeffs = [(random.uniform(-5, 5), random.uniform(-5, 5),
random.uniform(0, 2*np.pi)) for _ in range(num_terms)]
def color_func(x, y):
r = sum(0.5 * (np.sin(ax*x + ay*y + phase) + 1) / num_terms
for ax, ay, phase in r_coeffs)
g = sum(0.5 * (np.sin(ax*x + ay*y + phase) + 1) / num_terms
for ax, ay, phase in g_coeffs)
b = sum(0.5 * (np.sin(ax*x + ay*y + phase) + 1) / num_terms
for ax, ay, phase in b_coeffs)
r = max(0, min(1, r))
g = max(0, min(1, g))
b = max(0, min(1, b))
return (r, g, b)
return color_func
$$ \text{Rotation Transform: Applies a rotation matrix to } (x, y) \text{ based on distance from origin.} $$ $$ \text{If } r < 1, \text{ rotates by } \theta = (1 - r^2) \cdot n \text{ and scales by } r^2. $$
This transform rotates points around the origin, with the rotation angle depending on the radial distance $r$. For points closer to the origin $(r < 1)$, the rotation is stronger, and the points are also scaled by $r^2$. This creates a swirling effect that intensifies near the center.
# This is the implementation for
# n = N[2];
# f[x_, y_] := If[N[Sqrt[x^2 + y^2]] < 1,
# ({{Cos[(1 - #1)*n], -Sin[(1 - #1)*n]}, {Sin[(1 - #1)*n],
# Cos[(1 - #1)*n]}} & )[x^2 + y^2] . {x, y}*(x^2 +
# y^2), {x, y}]
def example_rotation_transform():
def rotation_transform(x, y, n=2.0):
r_squared = x**2 + y**2
r = np.sqrt(r_squared)
if r < 1:
theta = (1 - r_squared) * n
cos_theta = np.cos(theta)
sin_theta = np.sin(theta)
rotation_matrix = np.array([
[cos_theta, -sin_theta],
[sin_theta, cos_theta]
])
result = np.dot(rotation_matrix, np.array([x, y])) * r_squared
return result[0], result[1]
else:
return x, y
color_func = random_rgb_color_function_generator(seed=42)
fig, ax = transform_2d_plot(
rotation_transform,
x_range=(-1.2, 1.2),
y_range=(-1.2, 1.2),
color_function=color_func,
plot_points=24,
figsize=(3,3),
axes=False,
background_color='black'
)
return fig, ax
fig2, ax2 = example_rotation_transform()
plt.figure(2)
plt.show()
<Figure size 640x480 with 0 Axes>
$$ \text{Sine Ripple Transform: Adds a sinusoidal ripple effect to } (x, y) \text{ based on radial distance.} $$ $$ \text{Transforms } (x, y) \text{ as } (x + \sin(r) \cdot \frac{x}{r}, y + \sin(r) \cdot \frac{y}{r}). $$
This transform adds a sinusoidal ripple effect to the coordinates, where the amplitude of the ripple depends on the radial distance $r$. The effect is stronger for larger $r$, creating wave-like distortions that radiate outward from the origin.
# This is the implementation for
# Sin[Sqrt[x^2 + y^2]]*Normalize[{x, y}] + {x, y}
def sine_ripple_transform(x, y):
r = np.sqrt(x**2 + y**2)
if r < 1e-10:
return x, y
nx, ny = x/r, y/r
sine_factor = np.sin(r)
x_transformed = sine_factor * nx + x
y_transformed = sine_factor * ny + y
return x_transformed, y_transformed
def purple_gradient_color(x, y):
x_range = (-3*np.pi, 3*np.pi)
y_range = (-3*np.pi, 3*np.pi)
norm_x = (x - x_range[0]) / (x_range[1] - x_range[0])
return (0.4, norm_x, 0.8)
fig, ax = transform_2d_plot(
transform_func=sine_ripple_transform,
x_range=(-3*np.pi, 3*np.pi),
y_range=(-3*np.pi, 3*np.pi),
color_function=purple_gradient_color,
plot_points=50,
axes=False,
background_color='black',
figsize=(3, 3),
line_width=0.8
)
plt.show()
$$ \text{Parametric Tangent Transform: Applies a hyperbolic tangent-like transformation.} $$ $$ \text{Transforms } x \text{ as } \frac{3^2 \cdot x}{2^2 \cdot y} \text{ and leaves } y \text{ unchanged.} $$
This transform applies a hyperbolic tangent-like transformation to the $x$-coordinate while leaving the $y$-coordinate unchanged. The result is a stretching or compressing effect along the $x$-axis, depending on the value of $y$.
# This is the implementation for
# parabolic tangent(?)
def parametric_tangent_transform(x, y):
x_transformed = x+(1/2)*x*y
y_transformed = y
return x_transformed, y_transformed
def purple_gradient_color(x, y):
x_range = (-3*np.pi, 3*np.pi)
y_range = (-3*np.pi, 3*np.pi)
norm_x = (x - x_range[0]) / (x_range[1] - x_range[0])
return (0.4, norm_x, 0.8)
fig, ax = transform_2d_plot(
transform_func=parametric_tangent_transform,
x_range=(-3*np.pi, 3*np.pi),
y_range=(-3*np.pi, 3*np.pi),
color_function=purple_gradient_color,
plot_points=50,
axes=False,
background_color='black',
figsize=(3, 3),
line_width=0.8
)
plt.show()
# This is the implementation for
# hyperbolic tangent(?)
def parametric_tangent_transform(x, y):
x_transformed = (3**2 * x) / (2**2 *y) #(np.sqrt(np.abs(y)) + 1e-10))
y_transformed = y
return x_transformed, y_transformed
fig, ax = transform_2d_plot(
transform_func=parametric_tangent_transform,
x_range=(-3*np.pi, 3*np.pi),
y_range=(-3*np.pi, 3*np.pi),
color_function=purple_gradient_color,
plot_points=50,
axes=False,
background_color='black',
figsize=(3, 3),
line_width=0.8
)
plt.show()
$$ \text{Sine Transform: Maps } (x, y) \text{ using trigonometric functions.} $$ $$ \text{Transforms } (x, y) \text{ as } (\cos(y), \sin(x)). $$
This transform maps the coordinates using trigonometric functions, creating a wave-like pattern. The $x$-coordinate is replaced with $cos(y)$, and the $y$-coordinate is replaced with $\sin(x)$. This results in a complex, oscillating distortion.
# This is the implementation for
# x'=cos(y), y'=sin(x)
def sine_transform(x, y):
x_transformed = np.cos(y)
y_transformed = np.sin(x)
return x_transformed, y_transformed
fig, ax = transform_2d_plot(
transform_func=sine_transform,
x_range=(-3*np.pi, 3*np.pi),
y_range=(-3*np.pi, 3*np.pi),
color_function=purple_gradient_color,
plot_points=50,
axes=False,
background_color='black',
figsize=(3, 3),
line_width=0.8
)
plt.show()
$$ \text{Polynomial Transforms: Applies polynomial mappings to } (x, y). $$ $$ \text{For example, } (y \cdot x, x^2) \text{ or } (y \cdot x, x^3). $$
These transforms apply polynomial functions to the coordinates, such as multiplying (x) and (y) or raising (x) to a power. The resulting distortions can create curves, folds, or other nonlinear effects depending on the polynomial used.
# This is the implementation for
# y'=x^2, x'=y*x
def poly2_transform(x, y):
x_transformed = y*x
y_transformed = x*x
return x_transformed, y_transformed
fig, ax = transform_2d_plot(
transform_func=poly2_transform,
x_range=(-3*np.pi, 3*np.pi),
y_range=(-3*np.pi, 3*np.pi),
color_function=purple_gradient_color,
plot_points=50,
axes=False,
background_color='black',
figsize=(3, 3),
line_width=0.8
)
plt.show()
# This is the implementation for
# y'=x^3, x'=y*x
def poly3_transform(x, y):
x_transformed = y*x
y_transformed = x*x*x
return x_transformed, y_transformed
fig, ax = transform_2d_plot(
transform_func=poly3_transform,
x_range=(-3*np.pi, 3*np.pi),
y_range=(-3*np.pi, 3*np.pi),
color_function=purple_gradient_color,
plot_points=50,
axes=False,
background_color='black',
figsize=(3, 3),
line_width=0.8
)
plt.show()
$$ \text{Trigonometric Transforms: Combines trigonometric functions with } (x, y). $$ $$ \text{For example, } (\sin(y) \cdot \cos(y), x \cdot y) \text{ or } (\tan(y), x \cdot y). $$
These transforms combine trigonometric functions (e.g., sine, cosine, tangent) with the coordinates. The result is a complex, periodic distortion that can create intricate patterns or waves.
# This is the implementation for
# y'=xy, x'=sin(y)cos(y)
def trig1_transform(x, y):
x_transformed = np.sin(y)*np.cos(y)
y_transformed = x*y
return x_transformed, y_transformed
fig, ax = transform_2d_plot(
transform_func=trig1_transform,
x_range=(-3*np.pi, 3*np.pi),
y_range=(-3*np.pi, 3*np.pi),
color_function=purple_gradient_color,
plot_points=50,
axes=False,
background_color='black',
figsize=(3, 3),
line_width=0.8
)
plt.show()
# This is the implementation for
# y'=xy, x'=sin(y)+cos(y)
def trig2_transform(x, y):
x_transformed = np.sin(y)+np.cos(y)
y_transformed = x*y
return x_transformed, y_transformed
fig, ax = transform_2d_plot(
transform_func=trig2_transform,
x_range=(-3*np.pi, 3*np.pi),
y_range=(-3*np.pi, 3*np.pi),
color_function=purple_gradient_color,
plot_points=50,
axes=False,
background_color='black',
figsize=(3, 3),
line_width=0.8
)
plt.show()
# This is the implementation for
# y'=xy, x'=tan(x)cos(y)
def trig3_transform(x, y):
x_transformed = np.tan(y)*np.cos(y)
y_transformed = x*y
return x_transformed, y_transformed
fig, ax = transform_2d_plot(
transform_func=trig3_transform,
x_range=(-3*np.pi, 3*np.pi),
y_range=(-3*np.pi, 3*np.pi),
color_function=purple_gradient_color,
plot_points=50,
axes=False,
background_color='black',
figsize=(3, 3),
line_width=0.8
)
plt.show()
# This is the implementation for
# y'=xy, x'=tanh(x)
def trig5_transform(x, y):
x_transformed = np.tanh(y)
y_transformed = x*y
return x_transformed, y_transformed
fig, ax = transform_2d_plot(
transform_func=trig5_transform,
x_range=(-3*np.pi, 3*np.pi),
y_range=(-3*np.pi, 3*np.pi),
color_function=purple_gradient_color,
plot_points=50,
axes=False,
background_color='black',
figsize=(3, 3),
line_width=0.3
)
plt.xlim(-3, 3)
plt.ylim(-3, 3)
plt.show()
$$ \text{Exponential Transform: Uses exponential functions to transform } (x, y). $$ $$ \text{Transforms } (x, y) \text{ as } (x \cdot y, \exp(x)). $$
This transform applies exponential functions to the coordinates, such as $\exp(x)$. The result is a rapid scaling or distortion that intensifies for larger values of $x$, creating dramatic effects.
# This is the implementation for
# y'=exp(x), x'=x*y
def exp_transform(x, y):
x_transformed = x*y
y_transformed = np.exp(x)
return x_transformed, y_transformed
fig, ax = transform_2d_plot(
transform_func=exp_transform,
x_range=(-3*np.pi, 3*np.pi),
y_range=(-3*np.pi, 3*np.pi),
color_function=purple_gradient_color,
plot_points=50,
axes=False,
background_color='black',
figsize=(3, 3),
line_width=0.3
)
plt.xlim(-3, 3)
plt.ylim(0, 6)
plt.show()
# This is the implementation for
# y'=x*y, x'=x*x*x
def exp2_transform(x, y):
x_transformed = x*x*x
y_transformed = x*y
return x_transformed, y_transformed
fig, ax = transform_2d_plot(
transform_func=exp2_transform,
x_range=(-3*np.pi, 3*np.pi),
y_range=(-3*np.pi, 3*np.pi),
color_function=purple_gradient_color,
plot_points=50,
axes=False,
background_color='black',
figsize=(3, 3),
line_width=0.3
)
plt.xlim(-3, 3)
plt.ylim(0, 6)
plt.show()
$$ \text{Zeta Transform: Applies the Riemann zeta function to } (x, y). $$ $$ \text{Transforms } (x, y) \text{ as } (x \cdot y, \text{Re}(\zeta(x))). $$
This transform uses the Riemann zeta function $\zeta(x)$ to modify the coordinates. The real part of $\zeta(x)$ is applied to the $y$-coordinate, creating a distortion that reflects the complex behavior of the zeta function.
# for the zeta function
from mpmath import zeta
def zeta_function(x):
if np.abs(x - 1) < 1e-6:
return np.nan
return np.real(zeta(x))
def zeta_transform(x, y):
x_transformed = x * y
y_transformed = zeta_function(x)
return x_transformed, y_transformed
transform_2d_plot(
transform_func=zeta_transform,
x_range=(-3*np.pi, 3*np.pi),
y_range=(-3*np.pi, 3*np.pi),
color_function=purple_gradient_color,
plot_points=30,
axes=True,
background_color='black',
figsize=(3, 3),
line_width=0.5,
)
plt.xlim(-0.5, 0.5)
plt.ylim(-1, 0)
(-1.0, 0.0)
def sine_normalize_transform(x, y):
r = np.sqrt(x**2 + y**2)
if r < 1e-10:
return 0, 0
nx, ny = x/r, y/r
sine_factor = np.sin(r)
x_transformed = sine_factor * nx
y_transformed = sine_factor * ny
return x_transformed, y_transformed
transform_2d_plot(
transform_func=sine_normalize_transform,
x_range=(-3*np.pi, 3*np.pi),
y_range=(-3*np.pi, 3*np.pi),
color_function=purple_gradient_color,
plot_points=40,
axes=True,
background_color='black',
figsize=(3, 3),
line_width=0.5,
)
plt.xlim(-1, 1)
plt.ylim(-1, 1)
(-1.0, 1.0)
def tanexptan_normalize_transform(x, y):
r = np.sqrt(x**2 + y**2)
if r < 1e-10:
return 0, 0
nx, ny = x/r, y/r
tan_factor = np.tan(r)/np.exp(np.tan(r))
x_transformed = tan_factor * nx
y_transformed = tan_factor * ny
return x_transformed, y_transformed
transform_2d_plot(
transform_func=tanexptan_normalize_transform,
x_range=(-3*np.pi, 3*np.pi),
y_range=(-3*np.pi, 3*np.pi),
color_function=purple_gradient_color,
plot_points=15,
axes=True,
background_color='black',
figsize=(3, 3),
line_width=0.5,
)
plt.xlim(-5, 5)
plt.ylim(-5, 5)
(-5.0, 5.0)
def log_normalize_transform(x, y):
r = np.sqrt(x**2 + y**2)
if r < 1e-10:
return 0, 0
nx, ny = x/r, y/r
x_transformed = nx*np.log(r)
y_transformed = ny*np.log(r)
return x_transformed, y_transformed
transform_2d_plot(
transform_func=log_normalize_transform,
x_range=(-3*np.pi, 3*np.pi),
y_range=(-3*np.pi, 3*np.pi),
color_function=purple_gradient_color,
plot_points=40,
axes=True,
background_color='black',
figsize=(3, 3),
line_width=0.5,
)
plt.xlim(-2, 2)
plt.ylim(-2, 2)
(-2.0, 2.0)
def sincos_normalize_transform(x, y):
r = np.sqrt(x**2 + y**2)
if r < 1e-10:
return 0, 0
nx, ny = x/r, y/r
sin_factor = np.sin(r)
cos_factor = np.cos(r)
x_transformed = sin_factor * nx
y_transformed = cos_factor * ny
return x_transformed, y_transformed
transform_2d_plot(
transform_func=sincos_normalize_transform,
x_range=(-3*np.pi, 3*np.pi),
y_range=(-3*np.pi, 3*np.pi),
color_function=purple_gradient_color,
plot_points=15,
axes=True,
background_color='black',
figsize=(3, 3),
line_width=0.5,
)
plt.xlim(-1, 1)
plt.ylim(-1, 1)
(-1.0, 1.0)
$$ \text{Mandelbrot Transform: Iterates complex numbers to generate fractal patterns.} $$ $$ \text{Transforms } (x, y) \text{ based on escape time and angle of complex iteration.} $$
This transform uses the Mandelbrot set algorithm to generate fractal patterns. The coordinates are iterated as complex numbers $z = z^2 + c$, and the transformation depends on the escape time and angle of iteration.
def mandelbrot_transform(x, y):
c = complex(x, y)
z = complex(0, 0)
max_iter = 500
escape_radius = 2.0
for i in range(max_iter):
z = z*z + c
if abs(z) > escape_radius:
escape_value = i / max_iter
angle = np.angle(z)
mag = np.log(abs(z)) / 10
x_transformed = mag * np.cos(angle)
y_transformed = mag * np.sin(angle)
return x_transformed, y_transformed
return 0, 0
def mandelbrot_color(x, y):
c = complex(x, y)
z = complex(0, 0)
max_iter = 30
escape_radius = 2.0
for i in range(max_iter):
z = z*z + c
if abs(z) > escape_radius:
hue = i / max_iter
return (0.5 + 0.5*np.sin(hue*6), 0.8, 1.0 - 0.7*hue)
return (0.0, 0.0, 0.0)
transform_2d_plot(
transform_func=mandelbrot_transform,
x_range=(-2.0, 1.0),
y_range=(-1.5, 1.5),
color_function=mandelbrot_color,
plot_points=15,
axes=True,
background_color='black',
figsize=(3, 3),
line_width=0.5,
)
plt.xlim(-0.2, 0.2)
plt.ylim(-0.2, 0.2)
(-0.2, 0.2)
$$ \text{Julia Transform: Similar to Mandelbrot but with a fixed complex constant } c. $$ $$ \text{Transforms } (x, y) \text{ based on escape time and angle for } z = z^2 + c. $$
This transform is similar to the Mandelbrot transform but uses a fixed complex constant $c$. The resulting patterns are Julia sets, which are fractals with intricate, self-similar structures.
def julia_transform(c):
def transform(x, y):
z = complex(x, y)
max_iter = 500
escape_radius = 2.0
for i in range(max_iter):
z = z*z + c
if abs(z) > escape_radius:
escape_value = i / max_iter
angle = np.angle(z)
mag = np.log(abs(z)) / 10
x_transformed = mag * np.cos(angle)
y_transformed = mag * np.sin(angle)
return x_transformed, y_transformed
return 0, 0
return transform
def julia_color(c):
def color_func(x, y):
z = complex(x, y)
max_iter = 30
escape_radius = 2.0
for i in range(max_iter):
z = z*z + c
if abs(z) > escape_radius:
hue = i / max_iter
return hsv_to_rgb(np.array([hue, 0.8, 1.0]).reshape(1, 1, 3)).flatten()
return np.array([0.0, 0.0, 0.0])
return color_func
julia_seeds = [
complex(-0.8, 0.156),
complex(-0.4, 0.6),
complex(0.285, 0.01),
complex(-0.7269, 0.1889),
complex(-0.8, 0.2),
complex(0.35, -0.05)
]
for i, seed in enumerate(julia_seeds):
transform_func = julia_transform(seed)
color_func = julia_color(seed)
transform_2d_plot(
transform_func=transform_func,
x_range=(-1.5, 1.5),
y_range=(-1.5, 1.5),
color_function=color_func,
plot_points=12,
axes=False,
background_color='black',
figsize=(3, 3),
line_width=0.5,
)
plt.xlim(-0.2, 0.2)
plt.ylim(-0.2, 0.2)
plt.title(f"c = {seed}", color='white', fontsize=10)
$$ \text{Normalization Transforms: Normalizes } (x, y) \text{ by radial distance.} $$ $$ \text{For example, } \left(\frac{x}{r}, \frac{y}{r}\right) \text{ or } \left(\frac{x \cdot \log(r)}{r}, \frac{y \cdot \log(r)}{r}\right). $$
These transforms normalize the coordinates by dividing by the radial distance $r$. This can create a radial scaling effect, with optional logarithmic adjustments for more complex distortions.
def normalize_transform(x, y):
r = np.sqrt(x**2 + y**2) + 1/2
if r < 1e-10:
return 0, 0
nx, ny = x/r, y/r
x_transformed = nx
y_transformed = ny
return x_transformed, y_transformed
transform_2d_plot(
transform_func=normalize_transform,
x_range=(-3*np.pi, 3*np.pi),
y_range=(-3*np.pi, 3*np.pi),
color_function=purple_gradient_color,
plot_points=100,
axes=True,
background_color='black',
figsize=(3, 3),
line_width=0.5,
)
plt.xlim(-1, 1)
plt.ylim(-1, 1)
plt.show()