gline gline - 1 year ago 151
Python Question

Python - 3D Plotting, horizontal lines missing and incorrect gradients showing

I am new to 3D surface plots and I am trying to make a 3D plot of temperature as a function of distance and time using the following:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm

t = np.arange(0,60,1)
z = np.arange(5,85,5)

ax = fig.gca(projection='3d')
X, Y = np.meshgrid(z, t)
surface=ax.plot_surface(X,Y,T1, linewidth=1,cmap=cm.coolwarm, antialiased=False)
fig.colorbar(surface, shrink=0.5, aspect=5)
ax.view_init(ax.elev, ax.azim+90)
ax.set_title("Temperature Distribution 1")
ax.set_xlabel('z (cm)')
ax.set_ylabel('Time (min)')
ax.set_zlabel('Temperature ($^\circ$C)')
ax.set_xticks(np.arange(0,80, 15))

T1 is 2D data. This produces the following:

3D Surface Plot of Temperature

There is only 1 horizontal line showing at around 60cm, however I would like a horiztonal line every 5cm (data was taken along every 5cm). It seems there is only 2 sections to the plot along the distance axis. The colour gradients are showing in large blocks instead of showing as a function of temperature all along the length.

e.g. for time between 50-60mins from distance 0~40cm, the temperature goes from ~180 to ~20 degrees, but the colour of that block is dark red all the way along it, instead it should start as dark red and reduce down to blue. How do I get the temperature to show the correct gradient along the whole length axis.

Also the temperature legend is in %, instead of the temperature values in degrees, how do I fix this?

Answer Source

Looking at the documentation of surface we find

The rstride and cstride kwargs set the stride used to sample the input data to generate the graph. If 1k by 1k arrays are passed in, the default values for the strides will result in a 100x100 grid being plotted. Defaults to 10.

Thus, using

surface=ax.plot_surface(X,Y,T1, rstride=8, cstride=8)

you get

enter image description here

While using

surface=ax.plot_surface(X,Y,T1, rstride=5, cstride=1)

you get

enter image description here

This is an example how to create reproducible data for this case:

t = np.arange(0,60,1)
z = z=np.arange(5,85,5)
f = lambda z, t, z0, t0, sz, st: 180.*np.exp(-(z-z0)**2/sz**2 -(t-t0)**2/st**2)
X, Y = np.meshgrid(z, t)
T1 =f(X,Y,-20.,56, 40.,30.)
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download