# Best way to plot a 4 dimensional meshgrid

I have $4$ variables $X$, $Y$, $Z$ and $C$, and I want to plot these on a graph. Usually I would just plot the surface $X$, $Y$, $Z$ and then use color to represent the $4$th dimension, as shown bellow:

However, my $X$, $Y$, and $Z$ co-ordinates make up a $3$-dimensional meshgrid, so when I do the $4$ dimensional plot it is hard to see what is going on, as shown below:

$X$, $Y$ and $Z$ represent spatial dimensions and $C$ represents a value that depends on its place its $3$-dimensional space. I need $X$, $Y$, and $Z$ to be shown in all places because these are the independent variables. In this simplified version of my function, $C=X+Y+Z$. I want to be able to pick any $3$ numbers for $X$, $Y$, and $Z$, and then look at my graph, and be able to get a good idea of what $C$ is. You can sort of do this with this current graph but it is hard to use.

What I want to know is: Is there a better way to plot this information? For example, is there a different co-ordinate system I could use that would be better? Or is there a way I could represent the 3 spatial dimensions so they look like a curved surface, but still include every point?

To reiterate that last question: Is there a way to represent every point in $3$ dimensions within $0 \leq X,Y,Z \leq 10$, all on one surface?

Thanks!

• And to think that I already had trouble with a $3$-dimensional plot... (which I solved with a $2$-dimensional plot with colors). But seriously, I don't think there's a simple way to do what you want.
– TMM
Commented Mar 7, 2014 at 20:10
• If you are not restricted to static images, you could make a dynamic plot that you can move around, to see depth in your image. But if you want to put it in a paper or something, that wouldn't work.
– TMM
Commented Mar 7, 2014 at 20:12
• (You might also want to try mathematica.stackexchange.com if you happen to be making such plots in Mathematica. Maybe they have some good suggestions.)
– TMM
Commented Mar 7, 2014 at 20:13
• I'm not restricted to static images, the graphs shown can be moved around, however even with this, it is still hard (but not impossible) to get a good estimate of C just by looking at the x, y and z position. Commented Mar 7, 2014 at 20:14
• I suppose it is fine to post it on mathematica.se.com as well. Perhaps you could slightly rephrase it to emphasize that (on that website at least) you are looking for visualization methods in Mathematica. By the way, some useful links: Visualizing 4D functions and 3D heatmaps.
– TMM
Commented Mar 7, 2014 at 20:21

Great question OP! I just wanted to add my contribution here. It might be too late, however, I think it is worthwhile to post anyway.

I created a program for this a while back for a multivariable calculus course I was teaching and figured I would include it here.

My approach is to use a scatterplot, but I made some changes to really make the graphics pop.

Specifically, I included a function to remove a portion of the Alpha channel range from the colormap to make portions of the range transparent. This is controlled by the function f_AlphaControl in the code below.

The function I used in the demo is the function $$f(x,y,z)=xyz e^{-(x^2+y^2+z^2)}$$

It has 4 local max and 4 local min, all of which are visualized in the plots below. I think the results speak for themselves so please take a look at them and let me know what you think 😃.

2700 points:

1000000 points:

This code allows for creation of isovolume renders that rival Mayavi and/or OpenGL but without all of the effort. I have similar routines coded up in Mayavi, however, since OP just asked about matplotlib, I wanted to show how powerful it can be.

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm

from matplotlib.colors import ListedColormap

## The following code creates the figure plotting function
def MakePlot(xx,yy,zz,ww,cmapO=cm.jet):
##Create Custom Colormap with Alpha varying depending on the functions behavior.
## This produces very nice isovolume plots similar to Mayavi and OpenCV

##Preallocate new colormap
my_cmapN=cmapO(np.arange(cmapO.N))

#set Alpha of new colormap to be small in the middle of the colormap range using a bump function
# this can be changed to emphasize different areas of the range that are of interest.
nA=cmapO.N
xA=np.linspace(-1,1,nA)
epsilon=5 #Width of range to exclude from alpha channel
x_0=0#Center of range to exclude from alpha channel

