Skip to main content
simpler extents
Source Link
Reinderien
  • 71.2k
  • 5
  • 76
  • 257

Don't min() and max() on your axes when you already know what the extents are. Since I demonstrate the use of a parametric n, just base your extent tuple on that.

import numpy as np
import matplotlib.gridspec
import matplotlib.pyplot as plt
import matplotlib.ticker
import scipy.special
from scipy.ndimage import gaussian_filter


def make_coords(n: int = 250) -> tuple[
    np.ndarray,  # r
    np.ndarray,  # theta
    tuple[int, int, int, int],  # axis extents
]:
    # regular cartesian dimensions
    ser = slice(-n, 1+n)
    yx = np.mgrid[ser, ser]
    y, x = yx
    extent = x.min()-n, x.max()n, y.min()-n, y.max()n

    # irregular polar dimensions based on cartesian dimensions
    r = np.linalg.norm(yx, axis=0)
    theta = np.arctan2(y, x)
    return r, theta, extent


def make_fake(
    r: np.ndarray, theta: np.ndarray,
    rand: np.random.Generator | None = None,
) -> np.ndarray:
    if rand is None:
        rand = np.random.default_rng()

    # generate some fake data
    p0 = (
        np.cos(3*theta) * np.sin(np.sqrt(r))
    )**6
    cleanup = (1 - np.exp(-0.01*r**2))*scipy.special.erfc((r - 200)/8)
    lumpy_1 = gaussian_filter(rand.random(r.shape), sigma=1)**2
    lumpy_2 = gaussian_filter(rand.random(r.shape), sigma=60)
    lumpy_2 -= lumpy_2.min()

    p = p0 * cleanup * lumpy_1 * lumpy_2
    p /= p.max()
    return p


def make_hist(theta: np.ndarray, p: np.ndarray) -> np.ndarray:
    """
    Not actually a histogram! This is a binned sum.

    assign a bin index to each pixel, centred on integer degrees
    (remember that Python's .astype(int) by itself rounds both
    +0.99 and -0.99 to zero, so we have to use floor first.
    cf. https://scicomp.stackexchange.com/a/40779/17869)
    """

    # 0-359, integral, where e.g. [-0.5, 0.5) maps to 0
    itheta = np.floor(np.rad2deg(theta) + 0.5).astype(int) % 360

    # binned sum with indices in itheta and values in p
    total = np.bincount(itheta.ravel(), weights=p.ravel())
    return total


def plot_image(
    fig: plt.Figure, ax: plt.Axes,
    p: np.ndarray, extent: tuple[int, int, int, int],
) -> None:
    im = ax.imshow(p, origin='lower', extent=extent)
    bar = fig.colorbar(mappable=im)

    ax.set_title('Sample dataset')
    ax.set_xlabel('x')
    ax.set_ylabel('y')
    bar.set_label('z')


def plot_hist_rect(
    ax: plt.Axes,
    hist: np.ndarray,
) -> None:
    ax.plot(hist)
    ax.xaxis.set_major_locator(matplotlib.ticker.MultipleLocator(30))
    ax.set_title('Binned sum')
    ax.set_xlabel('bin centre angle (deg)')
    ax.set_ylabel('sum')


def plot_hist_polar(
    ax: plt.PolarAxes,
    hist: np.ndarray,
) -> None:
    ax.plot(np.deg2rad(np.arange(360)), hist)
    ax.xaxis.set_major_locator(matplotlib.ticker.FixedLocator(
        np.deg2rad(np.arange(0, 360, 30)),
    ))
    ax.set_title('Binned sum')


def main() -> None:
    # repeatable simulation
    rand = np.random.default_rng(seed=4241)

    r, theta, extent = make_coords()
    p = make_fake(r=r, theta=theta, rand=rand)
    hist = make_hist(theta=theta, p=p)

    fig = plt.figure()
    grid = matplotlib.gridspec.GridSpec(figure=fig, nrows=2, ncols=2)
    plot_image(ax=fig.add_subplot(grid[0,0]), fig=fig, p=p, extent=extent)
    plot_hist_polar(ax=fig.add_subplot(grid[0,1], projection='polar'), hist=hist)
    plot_hist_rect(ax=fig.add_subplot(grid[1,:]), hist=hist)
    fig.tight_layout()
    plt.show()


