matplotlib not displaying intersection of 3D planes correctly [duplicate]
Asked Answered
E

2

7

I want to plot two planes and find their intersection line, but I get this result, where it's impossible to tell where they intersect, because one plane overlays the other.

A 3D projection should hide the non-visible part of the plane, how do I attain this result using matplotlib?

planes

You can clearly see that these to plains should intersect.

plane intersect

Here's the code I've used to get this result

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

values = range(-10, 11)

def plotPlane(plot, normal, d, values, colorName):
    # x, y, z
    x, y = np.meshgrid(values, values)
    z = (-normal[0] * x - normal[1] * y - d) * 1. / normal[2]

    # draw plot
    plot.plot_surface(x, y, z, color=colorName)

image = plt.figure().gca(projection='3d')

plotPlane(image, [3, 2, -4], 1, values, "red")
plotPlane(image, [5, -1, 2], 4, values, "gray")

plt.show()
Extradite answered 5/12, 2013 at 18:35 Comment(1)
See my answer here.Oddity
P
7

See How to draw intersecting planes? for a long explanation + possible work around.

The short answer in that matplotlib's 3D support is clever use of projections to generate a 2D view of the 3D object which is then rendered to the canvas. Due to the way that matplotlib renders (artist at a time) one artist is either fully above or fully below another. If you need real 3D support look into mayavi.

Per answered 5/12, 2013 at 21:36 Comment(4)
Thanks! I've took a huge detour into MATLAB, as far as I can tell, it's straight 3D. But I'll check out mayavi too.Extradite
I am confused, where did MATLAB come into this?Per
matplotlib is a tool, MATLAB is a tool, so I'm just switching tools.Extradite
this answer i posted a while ago is a better way of doing this.Oddity
W
8

Use plotly. You will get an interactive plot which you will be able to snapshot at any angle.

import numpy as np
import plotly.graph_objects as go
from plotly.subplots import make_subplots
from typing import Tuple, Iterable


def plotPlane(fig: go.Figure,
              normal: Tuple[int, int, int],
              d: int,
              values: Iterable,
              colorScaleName: str) -> None:
    """
        :param fig: figure to plot on
        :param colorScaleName: choose from <https://plotly.com/javascript/colorscales/>
    """
    # x, y, z
    x, y = np.meshgrid(values, values)
    z = (-normal[0] * x - normal[1] * y - d) * 1. / normal[2]

    # draw plane
    surface = go.Surface(x=x, y=y, z=z, colorscale=colorScaleName, showscale=False)
    fig.add_trace(surface, row=1, col=1)


# create figure
fig = make_subplots(rows=1, cols=1, specs=[[{'type': 'surface'}]])
# plot two intersectioned surfaces
values = range(-10, 11)
plotPlane(fig, (3, 2, -4), 1, values, "Hot")
plotPlane(fig, (5, -1, 2), 4, values, "Greys")
fig.show()

I ran it in jupyter-notebbok.

enter image description here

enter image description here

Wolfenbarger answered 31/12, 2020 at 12:54 Comment(1)
Epic example! But please add from plotly.subplots import make_subplotsVaria
P
7

See How to draw intersecting planes? for a long explanation + possible work around.

The short answer in that matplotlib's 3D support is clever use of projections to generate a 2D view of the 3D object which is then rendered to the canvas. Due to the way that matplotlib renders (artist at a time) one artist is either fully above or fully below another. If you need real 3D support look into mayavi.

Per answered 5/12, 2013 at 21:36 Comment(4)
Thanks! I've took a huge detour into MATLAB, as far as I can tell, it's straight 3D. But I'll check out mayavi too.Extradite
I am confused, where did MATLAB come into this?Per
matplotlib is a tool, MATLAB is a tool, so I'm just switching tools.Extradite
this answer i posted a while ago is a better way of doing this.Oddity

© 2022 - 2024 — McMap. All rights reserved.