3

I'm plotting 3d lines and points in matplotlib. On the output, there is always on top the last data plotted and not the "closer" data in the 3d projection. I would like to achieve a view that considers the perspective.

Here's a minimal code, In this case the red line is always on top of the blue line:

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

fig = plt.figure(figsize = [8, 14])
ax1 = fig.add_subplot(211, projection='3d')
ax2 = fig.add_subplot(212, projection='3d')

x = np.linspace(-1, 1, 100)
y = np.linspace(-1, 1, 100)

ax1.plot(x, y, 0, 'b', lw = 3)
ax1.plot(x, y, 1, 'r', lw = 3)

ax2.plot(x, y, 0, 'b', lw = 3)
ax2.plot(x, y, 1, 'r', lw = 3)

ax1.view_init(90, 0)
ax2.view_init(-90, 0)

plt.show()
heracho
  • 590
  • 1
  • 9
  • 28
  • You could experiment with adding `zorder` to each line, e.g. `zorder=0` for the first and `zorder=1` for he second plot. – Martin Evans Sep 11 '17 at 17:03
  • @MartinEvans, That experiment is equivalent to change the order in which the lines are plotted. Instead of always red on top of blue we get the opposite. The idea is that the view considers the proximity of the lines to the viewer. – heracho Sep 11 '17 at 17:34
  • 3
    Again the usual [My 3D plot doesn’t look right at certain viewing angles](https://matplotlib.org/mpl_toolkits/mplot3d/faq.html#my-3d-plot-doesn-t-look-right-at-certain-viewing-angles)-problem. – ImportanceOfBeingErnest Sep 11 '17 at 18:42
  • That is exactly the issue that I have @ImportanceOfBeingErnest. So, there's no solution available other than use another plotting tool? – heracho Sep 11 '17 at 20:46
  • Solution to what problem? I think you already solved the actual problem of the one line being in front of the other by reversing the order of plotting? In that sense you may always be able to tinker something which will solve an actual problem, like e.g. [this one](https://stackoverflow.com/questions/41699494/how-to-obscure-a-line-behind-a-surface-plot-in-matplotlib). But there is no general solution (which is why the FAQ was written I suppose). – ImportanceOfBeingErnest Sep 11 '17 at 20:54
  • That solution (zorder or order of plotting) is good for the minimal problem, but not enough for my real task, which is to observe the clustering of several 3D traces that have overlap. Maybe this is a different question about, if there's any tool to plot with a “physically correct” look in python? – heracho Sep 11 '17 at 21:18
  • 1
    Well, as the FAQ says, you may look into mayavi. Note that questions about software recommendations are off-topic here, but you may of course try any python 3D library you find and post a specific question here if it fails. – ImportanceOfBeingErnest Sep 11 '17 at 21:47

1 Answers1

3

As of matplotlib 2.1.0, you can set the projection type to orthographic by calling ax.set_proj_type('ortho'). So for your example:

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


fig = plt.figure(figsize = [8, 14])
ax1 = fig.add_subplot(211, projection='3d')
ax2 = fig.add_subplot(212, projection='3d')

ax1.set_proj_type('ortho')
ax2.set_proj_type('ortho')

x = np.linspace(-1, 1, 100)
y = np.linspace(-1, 1, 100)

ax1.plot(x, y, 0, 'b', lw = 3)
ax1.plot(x, y, 1, 'r', lw = 3)

ax2.plot(x, y, 0, 'b', lw = 3)
ax2.plot(x, y, 1, 'r', lw = 3)

ax1.view_init(90, 0)
ax2.view_init(-90, 0)

plt.show()
oha
  • 151
  • 1
  • 4