if __name__ == '__main__':
    main()
import numpy as np
import matplotlib.gridspec
import matplotlib.pyplot as plt
import matplotlib.ticker
import scipy.special
from scipy.ndimage import gaussian_filter


def make_coords(n: int = 250) -> tuple[
    np.ndarray,  # r
    np.ndarray,  # theta
    tuple[int, int, int, int],  # axis extents
]:
    # regular cartesian dimensions
    ser = slice(-n, 1+n)
    yx = np.mgrid[ser, ser]
    y, x = yx
    extent = x.min(), x.max(), y.min(), y.max()

    # irregular polar dimensions based on cartesian dimensions
    r = np.linalg.norm(yx, axis=0)
    theta = np.arctan2(y, x)
    return r, theta, extent


def make_fake(
    r: np.ndarray, theta: np.ndarray,
    rand: np.random.Generator | None = None,
) -> np.ndarray:
    if rand is None:
        rand = np.random.default_rng()

    # generate some fake data
    p0 = (
        np.cos(3*theta) * np.sin(np.sqrt(r))
    )**6
    cleanup = (1 - np.exp(-0.01*r**2))*scipy.special.erfc((r - 200)/8)
    lumpy_1 = gaussian_filter(rand.random(r.shape), sigma=1)**2
    lumpy_2 = gaussian_filter(rand.random(r.shape), sigma=60)
    lumpy_2 -= lumpy_2.min()

    p = p0 * cleanup * lumpy_1 * lumpy_2
    p /= p.max()
    return p


def make_hist(theta: np.ndarray, p: np.ndarray) -> np.ndarray:
    """
    Not actually a histogram! This is a binned sum.

    assign a bin index to each pixel, centred on integer degrees
    (remember that Python's .astype(int) by itself rounds both
    +0.99 and -0.99 to zero, so we have to use floor first.
    cf. https://scicomp.stackexchange.com/a/40779/17869)
    """

    # 0-359, integral, where e.g. [-0.5, 0.5) maps to 0
    itheta = np.floor(np.rad2deg(theta) + 0.5).astype(int) % 360

    # binned sum with indices in itheta and values in p
    total = np.bincount(itheta.ravel(), weights=p.ravel())
    return total


def plot_image(
    fig: plt.Figure, ax: plt.Axes,
    p: np.ndarray, extent: tuple[int, int, int, int],
) -> None:
    im = ax.imshow(p, origin='lower', extent=extent)
    bar = fig.colorbar(mappable=im)

    ax.set_title('Sample dataset')
    ax.set_xlabel('x')
    ax.set_ylabel('y')
    bar.set_label('z')


def plot_hist_rect(
    ax: plt.Axes,
    hist: np.ndarray,
) -> None:
    ax.plot(hist)
    ax.xaxis.set_major_locator(matplotlib.ticker.MultipleLocator(30))
    ax.set_title('Binned sum')
    ax.set_xlabel('bin centre angle (deg)')
    ax.set_ylabel('sum')


def plot_hist_polar(
    ax: plt.PolarAxes,
    hist: np.ndarray,
) -> None:
    ax.plot(np.deg2rad(np.arange(360)), hist)
    ax.xaxis.set_major_locator(matplotlib.ticker.FixedLocator(
        np.deg2rad(np.arange(0, 360, 30)),
    ))
    ax.set_title('Binned sum')