def f_AlphaControl(x):
u=(x-x_0)/epsilon
return 1-np.exp(-u**2/(1-u**2))*(np.abs(u)<1.)

yA=f_AlphaControl(xA)
plt.plot(xA,f_AlphaControl(xA))
plt.xlim([-1,1])
plt.ylim([0,1])

my_cmapN[:,-1]=yA

fig = plt.figure(dpi=200)

# Create new colormap
my_cmap = ListedColormap(my_cmapN)

plt.style.use('dark_background')
fig = plt.figure(dpi=200)
points=ax.scatter(xx,yy,zz,c=ww,cmap=my_cmap)
cbar=fig.colorbar(points)
# cbar.solids.set_rasterized(True)

cbar.set_alpha(1)
cbar.draw_all()

## Make Title for plot
ax.set_title(r'Plot of $$f:\mathbb{R}^3\rightarrow \mathbb{R}$$'+'\n'+r'$$w=f(x,y,z)$$')

##Plot x, y, and z axis useful for visual referencing when viewing the plot
eps=.3
tt=np.linspace(-(1+eps)*L,(1+eps)*L,2)
ax.plot(tt,0*tt,0*tt,c='magenta',linewidth=2);
ax.plot(0*tt,tt,0*tt,c='magenta',linewidth=2);
ax.plot(0*tt,0*tt,tt,c='magenta',linewidth=2)

## Set viewing angle
xang=-76;pang=12;
ax.view_init(pang, xang)

# Set axis limits
ax.set_xlim([-(1+eps)*L,(1+eps)*L]);ax.set_ylim([-(1+eps)*L,(1+eps)*L]);ax.set_zlim([-(1+eps)*L,(1+eps)*L]);

#Set axis labels
ax.set_xlabel('$$x$$');ax.set_ylabel('$$y$$');ax.set_zlabel('$$z$$')
plt.savefig("ScatterPlotVaryingAlpha.png",dpi=200)

if __name__ == "__main__":

#Set Plot Grid

L=1.5
x_C=0.0;y_C=0.0;z_C=0.0;
# Set XYZ Plotting Grid
a1=x_C-L;b1=x_C+L;
a2=y_C-L;b2=y_C+L;
a3=z_C-L;b3=z_C+L;

n=100;
NT=n**3

##The following if statement determines whether you want to use a random grid R=1
## or a uniform grid R=0

grid_flag=1

if grid_flag==1:
## Random Grid
xx=np.random.uniform(a1,b1,NT);
yy=np.random.uniform(a2,b2,NT);
zz=np.random.uniform(a3,b3,NT)
else:
## Even Grid
x = np.linspace(a1,b1,n);
y = np.linspace(a2,b2,n);
z = np.linspace(a3,b3,n);

X, Y, Z = np.meshgrid(x, y, z, indexing='ij', sparse=False)

xx=X.reshape(X.size);yy=Y.reshape(Y.size);zz=Z.reshape(Z.size);

## The following code defines the function of 3 variables that we wish to visualize
## This can be replaced with the flattened data array that you wish to plot

def f(x,y,z):
return x*y*z*np.exp(-(x**2+y**2+z**2))

ww=f(xx,yy,zz)
ww[np.isinf(ww)]=np.nan

MakePlot(xx,yy,zz,ww)
plt.show()



from matplotlib.colors import ListedColormap

• I originally asked this question as I wanted to include an image like this in my university dissertation 8 years ago, so it's a little late, but it's certainly a worthwhile post! :P I really like the idea of making portions of the range transparent. I will definitely consider this if I need to make an image like this in the future. It will be great for things like radiation fields around an object. Commented Nov 17, 2021 at 14:46

You could try plotting the 3rd dimension with color and the 4th dimension with the saturation/brightness of that color?

• (Or more like tints and shades of that color)
– Fred
Commented Jun 7, 2014 at 18:48