Reputation: 16478
Say I have a grid
xGrid = np.linspace(0.1, 1, 10)
yGrid = np.linspace(5, 10, 5)
and some data on that grid:
X, Y = np.meshgrid(xGrid, yGrid, indexing='ij')
Z = X*Y + 1
I could easily now plot Z(x, y)
. Now, there is a transformation t(x, y)
:
T = X+1+Y/2
and I would like to plot Z(t(x, y), y)
instead. To do that, I need to project my Z
data onto the t(x,y)-y
plane. What'd be the best way of doing that?
Since I ultimately want to plot the data and not do any further work with it, direct methods of doing this in matplotlib
(but actually drawing onto the correct new coordinates, not just relabeling the ticks) are also accepted.
Upvotes: 1
Views: 356
Reputation: 25023
If I understand your problem you could use pcolormesh
that can be used for non regular meshes
In [8]: import numpy as np
...: import matplotlib.pyplot as plt
...: from matplotlib.collections import PatchCollection, QuadMesh
...: from matplotlib.patches import Rectangle
...:
...: np.random.seed(2018)
...: xGrid = np.linspace(0.1, 1, 10)
...: yGrid = np.linspace(5, 10, 6)
...: X, Y = np.meshgrid(xGrid, yGrid, indexing='ij')
...: Z = X*Y + 1
...: T = X+1+Y/2
...: Zt = T*Y + 1
...: plt.pcolormesh(T, Y, Zt)
...: plt.colorbar()
Out[8]: <matplotlib.colorbar.Colorbar at 0x7fda83cd4ef0>
that produces
If the bands are too ugly use plt.pcolormesh(T, Y, Zt, shading='gouraud')
Upvotes: 1
Reputation: 59691
You can use interpolation to compute the values in the projection, for example with scipy.interpolate.RectBivariateSpline
:
import numpy as np
import scipy.interpolate
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
xGrid = np.linspace(0.1, 1, 10)
yGrid = np.linspace(5, 10, 5)
X, Y = np.meshgrid(xGrid, yGrid, indexing='ij')
Z = X * Y + 1
T = X + 1 + Y / 2
# Interpolate values
interp = scipy.interpolate.RectBivariateSpline(xGrid, yGrid, Z)
Zt = interp.ev(T.ravel(), Y.ravel()).reshape(Z.shape)
# Plot
fig = plt.figure(figsize=(8, 10))
ax1 = fig.add_subplot(211, projection='3d')
ax1.set_title('Original')
ax1.plot_surface(X, Y, Z)
ax2 = fig.add_subplot(212, projection='3d')
ax2.set_title('Projected')
ax2.plot_surface(T, Y, Zt)
fig.tight_layout()
Output:
Upvotes: 1