S F
S F

Reputation: 11

Python: How to create a 3D scatter plot and assign an opacity/transparency to each point, with a large dataset?

So I'm working with some 3D radar data, it basically consists of a 3D array of values that correspond to the return power, that is caused by the reflection from some object.

Because it's a 3D volume this is difficult to properly show in graphs/images etc. The data you want to see is hidden by the outer data for example.

What I would like to do is create a 3D scatter plot of this data where the opacity of each point is a defined by the value of that corresponding xyz (pixel) location.

I have used matplotlibs scatter plot but it is way to slow to use unfortunately and my knowledge of other plotting tools is very limited. Using matplotlib above 1000 points makes it really slow to manipulate the 3D plot so I'm looking for another plotting tool, pyqtgraph, mayavi etc. But it doesn't seem easy to build the scatter plot by the individual xyz points with other tools.

Here is the code I used, with a random 3D array instead of my data (the size of the data I'm using is the same), it's values are between 0 and 1 so no need to normalise etc.

points = np.random.rand(100,20,20)

def Scatter_Plot(points):
    fig = plt.figure()
    ax = fig.add_subplot(projection='3d')

    for x in range(0,points.shape[0]):
        for y in range(0,points.shape[1]):
            for z in range(0,points.shape[2]):
                val = points[x,y,z]
                ax.scatter(x, y, z, alpha=val,c='black',s=3)
    plt.show()

Thank you for your help

Upvotes: 1

Views: 885

Answers (2)

Michael S.
Michael S.

Reputation: 3130

Using your code, it is better to create list values and append to them instead of trying to graph every single time you go through the for loops (this is what was taking forever). You can even use arrays as the hue value if you are working with Matplotlib version that is greater than 3.4.*:

points = np.random.rand(100,20,20)

def Scatter_Plot(points):
    fig = plt.figure()
    ax = fig.add_subplot(projection='3d')

    xList = []
    yList = []
    zList = []
    valList = []
    for x in range(0,points.shape[0]):
        for y in range(0,points.shape[1]):
            for z in range(0,points.shape[2]):
                xList.append(x)
                yList.append(y)
                zList.append(z)
                valList.append(points[x,y,z])

    ax.scatter(xList, yList, zList, alpha=np.array(valList), c='black',s=3)

    plt.show()
Scatter_Plot(points)

Output:

enter image description here

Upvotes: 0

Colim
Colim

Reputation: 1303

Is this what you want?

import numpy as np
from matplotlib import pyplot as plt

points = np.random.rand(100, 20, 20)


def Scatter_Plot(points):
    fig = plt.figure()
    ax = fig.add_subplot(projection='3d')
    from itertools import product

    x, y, z = zip(*list(product(*map(range, points.shape))))
    val = points.flatten()

    ax.scatter(x, y, z, alpha=val, c='black', s=3)
    plt.show()


Scatter_Plot(points)

enter image description here

Upvotes: 0

Related Questions