0

I have a 3d scatterplot that needs updating. however, there is no variable that lets me address single datapoints.

self.fig = plt.figure(figsize=(8, 8))
self.ax = self.fig.add_subplot(111, projection='3d')
data_point = self.ax.scatter(xs=0, ys=0, zs=0)

I want to change the x,y,z coordinates but have only managed to change the z coordinate by using set_3d_properties(1,[0]). Other attributes like colour can easily be changed.

The program is supposed to be a dynamic simulation.

I tried searching for setter functions that let me address these coordinates set_offsets, set_data. However, the only promising one (an attribute) _offsets3d gave me a horribly long error message that ended with IndexError: invalid index to scalar variable.

code to reproduce:

import matplotlib
matplotlib.use("TkAgg")
import matplotlib.pyplot as plt

plt.ion()
fig = plt.figure(figsize=(8, 8))

ax = fig.add_subplot(111, projection='3d')
size = 6
ax.set_xlim(-(size / 2), size / 2)
ax.set_ylim(-(size / 2), size / 2)
ax.set_zlim(-(size / 2), size / 2)
datapoint = ax.scatter(0,0,0)

datapoint.set_data([1,1]) # supposed to work, doesn't work
datapoint.set_3d_properties(0,[5]) # works, changes the z coordinate

plt.show()
I Me
  • 3
  • 4
  • i added code to reproduce the problem. I'm thinking about clearing all scatterdots every step of the animation. Will greatly increase computation time though – I Me Jan 10 '23 at 10:23

1 Answers1

0

Not exactly an answer, but I expect that this can help the OP

  1. Create a scatterplot
In [20]: fig, ax = plt.subplots(layout='tight', subplot_kw=dict(projection="3d"))
    
In [21]: sp = ax.scatter((1,3), (5,2), (3,10))
  1. Investigate the (private) ._offsets3d attribute
In [22]: type(sp._offsets3d)
Out[22]: tuple
 
In [23]: [type(offset) for offset in sp._offsets3d]
Out[23]: [numpy.ma.core.MaskedArray, numpy.ma.core.MaskedArray, numpy.ndarray]
  1. View its contents
In [24]: sp._offsets3d[0]
Out[24]: 
masked_array(data=[1.0, 3.0],
             mask=[False, False],
       fill_value=1e+20)

In [25]: sp._offsets3d[2]
Out[25]: array([ 3, 10])

I've checked that, e.g., sp._offsets3d[0][] = 9 can be used to change an offset, without raising any error.

I don't know how to trigger the replot of the scatter points' cloud after the coordinates have been updated.

gboffi
  • 22,939
  • 8
  • 54
  • 85
  • thanks, i've tried it out and got the same problem as you. Even though the offsets3d should be processed in the set_3d_properties of the art3d class in matplotlib, it does not process the changes made in the x,y offsets by .set_offsets([1,1]) – I Me Jan 10 '23 at 14:07
  • @IMe Sometimes I think that Matplotlib's code is a matrioska AND a Klein bottle. =:-) – gboffi Jan 10 '23 at 16:01