def main() -> None:
    # repeatable simulation
    rand = np.random.default_rng(seed=4241)

    r, theta, extent = make_coords()
    p = make_fake(r=r, theta=theta, rand=rand)
    hist = make_hist(theta=theta, p=p)

    fig = plt.figure()
    grid = matplotlib.gridspec.GridSpec(figure=fig, nrows=2, ncols=2)
    plot_image(ax=fig.add_subplot(grid[0,0]), fig=fig, p=p, extent=extent)
    plot_hist_polar(ax=fig.add_subplot(grid[0,1], projection='polar'), hist=hist)
    plot_hist_rect(ax=fig.add_subplot(grid[1,:]), hist=hist)
    fig.tight_layout()
    plt.show()


if __name__ == '__main__':
    main()

Don't min() and max() on your axes when you already know what the extents are. Since I demonstrate the use of a parametric n, just base your extent tuple on that.

import numpy as np
import matplotlib.gridspec
import matplotlib.pyplot as plt
import matplotlib.ticker
import scipy.special
from scipy.ndimage import gaussian_filter


def make_coords(n: int = 250) -> tuple[
    np.ndarray,  # r
    np.ndarray,  # theta
    tuple[int, int, int, int],  # axis extents
]:
    # regular cartesian dimensions
    ser = slice(-n, 1+n)
    yx = np.mgrid[ser, ser]
    y, x = yx
    extent = -n, n, -n, n

    # irregular polar dimensions based on cartesian dimensions
    r = np.linalg.norm(yx, axis=0)
    theta = np.arctan2(y, x)
    return r, theta, extent


def make_fake(
    r: np.ndarray, theta: np.ndarray,
    rand: np.random.Generator | None = None,
) -> np.ndarray:
    if rand is None:
        rand = np.random.default_rng()

    # generate some fake data
    p0 = (
        np.cos(3*theta) * np.sin(np.sqrt(r))
    )**6
    cleanup = (1 - np.exp(-0.01*r**2))*scipy.special.erfc((r - 200)/8)
    lumpy_1 = gaussian_filter(rand.random(r.shape), sigma=1)**2
    lumpy_2 = gaussian_filter(rand.random(r.shape), sigma=60)
    lumpy_2 -= lumpy_2.min()

    p = p0 * cleanup * lumpy_1 * lumpy_2
    p /= p.max()
    return p


def make_hist(theta: np.ndarray, p: np.ndarray) -> np.ndarray:
    """
    Not actually a histogram! This is a binned sum.

    assign a bin index to each pixel, centred on integer degrees
    (remember that Python's .astype(int) by itself rounds both
    +0.99 and -0.99 to zero, so we have to use floor first.
    cf. https://scicomp.stackexchange.com/a/40779/17869)
    """

    # 0-359, integral, where e.g. [-0.5, 0.5) maps to 0
    itheta = np.floor(np.rad2deg(theta) + 0.5).astype(int) % 360

    # binned sum with indices in itheta and values in p
    total = np.bincount(itheta.ravel(), weights=p.ravel())
    return total


def plot_image(
    fig: plt.Figure, ax: plt.Axes,
    p: np.ndarray, extent: tuple[int, int, int, int],
) -> None:
    im = ax.imshow(p, origin='lower', extent=extent)
    bar = fig.colorbar(mappable=im)

    ax.set_title('Sample dataset')
    ax.set_xlabel('x')
    ax.set_ylabel('y')
    bar.set_label('z')


def plot_hist_rect(
    ax: plt.Axes,
    hist: np.ndarray,
) -> None:
    ax.plot(hist)
    ax.xaxis.set_major_locator(matplotlib.ticker.MultipleLocator(30))
    ax.set_title('Binned sum')
    ax.set_xlabel('bin centre angle (deg)')
    ax.set_ylabel('sum')


def plot_hist_polar(
    ax: plt.PolarAxes,
    hist: np.ndarray,
) -> None:
    ax.plot(np.deg2rad(np.arange(360)), hist)
    ax.xaxis.set_major_locator(matplotlib.ticker.FixedLocator(
        np.deg2rad(np.arange(0, 360, 30)),
    ))
    ax.set_title('Binned sum')


