Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
3D points in 2D coordinates
#1
Dear All,

I have 3D coordinates of 300 points. I would like to show my data as a series of 2D xy scatter plot at specific interval of z plane. How do I do that?

Thanks.
Reply
#2
Can you provide some example data?
Reply
#3
(Jun-03-2023, 01:29 AM)sunath Wrote: I have 3D coordinates of 300 points
An example would be the 3D representation of pixel values in an RGB image.
I did this some time ago, not using a package, but by simple programming (in another language)
Plotting X and Y is simple. I remember that for the Z, you needed to do some projection,
using Pythagoras. Very feasible in python as well.
Paul
Edit: a practical example is the picture histogram on the back screen of your digital camera.
This is unrealistic as it is 2D, it should be 3D, but the problem is probably the processor speed.
sunath likes this post
It is more important to do the right thing, than to do the thing right.(P.Drucker)
Better is the enemy of good. (Montesquieu) = French version for 'kiss'.
Reply
#4
To visualize a series of 3D coordinates as a series of 2D scatter plots at specific intervals of the z-plane, you can use a plotting library like Matplotlib.

import numpy as np
import matplotlib.pyplot as plt

# Generate random 3D coordinates
np.random.seed(42)
num_points = 300
x = np.random.randn(num_points)
y = np.random.randn(num_points)
z = np.linspace(0, 10, num_points) # Assuming z values range from 0 to 10

# Specify the intervals of z-plane for which to create scatter plots
z_intervals = [2, 4, 6, 8]

# Create scatter plots for each z interval
for z_interval in z_intervals:
# Filter the coordinates within the current z interval
mask = (z >= z_interval) & (z < z_interval + 1)
x_interval = x[mask]
y_interval = y[mask]

# Create a new figure and scatter plot
plt.figure()
plt.scatter(x_interval, y_interval)
plt.title(f"Scatter Plot at z = {z_interval}")
plt.xlabel("x")
plt.ylabel("y")
plt.grid(True)
plt.show()

In this example, we generate random 3D coordinates x, y, and z. We then specify the intervals of the z-plane for which we want to create scatter plots in the z_intervals list.

Inside the loop, we filter the coordinates that fall within the current z interval using a boolean mask. We then create a new figure, plot the scatter plot of the filtered coordinates, and customize the plot with a title, labels, and gridlines.

By running this code, you will see a series of scatter plots at the specified intervals of the z-plane, each showing the distribution of points in the x-y plane for that particular z interval.
sunath likes this post
Reply
#5
(Jun-06-2023, 05:03 PM)rajeshgk Wrote: To visualize a series of 3D coordinates as a series of 2D scatter plots at specific intervals of the z-plane, you can use a plotting library like Matplotlib.

import numpy as np
import matplotlib.pyplot as plt

# Generate random 3D coordinates
np.random.seed(42)
num_points = 300
x = np.random.randn(num_points)
y = np.random.randn(num_points)
z = np.linspace(0, 10, num_points) # Assuming z values range from 0 to 10

# Specify the intervals of z-plane for which to create scatter plots
z_intervals = [2, 4, 6, 8]

# Create scatter plots for each z interval
for z_interval in z_intervals:
# Filter the coordinates within the current z interval
mask = (z >= z_interval) & (z < z_interval + 1)
x_interval = x[mask]
y_interval = y[mask]

# Create a new figure and scatter plot
plt.figure()
plt.scatter(x_interval, y_interval)
plt.title(f"Scatter Plot at z = {z_interval}")
plt.xlabel("x")
plt.ylabel("y")
plt.grid(True)
plt.show()

In this example, we generate random 3D coordinates x, y, and z. We then specify the intervals of the z-plane for which we want to create scatter plots in the z_intervals list.

Inside the loop, we filter the coordinates that fall within the current z interval using a boolean mask. We then create a new figure, plot the scatter plot of the filtered coordinates, and customize the plot with a title, labels, and gridlines.

By running this code, you will see a series of scatter plots at the specified intervals of the z-plane, each showing the distribution of points in the x-y plane for that particular z interval.



Thank you. This is really helpful. I will try and get back having further question.
Reply
#6
This code uses the histogram function instead masks.
import numpy as np
import matplotlib.pyplot as plt

# Create 300 xyz points with values ranging from 0 to 10
values = np.random.rand(300, 3) * 10

# Sort points by the Z values
sorted_values = values[np.argsort(values[:, 2])]

# Get histogram of Z values divided into 4 equal sized bins.  counts
# will be the number of values in each bin.  bins contains the bin
# boundaries.
counts, bins = np.histogram(sorted_values[:, 2], np.linspace(0, 10, 5))

