plots added
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -9,3 +9,4 @@
|
|||||||
**/*.bbl
|
**/*.bbl
|
||||||
**/**.dat
|
**/**.dat
|
||||||
**/**.script
|
**/**.script
|
||||||
|
**/venv/**
|
||||||
|
|||||||
140
plots/demo-plot-1/README.md
Normal file
140
plots/demo-plot-1/README.md
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
# Parametric Surface Plotter
|
||||||
|
|
||||||
|
This project provides a simple way to **define and plot parametric 3D surfaces** (or curves) using Python.
|
||||||
|
|
||||||
|
* A **surface** is defined with **two parameters**:
|
||||||
|
|
||||||
|
$$
|
||||||
|
x = x(t, u), \quad y = y(t, u), \quad z = z(t, u)
|
||||||
|
$$
|
||||||
|
|
||||||
|
* A **curve** is defined with a **single parameter**:
|
||||||
|
|
||||||
|
$$
|
||||||
|
x = x(t), \quad y = y(t), \quad z = z(t)
|
||||||
|
$$
|
||||||
|
|
||||||
|
The script will:
|
||||||
|
|
||||||
|
* Generate a mesh of points (for surfaces) or a set of points (for curves)
|
||||||
|
* Plot the result in 3D with Matplotlib
|
||||||
|
* Save the plot as a high-definition `.svg` file, named after the parent directory of the script
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
Install dependencies:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pip install -r requirements.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
Run the script:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python plot_surface.py
|
||||||
|
```
|
||||||
|
|
||||||
|
A window with the 3D plot will open, and an `.svg` will be saved in the same directory.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Defining Your Own Geometry
|
||||||
|
|
||||||
|
### 1. Surfaces (two parameters: t, u)
|
||||||
|
|
||||||
|
Surfaces require two parameters because they are 2D objects.
|
||||||
|
You define three functions in `plot_surface.py`:
|
||||||
|
|
||||||
|
```python
|
||||||
|
def x_func(t, u): return ...
|
||||||
|
def y_func(t, u): return ...
|
||||||
|
def z_func(t, u): return ...
|
||||||
|
```
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
* **Cone**
|
||||||
|
|
||||||
|
$$
|
||||||
|
x = 4t\cos(u), \quad y = 4t\sin(u), \quad z = 10t
|
||||||
|
$$
|
||||||
|
|
||||||
|
```python
|
||||||
|
def x_func(t, u): return 4 * t * np.cos(u)
|
||||||
|
def y_func(t, u): return 4 * t * np.sin(u)
|
||||||
|
def z_func(t, u): return 10 * t
|
||||||
|
```
|
||||||
|
|
||||||
|
* **Sphere** (radius 1)
|
||||||
|
|
||||||
|
$$
|
||||||
|
x = \cos(u)\sin(t), \quad y = \sin(u)\sin(t), \quad z = \cos(t)
|
||||||
|
$$
|
||||||
|
|
||||||
|
```python
|
||||||
|
def x_func(t, u): return np.cos(u) * np.sin(t)
|
||||||
|
def y_func(t, u): return np.sin(u) * np.sin(t)
|
||||||
|
def z_func(t, u): return np.cos(t)
|
||||||
|
```
|
||||||
|
|
||||||
|
You can adjust parameter ranges in `generate_mesh()`:
|
||||||
|
|
||||||
|
```python
|
||||||
|
def generate_mesh(t_range=(0, 5), u_range=(0, 2*np.pi), n_t=50, n_u=100):
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
|
* Sphere → `t_range=(0, np.pi)`, `u_range=(0, 2*np.pi)`
|
||||||
|
* Cone → `t_range=(0, 5)`, `u_range=(0, 2*np.pi)`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 2. Curves (one parameter: t)
|
||||||
|
|
||||||
|
If your object is not a surface but a **curve**, you only need one parameter $t$.
|
||||||
|
|
||||||
|
Example: **Helix**
|
||||||
|
|
||||||
|
$$
|
||||||
|
x = \cos(t), \quad y = \sin(t), \quad z = t
|
||||||
|
$$
|
||||||
|
|
||||||
|
```python
|
||||||
|
def x_func(t): return np.cos(t)
|
||||||
|
def y_func(t): return np.sin(t)
|
||||||
|
def z_func(t): return t
|
||||||
|
```
|
||||||
|
|
||||||
|
Here you don’t need `u` at all. The code can be simplified to generate a 1D array of points and plot them as a line in 3D.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Which Should I Use?
|
||||||
|
|
||||||
|
* **Two parameters (t, u):** Use this for **surfaces** (sphere, torus, cone, paraboloid, etc.).
|
||||||
|
* **One parameter (t):** Use this for **curves** (helix, circle, line, parametric trajectory).
|
||||||
|
|
||||||
|
👉 A quick rule:
|
||||||
|
|
||||||
|
* If your equation is like $z = f(x, y)$, or implicit in 3 variables, you usually need **two parameters**.
|
||||||
|
* If your equation is like $x = f(t), y = g(t), z = h(t)$, then **one parameter** is enough.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
* Always use `numpy` functions (`np.sin`, `np.cos`, etc.), not Python’s built-ins, since the parameters are arrays.
|
||||||
|
* Some surfaces (like cones, hyperboloids) have two branches; you can add an additional `z_func_neg` if needed.
|
||||||
|
* The SVG is automatically named after the script’s parent directory.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
✅ With this, you can parametrize and visualize **both surfaces (2D)** and **curves (1D)** by editing only a few functions.
|
||||||
|
|
||||||
|
|
||||||
BIN
plots/demo-plot-1/demo-plot-1.png
Normal file
BIN
plots/demo-plot-1/demo-plot-1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 18 MiB |
100
plots/demo-plot-1/main.py
Normal file
100
plots/demo-plot-1/main.py
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
import os
|
||||||
|
import numpy as np
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
from mpl_toolkits.mplot3d import Axes3D # needed for 3D plotting
|
||||||
|
from matplotlib import rcParams
|
||||||
|
|
||||||
|
# -------------------------------
|
||||||
|
# Parametric surface functions
|
||||||
|
# -------------------------------
|
||||||
|
def x_func(t, u):
|
||||||
|
"""Parametric x(t,u)"""
|
||||||
|
return 4 * t * np.cos(u)
|
||||||
|
|
||||||
|
def y_func(t, u):
|
||||||
|
"""Parametric y(t,u)"""
|
||||||
|
return 4 * t * np.sin(u)
|
||||||
|
|
||||||
|
def z_func(t, u):
|
||||||
|
"""Parametric z(t,u)"""
|
||||||
|
return 10 * t
|
||||||
|
|
||||||
|
def z_func_neg(t, u):
|
||||||
|
"""Optional lower branch"""
|
||||||
|
return -10 * t
|
||||||
|
|
||||||
|
# -------------------------------
|
||||||
|
# Generate mesh
|
||||||
|
# -------------------------------
|
||||||
|
def generate_mesh(t_range=(0, 5), u_range=(0, 2*np.pi), n_t=200, n_u=400):
|
||||||
|
"""High-resolution parametric mesh"""
|
||||||
|
t = np.linspace(t_range[0], t_range[1], n_t)
|
||||||
|
u = np.linspace(u_range[0], u_range[1], n_u)
|
||||||
|
T, U = np.meshgrid(t, u)
|
||||||
|
X = x_func(T, U)
|
||||||
|
Y = y_func(T, U)
|
||||||
|
Z1 = z_func(T, U)
|
||||||
|
Z2 = z_func_neg(T, U)
|
||||||
|
return X, Y, Z1, Z2
|
||||||
|
|
||||||
|
# -------------------------------
|
||||||
|
# Plot surface with high-quality settings
|
||||||
|
# -------------------------------
|
||||||
|
def plot_surface():
|
||||||
|
# Generate high-res mesh
|
||||||
|
X, Y, Z1, Z2 = generate_mesh()
|
||||||
|
|
||||||
|
# Create figure with high DPI
|
||||||
|
fig = plt.figure(figsize=(12, 10), dpi=600)
|
||||||
|
ax = fig.add_subplot(111, projection="3d")
|
||||||
|
|
||||||
|
# Smooth shading, anti-aliasing
|
||||||
|
surf1 = ax.plot_surface(
|
||||||
|
X, Y, Z1,
|
||||||
|
cmap="viridis",
|
||||||
|
edgecolor="none",
|
||||||
|
rstride=1,
|
||||||
|
cstride=1,
|
||||||
|
antialiased=True,
|
||||||
|
linewidth=0,
|
||||||
|
alpha=0.95
|
||||||
|
)
|
||||||
|
|
||||||
|
surf2 = ax.plot_surface(
|
||||||
|
X, Y, Z2,
|
||||||
|
cmap="viridis",
|
||||||
|
edgecolor="none",
|
||||||
|
rstride=1,
|
||||||
|
cstride=1,
|
||||||
|
antialiased=True,
|
||||||
|
linewidth=0,
|
||||||
|
alpha=0.95
|
||||||
|
)
|
||||||
|
|
||||||
|
# Axis labels and title
|
||||||
|
ax.set_xlabel("X", labelpad=15)
|
||||||
|
ax.set_ylabel("Y", labelpad=15)
|
||||||
|
ax.set_zlabel("Z", labelpad=15)
|
||||||
|
ax.set_title("Parametric Surface", pad=20)
|
||||||
|
|
||||||
|
# Optional: adjust viewing angle
|
||||||
|
ax.view_init(elev=30, azim=45)
|
||||||
|
|
||||||
|
# Add colorbar
|
||||||
|
fig.colorbar(surf1, shrink=0.5, aspect=10, pad=0.1)
|
||||||
|
|
||||||
|
# Save at maximum quality
|
||||||
|
parent_dir = os.path.basename(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
filename_png = f"{parent_dir}.png"
|
||||||
|
|
||||||
|
plt.savefig(filename_png, format="png", dpi=1200, bbox_inches='tight') # ultra-high-res raster
|
||||||
|
print(f"and PNG as {filename_png}")
|
||||||
|
|
||||||
|
# Show interactive window (optional)
|
||||||
|
|
||||||
|
# -------------------------------
|
||||||
|
# Main
|
||||||
|
# -------------------------------
|
||||||
|
if __name__ == "__main__":
|
||||||
|
plot_surface()
|
||||||
|
|
||||||
Reference in New Issue
Block a user