.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/plot_02_direction_resolution.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_auto_examples_plot_02_direction_resolution.py: Asymmetric Directional Resolution ================================= One of the features of the UDCT is that it is able to specify different resolutions for different quadrants of the Fourier space. This allows one to target finer details with more division, and coarser scales with fewer. .. GENERATED FROM PYTHON SOURCE LINES 9-25 .. code-block:: Python # sphinx_gallery_thumbnail_number = 2 from __future__ import annotations import matplotlib.pyplot as plt import numpy as np from matplotlib import ticker from matplotlib.cm import ScalarMappable from matplotlib.colorbar import ColorbarBase from matplotlib.colors import Normalize, to_rgba from matplotlib.gridspec import GridSpec from numpy.fft import fftfreq, fftshift from curvelets.numpy import UDCT .. GENERATED FROM PYTHON SOURCE LINES 26-28 Symmetric and Asymmetric UDCTs ############################## .. GENERATED FROM PYTHON SOURCE LINES 28-33 .. code-block:: Python x = np.zeros((300, 200)) C_sym = UDCT(x.shape, num_scales=3, wedges_per_direction=3) C_asymh = UDCT(shape=x.shape, angular_wedges_config=np.array([[3, 6], [6, 12]])) C_asymv = UDCT(shape=x.shape, angular_wedges_config=np.array([[6, 3], [12, 6]])) .. GENERATED FROM PYTHON SOURCE LINES 34-39 Plotting Functions ################## Created Colored image from Windows ---------------------------------- .. GENERATED FROM PYTHON SOURCE LINES 39-97 .. code-block:: Python def color_windows( C, thresh=0.8, cmaps_dir: tuple[str, str] = ("Wistia", "winter_r"), color_low: str | tuple[int, ...] = "w", color_bg: str | tuple[int, ...] = (0, 0, 0, 1), ): wins = C.windows def create_mask( wedge: tuple[np.ndarray, np.ndarray], ) -> np.ndarray: wedge_dense = C._from_sparse(wedge) wedge_dense = fftshift(wedge_dense) return wedge_dense >= thresh # type: ignore[no-any-return] def assign_rgba_to_mask( mask_index: np.ndarray, mask_target: np.ndarray, rgb_a: tuple[int, ...] ) -> None: mask_target[..., 0][mask_index] = rgb_a[0] mask_target[..., 1][mask_index] = rgb_a[1] mask_target[..., 2][mask_index] = rgb_a[2] if len(rgb_a) > 3: mask_target[..., 3][mask_index] = rgb_a[3] # Scale 0 wedge mask = create_mask(wins[0][0][0]) # Full colored mask rgb_a = to_rgba(color_bg) if isinstance(color_bg, str) else color_bg mask_rgba = np.zeros((*mask.shape, 4), dtype=float) assign_rgba_to_mask(Ellipsis, mask_rgba, rgb_a) # type: ignore[arg-type] # Set scale 0 wedges in full mask rgb_a = to_rgba(color_low) if isinstance(color_low, str) else color_low assign_rgba_to_mask(mask, mask_rgba, rgb_a) # Rest of scales for iscale in range(1, len(wins)): ndir = len(wins[iscale]) assert ndir == 2 for idir in range(ndir): nwedges = len(wins[iscale][idir]) cmap = plt.get_cmap(cmaps_dir[idir]) norm = Normalize(vmin=0, vmax=nwedges - 1) scalarMap = ScalarMappable(norm=norm, cmap=cmap) for iwedge in range(nwedges): mask = create_mask(wins[iscale][idir][iwedge]) mask += np.flip(mask, axis=(0, 1)) rgb_a = scalarMap.to_rgba(iwedge) assign_rgba_to_mask(mask, mask_rgba, rgb_a) return mask_rgba .. GENERATED FROM PYTHON SOURCE LINES 98-100 Created Disk from Windows ------------------------- .. GENERATED FROM PYTHON SOURCE LINES 100-176 .. code-block:: Python def plot_disk( C, ax, cmaps_dir: tuple[str, str] = ("Wistia", "winter_r"), color_low: str | tuple[int, ...] = "w", color_bg: str | tuple[int, ...] = (0, 0, 0, 1), ): deg_360 = 2 * np.pi deg_135 = np.pi * 3 / 4 deg_n45 = -np.pi / 4 deg_90 = np.pi / 2 ax.yaxis.set_visible(False) ax.grid(False) ax.set_facecolor(color_bg) nscales = len(C.windows) wedge_height = 1 / (nscales - 1) ax.bar(x=0, height=wedge_height, width=deg_360, bottom=0, color=color_low) for iscale, s in enumerate(C.windows[1:], start=1): ndir = len(s) assert ndir == 2 for idir, d in enumerate(s): nwedges = len(d) angles_per_wedge = deg_90 / nwedges pm = (-1) ** idir # CCW for idir == 0, CC otherwise cmap = plt.get_cmap(cmaps_dir[idir]) norm = Normalize(vmin=0, vmax=nwedges - 1) scalarMap = ScalarMappable(norm=norm, cmap=cmap) for iwedge in range(nwedges): color = scalarMap.to_rgba(iwedge) for offset in [deg_135, deg_n45]: # top-left, bottom-right wedge_x = offset + pm * angles_per_wedge * (0.5 + iwedge) wedge_width = angles_per_wedge wedge_bottom = iscale * wedge_height ax.bar( x=wedge_x, height=wedge_height, width=wedge_width, bottom=wedge_bottom, color=color, ) linewidth = 0.05 * wedge_height linecolor = color_bg # Plot after so they are on top for iscale, s in enumerate(C.windows): # Scale separators ax.bar( x=0, height=linewidth, width=deg_360, bottom=(iscale + 1 - linewidth / 2) / (nscales - 1), color=linecolor, ) if iscale == 0: continue # Wedge separators for idir, d in enumerate(s): nwedges = len(d) angles_per_wedge = deg_90 / nwedges pm = (-1) ** idir for iwedge in range(nwedges): for offset in [deg_135, deg_n45]: # top-left, bottom-right wedge_x = offset + pm * angles_per_wedge * (0.5 + iwedge) wedge_width = angles_per_wedge wedge_bottom = iscale * wedge_height ax.bar( x=wedge_x - wedge_width / 2, height=wedge_height, width=linewidth, bottom=wedge_bottom, color=linecolor, ) .. GENERATED FROM PYTHON SOURCE LINES 177-179 Create Colorbars for Directions ------------------------------- .. GENERATED FROM PYTHON SOURCE LINES 179-199 .. code-block:: Python def plot_colorbars( windows, axs, cmaps: tuple[str, str] = ("Wistia", "winter_r"), orientation: str = "horizontal", ): for idir, cax in enumerate(axs): max_wedges = max(len(d) for s in windows for d in s) cmap = plt.get_cmap(cmaps[idir], max_wedges) ColorbarBase(cax, cmap=cmap, orientation=orientation) xyaxis = cax.yaxis if orientation == "vertical" else cax.xaxis xyaxis.set_major_locator(ticker.MultipleLocator(1)) xyaxis.set_major_formatter( ticker.FuncFormatter( lambda x, _: "Low" if int(round(2 * x)) == 0 else "High" ) ) cax.set_title(f"Dir {idir}") .. GENERATED FROM PYTHON SOURCE LINES 200-202 Plot Support of UDCTs in the Fourier Domain ########################################### .. GENERATED FROM PYTHON SOURCE LINES 202-211 .. code-block:: Python cmaps = ("Wistia", "winter_r") color_low = "xkcd:salmon" color_bg = "w" nx, ny = x.shape kx = fftshift(fftfreq(nx)) ky = fftshift(fftfreq(ny)) C: UDCT .. GENERATED FROM PYTHON SOURCE LINES 212-214 Symmetric --------- .. GENERATED FROM PYTHON SOURCE LINES 214-239 .. code-block:: Python title = "Symmetric" C = C_sym colored_wins = color_windows(C, cmaps_dir=cmaps, color_low=color_low, color_bg=color_bg) fig = plt.figure(layout="constrained") fig.suptitle(title) gs = GridSpec(3, 2, figure=fig, height_ratios=[8, 1, 1]) ax1 = fig.add_subplot(gs[0, 0]) ax2 = fig.add_subplot(gs[0, 1], projection="polar") ax3 = fig.add_subplot(gs[1, :]) ax4 = fig.add_subplot(gs[2, :]) ax1.imshow( colored_wins.swapaxes(0, 1), extent=[kx[0], kx[-1], ky[-1], ky[0]], aspect=ny / nx ) ax1.xaxis.set_minor_locator(ticker.MultipleLocator(0.1)) ax1.yaxis.set_minor_locator(ticker.MultipleLocator(0.1)) ax1.set( xlim=[kx[0], -kx[0]], ylim=[-ky[0], ky[0]], xlabel="Normalized $k_x$", ylabel="Normalized $k_y$", ) plot_colorbars(C.windows, [ax3, ax4], cmaps=cmaps) plot_disk(C, ax2, cmaps_dir=cmaps, color_low=color_low, color_bg=color_bg) .. image-sg:: /auto_examples/images/sphx_glr_plot_02_direction_resolution_001.png :alt: Symmetric, Dir 0, Dir 1 :srcset: /auto_examples/images/sphx_glr_plot_02_direction_resolution_001.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 240-242 Asymmetric: Finer horizontally ------------------------------ .. GENERATED FROM PYTHON SOURCE LINES 242-265 .. code-block:: Python title = "Asymmetric: Finer horizontally" C = C_asymh colored_wins = color_windows(C, cmaps_dir=cmaps, color_low=color_low, color_bg=color_bg) fig = plt.figure(layout="constrained") fig.suptitle(title) gs = GridSpec(3, 2, figure=fig, height_ratios=[8, 1, 1]) ax1 = fig.add_subplot(gs[0, 0]) ax2 = fig.add_subplot(gs[0, 1], projection="polar") ax3 = fig.add_subplot(gs[1, :]) ax4 = fig.add_subplot(gs[2, :]) ax1.imshow(colored_wins.swapaxes(0, 1), extent=[kx[0], kx[-1], ky[-1], ky[0]]) ax1.xaxis.set_minor_locator(ticker.MultipleLocator(0.1)) ax1.yaxis.set_minor_locator(ticker.MultipleLocator(0.1)) ax1.set( xlim=[kx[0], -kx[0]], ylim=[-ky[0], ky[0]], xlabel="Normalized $k_x$", ylabel="Normalized $k_y$", ) plot_colorbars(C.windows, [ax3, ax4], cmaps=cmaps) plot_disk(C, ax2, cmaps_dir=cmaps, color_low=color_low, color_bg=color_bg) .. image-sg:: /auto_examples/images/sphx_glr_plot_02_direction_resolution_002.png :alt: Asymmetric: Finer horizontally, Dir 0, Dir 1 :srcset: /auto_examples/images/sphx_glr_plot_02_direction_resolution_002.png :class: sphx-glr-single-img .. GENERATED FROM PYTHON SOURCE LINES 266-268 Asymmetric: Finer vertically ---------------------------- .. GENERATED FROM PYTHON SOURCE LINES 268-290 .. code-block:: Python title = "Asymmetric: Finer vertically" C = C_asymv colored_wins = color_windows(C, cmaps_dir=cmaps, color_low=color_low, color_bg=color_bg) fig = plt.figure(layout="constrained") fig.suptitle(title) gs = GridSpec(3, 2, figure=fig, height_ratios=[8, 1, 1]) ax1 = fig.add_subplot(gs[0, 0]) ax2 = fig.add_subplot(gs[0, 1], projection="polar") ax3 = fig.add_subplot(gs[1, :]) ax4 = fig.add_subplot(gs[2, :]) ax1.imshow(colored_wins.swapaxes(0, 1), extent=[kx[0], kx[-1], ky[-1], ky[0]]) ax1.xaxis.set_minor_locator(ticker.MultipleLocator(0.1)) ax1.yaxis.set_minor_locator(ticker.MultipleLocator(0.1)) ax1.set( xlim=[kx[0], -kx[0]], ylim=[-ky[0], ky[0]], xlabel="Normalized $k_x$", ylabel="Normalized $k_y$", ) plot_colorbars(C.windows, [ax3, ax4], cmaps=cmaps) plot_disk(C, ax2, cmaps_dir=cmaps, color_low=color_low, color_bg=color_bg) .. image-sg:: /auto_examples/images/sphx_glr_plot_02_direction_resolution_003.png :alt: Asymmetric: Finer vertically, Dir 0, Dir 1 :srcset: /auto_examples/images/sphx_glr_plot_02_direction_resolution_003.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-timing **Total running time of the script:** (0 minutes 1.355 seconds) .. _sphx_glr_download_auto_examples_plot_02_direction_resolution.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: plot_02_direction_resolution.ipynb ` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: plot_02_direction_resolution.py ` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: plot_02_direction_resolution.zip ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_