'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:
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
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. |


