'How to translate/shift gradient matrix in python plot?

Context

Suppose I have the following gradient matrix:

[[0.         0.5        1.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.        ]
 [0.         0.5        1.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.        ]
 [0.         0.33333333 0.66666667 1.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.        ]
 [0.         0.         0.33333333 0.66666667 1.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.        ]
 [0.         0.         0.33333333 0.66666667 1.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.        ]
 [0.         0.         0.         0.33333333 0.66666667 1.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.        ]
 [0.         0.         0.         0.33333333 0.66666667 1.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.        ]
 [0.         0.         0.         0.         0.33333333 0.66666667 1.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.        ]
 [0.         0.         0.         0.         0.33333333 0.66666667 1.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.        ]
 [0.         0.         0.         0.         0.         0.33333333 0.66666667 1.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.        ]
 [0.         0.         0.         0.         0.         0.25       0.5        0.75       1.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.        ]
 [0.         0.         0.         0.         0.         0.         0.33333333 0.66666667 1.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.        ]
 [0.         0.         0.         0.         0.         0.         0.25       0.5        0.75       1.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.        ]
 [0.         0.         0.         0.         0.         0.         0.         0.33333333 0.66666667 1.         0.         0.         0.         0.         0.         0.         0.         0.         0.         0.        ]
 [0.         0.         0.         0.         0.         0.         0.         0.25       0.5        0.75       1.         0.         0.         0.         0.         0.         0.         0.         0.         0.        ]
 [0.         0.         0.         0.         0.         0.         0.         0.25       0.5        0.75       1.         0.         0.         0.         0.         0.         0.         0.         0.         0.        ]
 [0.         0.         0.         0.         0.         0.         0.         0.         0.25       0.5        0.75       1.         0.         0.         0.         0.         0.         0.         0.         0.        ]
 [0.         0.         0.         0.         0.         0.         0.         0.         0.2        0.4        0.6        0.8        1.         0.         0.         0.         0.         0.         0.         0.        ]
 [0.         0.         0.         0.         0.         0.         0.         0.         0.         0.25       0.5        0.75       1.         0.         0.         0.         0.         0.         0.         0.        ]
 [0.         0.         0.         0.         0.         0.         0.         0.         0.         0.2        0.4        0.6        0.8        1.         0.         0.         0.         0.         0.         0.        ]]

Which yields the following plot:

enter image description here

MWE

That image can be created with a patch that only displays the gradient that runs accross the matrix with:

import matplotlib.pyplot as plt
from matplotlib.patches import PathPatch
from matplotlib.path import Path
from scipy.ndimage import rotate


def generate_patch_plot():
    """Creates the geometry of the logo."""
    E=(8.0, 17.32050807568877)
    F=(10.0, 17.32050807568877)
    G=(16.0, 0)
    H=(20.0, 0.0)

    fig = plt.figure()
    ax = fig.add_subplot(111, aspect="equal")
    square_patch = Path([(0, 0), (0, 20), (20, 20), (20, 0), (0, 0)])
    square_path_patch = PathPatch(square_patch, facecolor="none")
    ax.add_patch(square_path_patch)
    gradient_matrix=[[0,0.6,0],[0,0.6,0],[0,0.6,0]]
    plt.plot(E[0], E[1], "ro", label="E")
    plt.plot(F[0], F[1], "yo", label="F")
    plt.plot(G[0], G[1], "bo", label="G")
    plt.plot(H[0], H[1], "co", label="H")
    im = plt.imshow(
        gradient_matrix,  # Gradient matrix
        interpolation="bilinear",
        origin="lower",  # Something
        cmap=plt.cm.hsv,
        extent=[0, 20, 0, 20],
        # extent=extension_domain,
        # clip_path=patch, # original.
        clip_path=square_path_patch,
        clip_on=True,
    )
    # im.set_clip_path(patch) # original.
    im.set_clip_path(square_path_patch)
    plt.show()

where E,F,G,H are the top left, top right, bottom left bottom right coordinates of the patch. The patch ensures only the gradient is visible inside the patch, and that the rest of the matrix is ignored outside the patch. However, when I look at the plot that is generated, the matrix is plotted from top left at y=0 to y=15.

Question

How could one shift this matrix to be displayed from x = 4 to -24, and from y = 7 to -27?



Solution 1:[1]

The XY-problem of plotting a colour gradient patch at a certain location/offset can be realised using a patch and extend. The code below generates 3 separate patches with different colour gradient matrices and different colour maps:

Code

# -*- coding: utf-8 -*-
"""Generates three separate patches with a colour gradient that co-exist in the
same geometry."""


import matplotlib.pyplot as plt
from matplotlib.patches import PathPatch
from matplotlib.path import Path

from src.create_gradient import re_order_coordinates


