简体   繁体   中英

Scatter points are disappearing when rotating a 3d surface plot

I'm trying to get a feel for how well a surface fits my data points by graphing everything and rotating the surface around to check for any oddities in the surface behavior relative to the scattered point in 3d space.

The problem is that when I rotate the render to do this, the plots disappear. How can I make the plots persist?

在此处输入图像描述

You can repro with the below code - mainly taken from the amazing answers at Python 3D polynomial surface fit, order dependent .

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

def main():
    # Generate Data...
    numdata = 100
    x = np.random.random(numdata)
    y = np.random.random(numdata)
    z = x**2 + y**2 + 3*x**3 + y + np.random.random(numdata)

    # Fit a 3rd order, 2d polynomial
    m = polyfit2d(x,y,z)

    # Evaluate it on a grid...
    nx, ny = 20, 20
    xx, yy = np.meshgrid(np.linspace(x.min(), x.max(), nx), 
                         np.linspace(y.min(), y.max(), ny))
    zz = polyval2d(xx, yy, m)

    # Plot
    #plt.imshow(zz, extent=(x.min(), y.max(), x.max(), y.min()))
    #plt.scatter(x, y, c=z)
    #plt.show()

    fig = plt.figure()
    ax = Axes3D(fig)
    ax.scatter(x, y, z, color='red', zorder=0)
    ax.plot_surface(xx, yy, zz, zorder=10)
    ax.set_xlabel('X data')
    ax.set_ylabel('Y data')
    ax.set_zlabel('Z data')

    plt.show()
    text = "filler"

def polyfit2d(x, y, z, order=4):
    ncols = (order + 1)**2
    G = np.zeros((x.size, ncols))
    #ij = itertools.product(range(order+1), range(order+1))
    ij = xy_powers(order)
    for k, (i,j) in enumerate(ij):
        G[:,k] = x**i * y**j
    m, _, _, _ = np.linalg.lstsq(G, z)
    return m

def polyval2d(x, y, m):
    order = int(np.sqrt(len(m))) - 1
    #ij = itertools.product(range(order+1), range(order+1))
    ij = xy_powers(order)
    z = np.zeros_like(x)
    for a, (i,j) in zip(m, ij):
        z += a * x**i * y**j
    return z

def xy_powers(order):
    powers = itertools.product(range(order + 1), range(order + 1))
    return [tup for tup in powers if sum(tup) <= order]

main()

A simple thing you can do is setting the transparency of your surface to a lower value than your scatter plot. See example below where I used a transparency value equal to 0.4 with the line ax.plot_surface(xx, yy, zz, zorder=10,alpha=0.4) .

And the output gives:

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM