FooBar
FooBar

Reputation: 16478

Projecting plane onto new coordinate system

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

Answers (2)

gboffi
gboffi

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

enter image description here

If the bands are too ugly use plt.pcolormesh(T, Y, Zt, shading='gouraud')

enter image description here

Upvotes: 1

javidcf
javidcf

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:

Original and projected plot

Upvotes: 1

Related Questions