My data needs to be plotted on a log scale in order to be able to see some of my really small values, however, I can't seem to find any way to do it on a 3D bar plot.
Supposedly in a 2D bar plot you can adjust the scales by simply including ax.set_zscale('log')
in your code, but in a 3D plot, that just adjusts the labels but doesn't apply it to the data.
Also in the figure below, you will be able to see that the labels are all squished to the bottom of the z-axis.
The only help I have found was here: Plotting mplot3d / axes3D xyz surface plot with log scale?
Here the answer says I will need to change my numpy array, and I cannot not figure out how to do that. I tried using numpy.log_space
on my delta z data but that made everything way worse.
Here is a reproduceable dataframe, one similar to the one I got my data from, and all 'my' code (a lot of it is copied from another stackoverflow page)
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
df = pd.DataFrame({'Ionization #': [4.341, 5.139, 5.212, 5.986, 6.108],
'Name': ['Potassium', 'Sodium', 'Barium', 'Aluminium', 'Thalium'],
'Nebulizer 1': [27.0923, 23.1222, 0.1975, 5.0517, 0.1484],
'Nebulizer 2': [18.5475, 21.1542, 0.0721, 3.9544, 0.3125],
'Nebulizer 3': [25.2555, 20.5644, 0.1665, 0.3125, 0.0154]})
# bar width
dy, dx = 0.5, 0.5
# setup the figure and axes
fig = plt.figure(figsize=(8, 8))
ax = Axes3D(fig)
#ax = fig.add_subplot(121, projection='3d')
# set position for bars
ypos = np.arange(df.shape[0])
xpos = np.arange(3)
#set the ticks in the middle of the bars
ax.set_xticks(xpos + dx/2)
ax.set_yticks(ypos + dy/2)
# create mesh grid
xpos, ypos = np.meshgrid(xpos, ypos)
xpos = xpos.flatten()
ypos = ypos.flatten()
# the bars start from 0k
zpos=np.zeros(15, dtype=int).flatten()
MDL_DF = df[['Nebulizer 1', 'Nebulizer 2', 'Nebulizer 3']]
dz = MDL_DF.values.ravel()
# dz = np.logspace(0.01547368, 26.52218327, 96)
# print(dz)
ax.bar3d(xpos, ypos, zpos, dx, dy, dz)
ax.w_xaxis.set_ticklabels(MDL_DF.columns, fontsize=8)
ax.w_yaxis.set_ticklabels(df['Name'], fontsize=6)
# z log scale
ax.set_zscale('log')
#Axis Labels
ax.set_xlabel('Nebulizer')
ax.set_ylabel('Element')
ax.set_zlabel('MDL')
plt.show()