3

I've made this 3d bar plot, but I've found a wrong overlap in some bars, as I show in the image below with green circles:enter image description here

The plot is made by:

import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d.axes3d import Axes3D
import matplotlib.colors as colors

fig = plt.figure(figsize=(10,8))
ax = fig.add_subplot(111, projection='3d')    
matrix = np.array([
[84 80 68 56 60 44 55 39 27 29]
[82 67 63 44 47 33 22 19  9  2]
[53 61 48 34  0 16  0  0  0  0]
[48 25  0  0  0  0  0  0  0  0]])

len_x, len_y = matrix.shape
_x = np.arange(len_x)
_y = np.arange(len_y)

xpos, ypos = np.meshgrid(_x, _y)
xpos = xpos.flatten('F')
ypos = ypos.flatten('F')
zpos = np.zeros_like(xpos)

dx = np.ones_like(zpos)
dy = dx.copy()
dz = matrix.flatten()

cmap=plt.cm.magma(plt.Normalize(0,100)(dz))

ax.bar3d(xpos+0.32, ypos-0.3, zpos, dx-0.6, dy-0.1, dz, zsort='max', color=cmap)

ax.set_xlabel('x')
ax.set_xticks(np.arange(len_x+1))
ax.set_xticklabels(['1000','500','100','50','0'])
ax.set_xlim(0,4)
ax.set_ylabel('y')
ax.set_yticks(np.arange(len_y+1))
ax.set_yticklabels(['0.5','1.','1.5','2.','2.5','3.','3.5','4.','4.5','5.'])
ax.set_ylim(-0.5,10)
ax.set_zlabel('z')
ax.set_zlim(0,100)
ax.view_init(ax.elev, ax.azim+100)

Is it a bug? Why some bars are badly overlapping? I'm using matplotlib version 2.1.0 and anaconda python 3.6.3

Dinei
  • 4,494
  • 4
  • 36
  • 60
Alessandro Peca
  • 873
  • 1
  • 15
  • 40

1 Answers1

1

As pointed out by @DavidG in the comments, this is an issue without an ideal solution:

My 3D plot doesn’t look right at certain viewing angles
This is probably the most commonly reported issue with mplot3d. The problem is that – from some viewing angles – a 3D object would appear in front of another object, even though it is physically behind it. This can result in plots that do not look “physically correct.”

Unfortunately, while some work is being done to reduce the occurrence of this artifact, it is currently an intractable problem, and can not be fully solved until matplotlib supports 3D graphics rendering at its core.
[Source]

However, I was able to greatly reduce this issue by playing with the viewing angle of the plots and reducing the contact areas between the bars.

For example, to change the viewing angle (the "camera position"), I used:

ax.view_init(elev=30, azim=-60) # Changes the elevation and azimuth

More details in how to set “camera position” for 3d plots using python/matplotlib?

As per the contact areas, it depends on your plot. In my case, all the bars had contact alongside the y axis, so I just reduced the dy param a little to left some gap between the bars.

Dinei
  • 4,494
  • 4
  • 36
  • 60