def generate_patch_plot():
    """Creates the geometry of the logo."""
    E = (8.0, 17.32050807568877)
    F = (10.0, 17.32050807568877)
    G = (16.0, 0)
    H = (20.0, 0.0)

    fig = plt.figure()
    ax = fig.add_subplot(111, aspect="equal")

    # Create gradient matrix for that segment.
    gradient_matrix_top_right = [[0, 0, 0], [0, 0.6, 0], [0, 0.6, 0]]
    gradient_matrix_mid = [[0, 0, 0], [1, 1, 1], [0, 0, 0]]
    gradient_matrix_bottom_left = [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
    # First row is on bottom, last row on top.

    # Plot the patch coordinates.
    # TODO: shift left and down for manual verification.
    plt.plot(E[0], E[1], "ro", label="E")
    plt.plot(F[0], F[1], "yo", label="F")
    plt.plot(G[0], G[1], "bo", label="G")
    plt.plot(H[0], H[1], "co", label="H")

    extent_one = [0, 1, 0, 1]
    extent_two = [1, 2, 1, 2]
    extent_three = [-1, -2, -1, -2]

    # Create the first image
    plt.imshow(
        gradient_matrix_top_right,  # Gradient matrix
        interpolation="bilinear",
        origin="lower",  # Something
        cmap=plt.cm.hsv,
        extent=extent_one,
        # extent=extension_domain,
        # clip_path=patch, # original.
        clip_path=add_first_patch(ax),
        clip_on=True,
    )

    # Create the second
    plt.imshow(
        gradient_matrix_mid,  # Gradient matrix
        interpolation="bilinear",
        origin="lower",  # Something
        cmap=plt.cm.summer_r,
        extent=extent_two,
        # extent=extension_domain,
        # clip_path=patch, # original.
        clip_path=add_second_patch(ax),
        clip_on=True,
    )

    # Create the bottom left image
    plt.imshow(
        gradient_matrix_bottom_left,  # Gradient matrix
        interpolation="bilinear",
        origin="lower",  # Something
        cmap=plt.cm.summer_r,
        extent=extent_three,
        # extent=extension_domain,
        # clip_path=patch, # original.
        clip_path=add_third_patch(ax),
        clip_on=True,
    )

    # im.set_clip_path(patch) # original.
    # im.set_clip_path(square_path_patch)
    ax.set_xlim((-2, 2))
    ax.set_ylim((-2, 2))
    plt.show()


def create_4_coord_patch(top_left, top_right, bottom_left, bottom_right):
    """Generate a patch that describes the visible part of the gradient
    matrix."""
    top_left, top_right, bottom_left, bottom_right = re_order_coordinates(
        top_left, top_right, bottom_left, bottom_right
    )
    square_patch = Path(
        [top_left, top_right, bottom_right, bottom_left, top_left]
    )
    print(square_patch)
    square_path_patch = PathPatch(square_patch, facecolor="none")
    return square_path_patch


def create_square_patch(top_left, top_right, bottom_left, bottom_right):
    """Generate a patch that describes the visible part of the gradient
    matrix."""
    top_left, top_right, bottom_left, bottom_right = re_order_coordinates(
        top_left, top_right, bottom_left, bottom_right
    )
    bottom_left = (0, 0)
    top_left = (0, top_left[1])
    top_right = (400, 20)

    square_patch = Path(
        [top_left, top_right, bottom_right, bottom_left, top_left]
    )
    print(square_patch)
    square_path_patch = PathPatch(square_patch, facecolor="none")
    return square_path_patch


def add_first_patch(ax):
    """Adds a patch to the top right of the plot."""
    # First patch.
    top_left = (0, 1)
    top_right = (1, 1)
    bottom_left = (0, 0)
    bottom_right = (1, 0)
    square_path_patch_one = create_4_coord_patch(
        top_left, top_right, bottom_left, bottom_right
    )
    ax.add_patch(square_path_patch_one)
    return square_path_patch_one


def add_second_patch(ax):
    """Adds a patch to the top right of the origin of the plot."""
    # Second patch.
    top_left = (1, 2)
    top_right = (2, 2)
    bottom_left = (1, 1)
    bottom_right = (2, 1)
    square_path_patch_two = create_4_coord_patch(
        top_left, top_right, bottom_left, bottom_right
    )
    ax.add_patch(square_path_patch_two)
    return square_path_patch_two


def add_third_patch(ax):
    """Adds a patch to the bottom left of the origin of the plot."""
    # Third patch.
    top_left = (-2, -1)
    top_right = (-1, -1)
    bottom_left = (-2, -2)
    bottom_right = (-1, -2)
    square_path_patch_three = create_4_coord_patch(
        top_left, top_right, bottom_left, bottom_right
    )
    ax.add_patch(square_path_patch_three)
    return square_path_patch_three

Output

enter image description here

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 a.t.