2

Multiple Histogram Plot

The default 3D grid in matplotlib appears below z=0. This makes my reference lines (red) and histograms appear to be slightly off or hovering above the grid. I want them to appear to be attached to the grid.

import matplotlib.pyplot as plt
import numpy as np
from pathlib import Path
from matplotlib import cm
from scipy.stats import norm

open_file = Path('my_data_file.csv')
savefn   = Path('my_save_file.png')
nbins = 8
lsl   = 1.03
usl   = 1.05
data = np.zeros((30,8))


with open(open_file) as file:
    for x,line in enumerate(file):
        items = line.split(',')
        for y,item in enumerate(items):
            data[x,y] = float(item)           


fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

for z in range(data.shape[1]):#loop through the data
    ys = data[:,z]
    hist, bins = np.histogram(ys, bins=nbins)
    mu, std = norm.fit(ys) #get the mean and std
    xs = (bins[:-1] + bins[1:])/2
    x = np.linspace(min(xs), max(xs), 3*len(xs))#upsample the bins
    p = norm.pdf(x,mu,std)#fit the data to a normal pdf
    p = 3*p/sum(p) #normalize fits
    y = np.ones(len(p))*(z+1)
    ax.bar(xs, hist/sum(hist), zs=z+1, zdir='y', color=cm.Set1(z), ec='k', alpha=0.5,width=(xs[1]-xs[0]))#plot the histogram
    ax.plot(x,y,p,color=cm.Set1(z))#plot the fit


ax.plot((1.03,1.03),(1,8),0,color='r')#plot the lower spec limit
ax.plot([1.05,1.05],[1,8],0,color='r')#plot the upper spec limit

ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
plt.xlim(lsl-(lsl/1000),usl+(lsl/1000))
plt.ylim(1,8)
ax.set_zlim([0,0.4])

plt.show()
fig.savefig(fname= savefn,format="png",dpi=600)   
Peter O.
  • 32,158
  • 14
  • 82
  • 96
brummel
  • 41
  • 4
  • Just try changing the viewing angle. – Jay Patel Mar 09 '21 at 04:31
  • Changing the viewing angle does not affect the position of the gridlines relative to z=0. Unless I'm looking almost straight downward, the histograms and reference lines appear to be hovering. – brummel Mar 10 '21 at 19:58

1 Answers1

0

The only hacky way that worked for me in a similar situation was to mess around with the beginning of the range given to:

    ax.set_zlim([0,0.4])

So perhaps in your case, a starting value of 0.01 would help.