Home > database >  pyplot 3d z axis-log plot
pyplot 3d z axis-log plot

Time:03-20

In order to create a 3d plot using plot_surface and wireframe I wrote this (looking here around)

from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
from matplotlib import rc
from matplotlib.ticker import MultipleLocator
import matplotlib.ticker as mticker
import numpy as np
from matplotlib.ticker import FormatStrFormatter

def log_tick_formatter(val, pos=None):
    return f"10$^{{{int(val)}}}$" 



data=np.genfromtxt('jpdfomegal2_90.dat')

x_len= len(np.unique(data[:, 0]))
y_len= len(np.unique(data[:, 1]))

X = data[:, 0].reshape(x_len, y_len)
Y = data[:, 1].reshape(x_len, y_len)
Z = data[:, 2].reshape(x_len, y_len)

#identify lowest non-negative Z value Zmin>0

Zmin = np.where(Z > 0, Z, np.inf).min()
Zmax = Z.max()


#and substitute zero with a slightly lower value than Zmin
Z[Z==0] = 0.9 * Zmin
#log transformation because the conversion in 3D 
#does not work well in matplotlib
Zlog = np.log10(Z)
rc('font',family='palatino')
rc('font',size=18)
fig = plt.figure(figsize=(12,8))
#ax = fig.add_subplot(projection='3d') 
ax = Axes3D(fig)
ax.set_xlim3d(0,15)
ax.set_zlim3d(np.floor(np.log10(Zmin))-1, np.ceil(np.log10(10)))
ax.zaxis.set_major_formatter(mticker.FuncFormatter(log_tick_formatter))
ax.zaxis.set_major_locator(mticker.MaxNLocator(integer=True))

rc('font',family='palatino')
rc('font',size=18)
tmp_planes = ax.zaxis._PLANES 
ax.zaxis._PLANES = ( tmp_planes[2], tmp_planes[3], 
                     tmp_planes[0], tmp_planes[1], 
                     tmp_planes[4], tmp_planes[5])

ax.set_xlabel('$\omega^2 /<\omega^2>$')
ax.xaxis.labelpad = 10
ax.yaxis.labelpad = 10
ax.set_ylabel('cos$(\omega,\lambda^2)$')

ax.zaxis.set_rotate_label(False)  # disable automatic rotation

ax.zaxis.labelpad = 10
ax.set_zlabel('')

ax.view_init(elev=17, azim=-60)

ax.grid(False)
ax.xaxis.pane.set_edgecolor('black')
ax.yaxis.pane.set_edgecolor('black')
ax.zaxis.pane.set_edgecolor('black')
ax.xaxis.pane.fill = False
ax.yaxis.pane.fill = False
ax.zaxis.pane.fill = False



ax.xaxis.set_major_locator(MultipleLocator(2))
ax.yaxis.set_major_locator(MultipleLocator(0.2))
ax.zaxis.set_major_locator(MultipleLocator(1))

#not sure this axis scaling routine is really necessary 
scale_x = 1
scale_y = 1
scale_z = 0.8
ax.get_proj = lambda: np.dot(Axes3D.get_proj(ax), np.diag([scale_x, scale_y, scale_z, 1]))
ax.contour(X, Y, np.log10(Z), 4, lw=0.1, colors="k", linestyles="--", offset=np.floor(np.log10(Zmin))-1)#-7)
surf = ax.plot_surface(X, Y, np.log10(Z), cmap="binary", lw=0.1,alpha=0.5)
ax.plot_wireframe(X, Y, np.log10(Z),linewidth=1,color='k')
ax.contour(X, Y, np.log10(Z), 4, lw=0.1, colors="k", linestyles="solid")
fig.colorbar(surf, shrink=0.5, aspect=20)

plt.tight_layout()
plt.savefig('jpdf_lambda2_90.png', bbox_inches='tight')
plt.show()

the problem is related to the "minorticks" along zaxis .. I obtain this :enter image description here

but I would have this format and ticks in the axis enter image description here

Does somebody clarify how to obtain it and as well I did not find a way to use the log scale in pyplot 3d

CodePudding user response:

There's an enter image description here

  • Related