Spaces:
Sleeping
Sleeping
| from __future__ import annotations | |
| import io | |
| import tempfile | |
| import matplotlib | |
| matplotlib.use("Agg") | |
| import matplotlib.pyplot as plt | |
| import numpy as np | |
| def plot_function( | |
| expression: str, | |
| x_range: tuple[float, float] = (-10, 10), | |
| title: str = "", | |
| xlabel: str = "x", | |
| ylabel: str = "y", | |
| ) -> str: | |
| """Plot a mathematical function and return the path to the saved image. | |
| Args: | |
| expression: A numpy-compatible expression string using 'x' as variable. | |
| Examples: "np.sin(x)", "x**2 - 3*x + 2", "np.exp(-x**2)" | |
| x_range: Tuple of (x_min, x_max). | |
| title: Plot title. | |
| xlabel: X-axis label. | |
| ylabel: Y-axis label. | |
| Returns: | |
| Path to the saved PNG image. | |
| """ | |
| x = np.linspace(x_range[0], x_range[1], 500) | |
| try: | |
| y = eval(expression, {"x": x, "np": np, "pi": np.pi, "e": np.e}) | |
| except Exception as e: | |
| return _error_plot(f"Cannot evaluate: {expression}\n{e}") | |
| fig, ax = plt.subplots(figsize=(8, 5)) | |
| ax.plot(x, y, "b-", linewidth=2) | |
| ax.set_title(title or f"$y = {expression}$") | |
| ax.set_xlabel(xlabel) | |
| ax.set_ylabel(ylabel) | |
| ax.grid(True, alpha=0.3) | |
| ax.axhline(y=0, color="k", linewidth=0.5) | |
| ax.axvline(x=0, color="k", linewidth=0.5) | |
| return _save_fig(fig) | |
| def plot_multiple( | |
| expressions: list[dict], | |
| x_range: tuple[float, float] = (-10, 10), | |
| title: str = "", | |
| ) -> str: | |
| """Plot multiple functions on the same axes. | |
| Args: | |
| expressions: List of {"expr": str, "label": str} dicts. | |
| x_range: Tuple of (x_min, x_max). | |
| title: Plot title. | |
| Returns: | |
| Path to the saved PNG image. | |
| """ | |
| x = np.linspace(x_range[0], x_range[1], 500) | |
| fig, ax = plt.subplots(figsize=(8, 5)) | |
| for item in expressions: | |
| expr = item["expr"] | |
| label = item.get("label", expr) | |
| try: | |
| y = eval(expr, {"x": x, "np": np, "pi": np.pi, "e": np.e}) | |
| ax.plot(x, y, linewidth=2, label=label) | |
| except Exception: | |
| continue | |
| ax.set_title(title) | |
| ax.grid(True, alpha=0.3) | |
| ax.axhline(y=0, color="k", linewidth=0.5) | |
| ax.axvline(x=0, color="k", linewidth=0.5) | |
| ax.legend() | |
| return _save_fig(fig) | |
| def _save_fig(fig) -> str: | |
| tmp = tempfile.NamedTemporaryFile(suffix=".png", delete=False) | |
| fig.savefig(tmp.name, dpi=100, bbox_inches="tight") | |
| plt.close(fig) | |
| return tmp.name | |
| def _error_plot(message: str) -> str: | |
| fig, ax = plt.subplots(figsize=(8, 5)) | |
| ax.text(0.5, 0.5, message, ha="center", va="center", fontsize=12, color="red") | |
| ax.set_xlim(0, 1) | |
| ax.set_ylim(0, 1) | |
| ax.axis("off") | |
| return _save_fig(fig) | |