def main() -> None:
    # repeatable simulation
    rand = np.random.default_rng(seed=4241)

    r, theta, extent = make_coords()
    p = make_fake(r=r, theta=theta, rand=rand)
    hist = make_hist(theta=theta, p=p)

    fig = plt.figure()
    grid = matplotlib.gridspec.GridSpec(figure=fig, nrows=2, ncols=2)
    plot_image(ax=fig.add_subplot(grid[0,0]), fig=fig, p=p, extent=extent)
    plot_hist_polar(ax=fig.add_subplot(grid[0,1], projection='polar'), hist=hist)
    plot_hist_rect(ax=fig.add_subplot(grid[1,:]), hist=hist)
    fig.tight_layout()
    plt.show()


if __name__ == '__main__':
    main()
added 1222 characters in body
Source Link
Reinderien
  • 71.2k
  • 5
  • 76
  • 257

Actual histogram

An actual histogram could look like

def make_hist2d(theta: np.ndarray, p: np.ndarray) -> tuple[
    np.ndarray,  # angle bin edges
    np.ndarray,  # value bin edges
    np.ndarray,  # histogram matrix
]:
    continuous_angle = np.rad2deg(theta) % 360
    angle_bin_edges = np.arange(0, 361, 5)
    value_bin_edges = np.linspace(start=0, stop=1, num=21)
    hist, angle_edges, value_edges = np.histogram2d(
        x=continuous_angle.ravel(), y=p.ravel(),
        bins=[angle_bin_edges, value_bin_edges],
    )
    return angle_edges, value_edges, hist


def plot_hist2d_polar(
    ax: plt.PolarAxes,
    angle_bin_edges: np.ndarray,
    value_bin_edges: np.ndarray,
    hist: np.ndarray,
) -> None:
    vv, aa = np.meshgrid(value_bin_edges, angle_bin_edges)
    aa = np.deg2rad(aa)
    hist = np.log(1 + hist)
    ax.pcolormesh(aa, vv, hist, edgecolors='face')
    ax.xaxis.set_major_locator(matplotlib.ticker.FixedLocator(
        np.deg2rad(np.arange(0, 360, 30)),
    ))
    ax.tick_params(axis='y', which='both', labelcolor='white')
    ax.set_title('Histogram, log scale')

histogram

Actual histogram

An actual histogram could look like

def make_hist2d(theta: np.ndarray, p: np.ndarray) -> tuple[
    np.ndarray,  # angle bin edges
    np.ndarray,  # value bin edges
    np.ndarray,  # histogram matrix
]:
    continuous_angle = np.rad2deg(theta) % 360
    angle_bin_edges = np.arange(0, 361, 5)
    value_bin_edges = np.linspace(start=0, stop=1, num=21)
    hist, angle_edges, value_edges = np.histogram2d(
        x=continuous_angle.ravel(), y=p.ravel(),
        bins=[angle_bin_edges, value_bin_edges],
    )
    return angle_edges, value_edges, hist


def plot_hist2d_polar(
    ax: plt.PolarAxes,
    angle_bin_edges: np.ndarray,
    value_bin_edges: np.ndarray,
    hist: np.ndarray,
) -> None:
    vv, aa = np.meshgrid(value_bin_edges, angle_bin_edges)
    aa = np.deg2rad(aa)
    hist = np.log(1 + hist)
    ax.pcolormesh(aa, vv, hist, edgecolors='face')
    ax.xaxis.set_major_locator(matplotlib.ticker.FixedLocator(
        np.deg2rad(np.arange(0, 360, 30)),
    ))
    ax.tick_params(axis='y', which='both', labelcolor='white')
    ax.set_title('Histogram, log scale')

histogram

fix up polar locator
Source Link
Reinderien
  • 71.2k
  • 5
  • 76
  • 257
import numpy as np
import matplotlib.gridspec
import matplotlib.pyplot as plt
import matplotlib.ticker
import scipy.special
from scipy.ndimage import gaussian_filter


def make_coords(n: int = 250) -> tuple[
    np.ndarray,  # r
    np.ndarray,  # theta
    tuple[int, int, int, int],  # axis extents
]:
    # regular cartesian dimensions
    ser = slice(-n, 1+n)
    yx = np.mgrid[ser, ser]
    y, x = yx
    extent = x.min(), x.max(), y.min(), y.max()

    # irregular polar dimensions based on cartesian dimensions
    r = np.linalg.norm(yx, axis=0)
    theta = np.arctan2(y, x)
    return r, theta, extent


def make_fake(
    r: np.ndarray, theta: np.ndarray,
    rand: np.random.Generator | None = None,
) -> np.ndarray:
    if rand is None:
        rand = np.random.default_rng()

    # generate some fake data
    p0 = (
        np.cos(3*theta) * np.sin(np.sqrt(r))
    )**6
    cleanup = (1 - np.exp(-0.01*r**2))*scipy.special.erfc((r - 200)/8)
    lumpy_1 = gaussian_filter(rand.random(r.shape), sigma=1)**2
    lumpy_2 = gaussian_filter(rand.random(r.shape), sigma=60)
    lumpy_2 -= lumpy_2.min()

    p = p0 * cleanup * lumpy_1 * lumpy_2
    p /= p.max()
    return p


def make_hist(theta: np.ndarray, p: np.ndarray) -> np.ndarray:
    """
    Not actually a histogram! This is a binned sum.

    assign a bin index to each pixel, centred on integer degrees
    (remember that Python's .astype(int) by itself rounds both
    +0.99 and -0.99 to zero, so we have to use floor first.
    cf. https://scicomp.stackexchange.com/a/40779/17869)
    """

    # 0-359, integral, where e.g. [-0.5, 0.5) maps to 0
    itheta = np.floor(np.rad2deg(theta) + 0.5).astype(int) % 360

    # binned sum with indices in itheta and values in p
    total = np.bincount(itheta.ravel(), weights=p.ravel())
    return total


def plot_image(
    fig: plt.Figure, ax: plt.Axes,
    p: np.ndarray, extent: tuple[int, int, int, int],
) -> None:
    im = ax.imshow(p, origin='lower', extent=extent)
    bar = fig.colorbar(mappable=im)

    ax.set_title('Sample dataset')
    ax.set_xlabel('x')
    ax.set_ylabel('y')
    bar.set_label('z')


def plot_hist_rect(
    ax: plt.Axes,
    hist: np.ndarray,
) -> None:
    ax.plot(hist)
    ax.xaxis.set_major_locator(matplotlib.ticker.MultipleLocator(30))
    ax.set_title('Binned sum')
    ax.set_xlabel('bin centre angle (deg)')
    ax.set_ylabel('sum')


def plot_hist_polar(
    ax: plt.PolarAxes,
    hist: np.ndarray,
) -> None:
    ax.plot(np.deg2rad(np.arange(360)), hist)
    ax.xaxis.set_major_locator(matplotlib.ticker.FixedLocator(
        np.deg2rad(np.arange(0, 360, 30)),
    ))
    ax.set_title('Binned sum')


def main() -> None:
    # repeatable simulation
    rand = np.random.default_rng(seed=4241)

    r, theta, extent = make_coords()
    p = make_fake(r=r, theta=theta, rand=rand)
    hist = make_hist(theta=theta, p=p)

    fig = plt.figure()
    grid = matplotlib.gridspec.GridSpec(figure=fig, nrows=2, ncols=2)
    plot_image(ax=fig.add_subplot(grid[0,0]), fig=fig, p=p, extent=extent)
    plot_hist_polar(ax=fig.add_subplot(grid[0,1], projection='polar'), hist=hist)
    plot_hist_rect(ax=fig.add_subplot(grid[1,:]), hist=hist)
    fig.tight_layout()
    plt.show()


if __name__ == '__main__':
    main()

plotsplots

import numpy as np
import matplotlib.gridspec
import matplotlib.pyplot as plt
import matplotlib.ticker
import scipy.special
from scipy.ndimage import gaussian_filter


