Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I show transformation of coordinate grid lines in python?

Suppose I have the regular cartesian coordinate system $(x,y)$ and I consider a rectangular mesh region $D$ (split into little squares). I want to see how the domain D would be mapped under a coordinate transform T:(x,y) -> (u(x,y) ,v(x,y) ) in Python?

I'm looking for something like this:

enter image description here

See here.

Could I be advised on how this could be done? I am a total beginner at python and programming.

like image 679
Clemens Bartholdy Avatar asked Oct 27 '25 13:10

Clemens Bartholdy


1 Answers

If I understand you correctly, you want to be able to see a sort of a grid plot of a transformed cartesian space? In that case, maybe something like this, using Numpy and Matplotlib. (You could do the same with just Pillow to draw some lines, but this is more convenient...)

EDIT: Following the discussion in the comments, I changed this a bit compared to the simpler original (see edit history), to make it easier to plot multiple transformations, as well as to color the lines to make it easier to follow how they're transformed. It's still pretty simple, though. (For fun, I also threw in a couple of extra transformations.)

import math

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm

colormap = cm.get_cmap("rainbow")


def plot_grid(
    xmin: float,
    xmax: float,
    ymin: float,
    ymax: float,
    n_lines: int,
    line_points: int,
    map_func,
):
    """
    Plot a transformation of a regular grid.

    :param xmin: Minimum x value
    :param xmax: Maximum x value
    :param ymin: Minimum y value
    :param ymax: Maximum y value
    :param n_lines: Number of lines per axis
    :param line_points: Number of points per line
    :param map_func: Function to map the grid points to new coordinates
    """
    # List for gathering the lines into.
    lines = []

    # Iterate over horizontal lines.
    for y in np.linspace(ymin, ymax, n_lines):
        lines.append([map_func(x, y) for x in np.linspace(xmin, xmax, line_points)])

    # Iterate over vertical lines.
    for x in np.linspace(xmin, xmax, n_lines):
        lines.append([map_func(x, y) for y in np.linspace(ymin, ymax, line_points)])

    # Plot all the lines.
    for i, line in enumerate(lines):
        p = i / (len(lines) - 1)  # Normalize to 0-1.
        # Transpose the list of points for passing to plot.
        xs, ys = zip(*line)
        # Get the line color from the colormap.
        plt.plot(xs, ys, color=colormap(p))


# Define some mapping functions.


def identity(x, y):
    return x, y


def example(x, y):
    c = complex(x, y) ** 2
    return (c.real, c.imag)


def wobbly(x: float, y: float):
    return x + math.sin(y * 2) * 0.2, y + math.cos(x * 2) * 0.3


def vortex(x: float, y: float):
    dst = (x - 2) ** 2 + (y - 2) ** 2
    ang = math.atan2(y - 2, x - 2)
    return math.cos(ang - dst * 0.1) * dst, math.sin(ang - dst * 0.1) * dst


# Set up the plot surface...
plt.figure(figsize=(8, 8))
plt.tight_layout()

plt.subplot(2, 2, 1)
plt.title("Identity")
plot_grid(0, 4, 0, 4, 10, 10, identity)

plt.subplot(2, 2, 2)
plt.title("Example")
plot_grid(0, 4, 0, 4, 10, 10, example)

plt.subplot(2, 2, 3)
plt.title("Wobbly")
plot_grid(0, 4, 0, 4, 10, 40, wobbly)

plt.subplot(2, 2, 4)
plt.title("Vortex")
plot_grid(0, 4, 0, 4, 10, 40, vortex)

plt.savefig("so71735261-2.png")
plt.show()

The result image is: enter image description here

like image 194
AKX Avatar answered Oct 29 '25 02:10

AKX