How to plot 3D bar plot on log scale

1k views Asked by At

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.

3D Bar Plot with log scale and squished to the bottom

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()
0

There are 0 answers