I was trying to make a 3D visualization of the joint probability mass function with the following code: import math import numpy as np import matplotlib.pyplot as plt def f(x, y): if(1 <= x + y and x + y <= 4): return (math.comb(3, x) * math.comb(2, y) * math.comb(3, 4 - x - y)) / math.comb(8, 4) else: return 0.0 x_domain = np.array([0, 1, 2, 3]) y_domain = np.array([0, 1, 2]) X, Y = np.meshgrid(x_domain, y_domain) X = np.ravel(X) Y = np.ravel(Y) Z = np.zeros_like(X, dtype=float) for i in range(len(X)): Z[i] = f(X[i], Y[i]) fig = plt.figure(figsize=(8, 4)) ax = fig.add_subplot(1, 1, 1, projection="3d") ax.scatter(X, Y, Z) # plots the induvidual points for i in range(len(X)): # draws lines from xy plane up (x,y,z) ax.plot([X[i], X[i]], [Y[i], Y[i]], [0, Z[i]], color="r") ax.set_xticks(x_domain) ax.set_yticks(y_domain) plt.show()  Which gave the following result:  As you can see, the stems of lines from the xy-plane do not align with the integer coordinates. I have searched through the matplotlib documentation and cant find the cause for this (unless I have overlooked something). Does anyone know how to fix the alignment issue? EDIT It seems stack overflow could not render the mathjax equation, so I removed it.
Actually, they DO align with the integer grid, as you will see by rotating your plot a bit. It's just that the z axis doesn't naturally start from 0, which is where the end of your whatever-they-are are. Add the line ax.set_zlim( 0.0, 0.25 )  just before plt.show() and you will be good to go. 