89 lines
2.5 KiB
Python
89 lines
2.5 KiB
Python
import matplotlib.pyplot as plt
|
|
import numpy as np
|
|
from sympy.abc import x, y
|
|
from sympy.plotting import plot_implicit
|
|
|
|
from .anim import animate
|
|
|
|
def _first_nonzero(arr: np.ndarray, axis: int):
|
|
mask = arr!=0
|
|
return min(np.where(mask.any(axis=axis), mask.argmax(axis=axis), arr.shape[axis] + 1))
|
|
|
|
def latex_polynumber(
|
|
arr: np.ndarray,
|
|
center: tuple[int, int] | None = None,
|
|
show_zero: bool = False
|
|
):
|
|
upper_left = _first_nonzero(arr, 0), _first_nonzero(arr, 1)
|
|
lower_right = (
|
|
len(arr) - _first_nonzero(np.flip(arr, 0), 0) - 1,
|
|
len(arr[1]) - _first_nonzero(np.flip(arr, 1), 1) - 1
|
|
)
|
|
|
|
center_left, center_top = center or (0, 0)
|
|
if center is not None:
|
|
# this does not need offset, since we iterate over this range
|
|
center_top = center[0]
|
|
# but this does for the array environment argument
|
|
center_left = center[1] - upper_left[1]
|
|
|
|
num_columns = lower_right[1] - upper_left[1]
|
|
column_layout = ("c" * center_left) + "|" + ("c" * (num_columns - center_left))
|
|
|
|
# build array output
|
|
ret = "\\begin{array}{" + column_layout + "}"
|
|
for i in range(upper_left[0], lower_right[0] + 1):
|
|
if i == center_top:
|
|
ret += " \\hline "
|
|
ret += " & ".join([
|
|
str(arr[i,j] if arr[i,j] != 0 or show_zero else "")
|
|
for j in range(upper_left[1], lower_right[1] + 1)
|
|
])
|
|
# next row
|
|
ret += " \\\\ "
|
|
return ret + "\\end{array}"
|
|
|
|
|
|
def poly_from_array(array):
|
|
ret = 0
|
|
for i, row in enumerate(array):
|
|
for j, val in enumerate(row):
|
|
ret += val*(x**i * y**j)
|
|
return ret
|
|
|
|
def bindfig(fig):
|
|
def ret(**kwargs):
|
|
for i, j in kwargs.items():
|
|
if i == "figsize":
|
|
if j is not None:
|
|
fig.set_figwidth(j[0])
|
|
fig.set_figheight(j[1])
|
|
continue
|
|
fig.__dict__["set_" + i](j)
|
|
return fig
|
|
return ret
|
|
|
|
def anim_curves(next_func, dims=25, invalid=2, frames=None, interval=200):
|
|
zero = np.zeros((dims, dims), dtype=np.int32)
|
|
#zero[0,0] = 1
|
|
fig = plt.gcf()
|
|
#plt.colorbar()
|
|
|
|
#temp = plt.figure
|
|
#I hate doing it, but there's no other way to get the figure before it's plotted
|
|
plt.figure = bindfig(fig)
|
|
|
|
@animate(fig, frames, interval=interval)
|
|
def ret(fr):
|
|
next_func(zero, invalid)
|
|
fig.clf()
|
|
plot_implicit(
|
|
poly_from_array(zero) - fr,
|
|
backend='matplotlib',
|
|
adaptive=False
|
|
)
|
|
plt.title(f"{fr+1}")
|
|
print(fr)
|
|
|
|
return ret
|