def make_coords(n: int = 250) -> tuple[
    np.ndarray,  # r
    np.ndarray,  # theta
    tuple[int, int, int, int],  # axis extents
]:
    # regular cartesian dimensions
    ser = slice(-n, 1+n)
    yx = np.mgrid[ser, ser]
    y, x = yx
    extent = x.min(), x.max(), y.min(), y.max()

    # irregular polar dimensions based on cartesian dimensions
    r = np.linalg.norm(yx, axis=0)
    theta = np.arctan2(y, x)
    return r, theta, extent


def make_fake(
    r: np.ndarray, theta: np.ndarray,
    rand: np.random.Generator | None = None,
) -> np.ndarray:
    if rand is None:
        rand = np.random.default_rng()

    # generate some fake data
    p0 = (
        np.cos(3*theta) * np.sin(np.sqrt(r))
    )**6
    cleanup = (1 - np.exp(-0.01*r**2))*scipy.special.erfc((r - 200)/8)
    lumpy_1 = gaussian_filter(rand.random(r.shape), sigma=1)**2
    lumpy_2 = gaussian_filter(rand.random(r.shape), sigma=60)
    lumpy_2 -= lumpy_2.min()

    p = p0 * cleanup * lumpy_1 * lumpy_2
    p /= p.max()
    return p


def make_hist(theta: np.ndarray, p: np.ndarray) -> np.ndarray:
    """
    Not actually a histogram! This is a binned sum.

    assign a bin index to each pixel, centred on integer degrees
    (remember that Python's .astype(int) by itself rounds both
    +0.99 and -0.99 to zero, so we have to use floor first.
    cf. https://scicomp.stackexchange.com/a/40779/17869)
    """

    # 0-359, integral, where e.g. [-0.5, 0.5) maps to 0
    itheta = np.floor(np.rad2deg(theta) + 0.5).astype(int) % 360

    # binned sum with indices in itheta and values in p
    total = np.bincount(itheta.ravel(), weights=p.ravel())
    return total


def plot_image(
    fig: plt.Figure, ax: plt.Axes,
    p: np.ndarray, extent: tuple[int, int, int, int],
) -> None:
    im = ax.imshow(p, origin='lower', extent=extent)
    bar = fig.colorbar(mappable=im)

    ax.set_title('Sample dataset')
    ax.set_xlabel('x')
    ax.set_ylabel('y')
    bar.set_label('z')


def plot_hist_rect(
    ax: plt.Axes,
    hist: np.ndarray,
) -> None:
    ax.plot(hist)
    ax.xaxis.set_major_locator(matplotlib.ticker.MultipleLocator(30))
    ax.set_title('Binned sum')
    ax.set_xlabel('bin centre angle (deg)')
    ax.set_ylabel('sum')


def plot_hist_polar(
    ax: plt.PolarAxes,
    hist: np.ndarray,
) -> None:
    ax.plot(np.deg2rad(np.arange(360)), hist)
    ax.set_title('Binned sum')


def main() -> None:
    # repeatable simulation
    rand = np.random.default_rng(seed=4241)

    r, theta, extent = make_coords()
    p = make_fake(r=r, theta=theta, rand=rand)
    hist = make_hist(theta=theta, p=p)

    fig = plt.figure()
    grid = matplotlib.gridspec.GridSpec(figure=fig, nrows=2, ncols=2)
    plot_image(ax=fig.add_subplot(grid[0,0]), fig=fig, p=p, extent=extent)
    plot_hist_polar(ax=fig.add_subplot(grid[0,1], projection='polar'), hist=hist)
    plot_hist_rect(ax=fig.add_subplot(grid[1,:]), hist=hist)
    fig.tight_layout()
    plt.show()


if __name__ == '__main__':
    main()

plots

import numpy as np
import matplotlib.gridspec
import matplotlib.pyplot as plt
import matplotlib.ticker
import scipy.special
from scipy.ndimage import gaussian_filter