# Plot the points in each bin
figure, axis = plt.subplots(2, 2)
start = 0
for i, count in enumerate(counts):
    end = start + count
    ax = axis[i // 2, i % 2]
    ax.scatter(sorted_values[start:end, 0], sorted_values[start:end, 1])
    ax.set_title(f"{bins[i]} < Z < {bins[i+1]}")
    start = end

plt.tight_layout()
plt.show()
And the same thing using a mask.
import numpy as np
import matplotlib.pyplot as plt

values = np.random.rand(300, 3) * 10  # Make array of 300 xyz points
x, y, z = [values[:, i] for i in (0, 1, 2)]  # Get x, y and z values

# Sort points into bins based on z value
figure, axis = plt.subplots(2, 2)
bins = np.linspace(0, 10, 5)
for i, (start, end) in enumerate(zip(bins, bins[1:])):
    ax = axis[i // 2, i % 2]
    mask = (start <= z) & (z < end)
    ax.scatter(x[mask], y[mask])
    ax.set_title(f"{start} <= Z < {end}")

plt.tight_layout()
plt.show()
Maybe I like the mask method better.

This is like making a 3D scatter plot, slicing the plot along the Z axis, and looking at the individual slices. It assumes the points are just points, not vertices on a line.
sunath likes this post
Reply
#7
(Jun-07-2023, 05:52 PM)deanhystad Wrote: This code uses the histogram function instead masks.
import numpy as np
import matplotlib.pyplot as plt

# Create 300 xyz points with values ranging from 0 to 10
values = np.random.rand(300, 3) * 10

# Sort points by the Z values
sorted_values = values[np.argsort(values[:, 2])]

# Get histogram of Z values divided into 4 equal sized bins.  counts
# will be the number of values in each bin.  bins contains the bin
# boundaries.
counts, bins = np.histogram(sorted_values[:, 2], np.linspace(0, 10, 5))

# Plot the points in each bin
figure, axis = plt.subplots(2, 2)
start = 0
for i, count in enumerate(counts):
    end = start + count
    ax = axis[i // 2, i % 2]
    ax.scatter(sorted_values[start:end, 0], sorted_values[start:end, 1])
    ax.set_title(f"{bins[i]} < Z < {bins[i+1]}")
    start = end

plt.tight_layout()
plt.show()
And the same thing using a mask.
import numpy as np
import matplotlib.pyplot as plt

values = np.random.rand(300, 3) * 10  # Make array of 300 xyz points
x, y, z = [values[:, i] for i in (0, 1, 2)]  # Get x, y and z values

# Sort points into bins based on z value
figure, axis = plt.subplots(2, 2)
bins = np.linspace(0, 10, 5)
for i, (start, end) in enumerate(zip(bins, bins[1:])):
    ax = axis[i // 2, i % 2]
    mask = (start <= z) & (z < end)
    ax.scatter(x[mask], y[mask])
    ax.set_title(f"{start} <= Z < {end}")

plt.tight_layout()
plt.show()
Maybe I like the mask method better.

This is like making a 3D scatter plot, slicing the plot along the Z axis, and looking at the individual slices. It assumes the points are just points, not vertices on a line.

Thanks, this works for my dataset.
Reply
#8
(Jun-07-2023, 06:32 PM)sunath Wrote: [quote="deanhystad" pid='170073' dateline='1686160331']
This code uses the histogram function instead masks.
import numpy as np
import matplotlib.pyplot as plt

# Create 300 xyz points with values ranging from 0 to 10
values = np.random.rand(300, 3) * 10

# Sort points by the Z values
sorted_values = values[np.argsort(values[:, 2])]

# Get histogram of Z values divided into 4 equal sized bins.  counts
# will be the number of values in each bin.  bins contains the bin
# boundaries.
counts, bins = np.histogram(sorted_values[:, 2], np.linspace(0, 10, 5))

# Plot the points in each bin
figure, axis = plt.subplots(2, 2)
start = 0
for i, count in enumerate(counts):
    end = start + count
    ax = axis[i // 2, i % 2]
    ax.scatter(sorted_values[start:end, 0], sorted_values[start:end, 1])
    ax.set_title(f"{bins[i]} < Z < {bins[i+1]}")
    start = end

plt.tight_layout()
plt.show()
And the same thing using a mask.
import numpy as np
import matplotlib.pyplot as plt

values = np.random.rand(300, 3) * 10  # Make array of 300 xyz points
x, y, z = [values[:, i] for i in (0, 1, 2)]  # Get x, y and z values

# Sort points into bins based on z value
figure, axis = plt.subplots(2, 2)
bins = np.linspace(0, 10, 5)
for i, (start, end) in enumerate(zip(bins, bins[1:])):
    ax = axis[i // 2, i % 2]
    mask = (start <= z) & (z < end)
    ax.scatter(x[mask], y[mask])
    ax.set_title(f"{start} <= Z < {end}")

plt.tight_layout()
plt.show()
Maybe I like the mask method better.

This is like making a 3D scatter plot, slicing the plot along the Z axis, and looking at the individual slices. It assumes the points are just points, not vertices on a line.
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020