def make_coords(n: int = 250) -> tuple[
    np.ndarray,  # r
    np.ndarray,  # theta
    tuple[int, int, int, int],  # axis extents
]:
    # regular cartesian dimensions
    ser = slice(-n, 1+n)
    yx = np.mgrid[ser, ser]
    y, x = yx
    extent = x.min(), x.max(), y.min(), y.max()

    # irregular polar dimensions based on cartesian dimensions
    r = np.linalg.norm(yx, axis=0)
    theta = np.arctan2(y, x)
    return r, theta, extent


def make_fake(
    r: np.ndarray, theta: np.ndarray,
    rand: np.random.Generator | None = None,
) -> np.ndarray:
    if rand is None:
        rand = np.random.default_rng()

    # generate some fake data
    p0 = (
        np.cos(3*theta) * np.sin(np.sqrt(r))
    )**6
    cleanup = (1 - np.exp(-0.01*r**2))*scipy.special.erfc((r - 200)/8)
    lumpy_1 = gaussian_filter(rand.random(r.shape), sigma=1)**2
    lumpy_2 = gaussian_filter(rand.random(r.shape), sigma=60)
    lumpy_2 -= lumpy_2.min()

    p = p0 * cleanup * lumpy_1 * lumpy_2
    p /= p.max()
    return p


def make_hist(theta: np.ndarray, p: np.ndarray) -> np.ndarray:
    """
    Not actually a histogram! This is a binned sum.

    assign a bin index to each pixel, centred on integer degrees
    (remember that Python's .astype(int) by itself rounds both
    +0.99 and -0.99 to zero, so we have to use floor first.
    cf. https://scicomp.stackexchange.com/a/40779/17869)
    """

    # 0-359, integral, where e.g. [-0.5, 0.5) maps to 0
    itheta = np.floor(np.rad2deg(theta) + 0.5).astype(int) % 360

    # binned sum with indices in itheta and values in p
    total = np.bincount(itheta.ravel(), weights=p.ravel())
    return total


def plot_image(
    fig: plt.Figure, ax: plt.Axes,
    p: np.ndarray, extent: tuple[int, int, int, int],
) -> None:
    im = ax.imshow(p, origin='lower', extent=extent)
    bar = fig.colorbar(mappable=im)

    ax.set_title('Sample dataset')
    ax.set_xlabel('x')
    ax.set_ylabel('y')
    bar.set_label('z')


def plot_hist_rect(
    ax: plt.Axes,
    hist: np.ndarray,
) -> None:
    ax.plot(hist)
    ax.xaxis.set_major_locator(matplotlib.ticker.MultipleLocator(30))
    ax.set_title('Binned sum')
    ax.set_xlabel('bin centre angle (deg)')
    ax.set_ylabel('sum')


def plot_hist_polar(
    ax: plt.PolarAxes,
    hist: np.ndarray,
) -> None:
    ax.plot(np.deg2rad(np.arange(360)), hist)
    ax.xaxis.set_major_locator(matplotlib.ticker.FixedLocator(
        np.deg2rad(np.arange(0, 360, 30)),
    ))
    ax.set_title('Binned sum')


def main() -> None:
    # repeatable simulation
    rand = np.random.default_rng(seed=4241)

    r, theta, extent = make_coords()
    p = make_fake(r=r, theta=theta, rand=rand)
    hist = make_hist(theta=theta, p=p)

    fig = plt.figure()
    grid = matplotlib.gridspec.GridSpec(figure=fig, nrows=2, ncols=2)
    plot_image(ax=fig.add_subplot(grid[0,0]), fig=fig, p=p, extent=extent)
    plot_hist_polar(ax=fig.add_subplot(grid[0,1], projection='polar'), hist=hist)
    plot_hist_rect(ax=fig.add_subplot(grid[1,:]), hist=hist)
    fig.tight_layout()
    plt.show()


if __name__ == '__main__':
    main()

plots

histogram plot suggestions
Source Link
Reinderien
  • 71.2k
  • 5
  • 76
  • 257
Loading
Source Link
Reinderien
  • 71.2k
  • 5
  • 76
  • 257
Loading