6

I'm writing an interface for making 3D scatter plots in matplotlib, and I'd like to access the data from a python script. For a 2D scatter plot, I know the process would be:

import numpy as np
from matplotlib import pyplot as plt

fig = plt.figure()
ax = fig.add_subplot(111)
h = ax.scatter(x,y,c=c,s=15,vmin=0,vmax=1,cmap='hot')
data = h.get_offsets()

With the above code, I know that data would be a (N,2) numpy array populated with my (x,y) data. When I try to perform the same operation for 3D data:

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

fig = plt.figure()
ax = Axes3D(fig)
h = ax.scatter(x,y,z,c=c,s=15,cmap='hot',vmin=0,vmax=1)
data = h.get_offsets()

The resulting data variable is still an (N,2) numpy array rather than a (N,3) numpy array. The contents of data no longer match any of my input data; I assume that data is populated with the 2D projections of my 3D data, but I would really like to access the 3D data used to generate the scatter plot. Is this possible?

1 Answer 1

4

Indeed, the coordinates obtained via get_offsets are the projected coordinates. The original coordinates are hidden inside the mpl_toolkits.mplot3d.art3d.Path3DCollection which is returned by the scatter in three dimensional axes. You would obtain the original coordinates from the ._offsets3d attribute. (This is a "private" attribute, but unfortunately the only way to retrieve this information.)

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

fig = plt.figure()
ax = Axes3D(fig)
x = [1,2,3,4]
y = [1,3,3,5]
z = [10,20,30,40]
c= [1,2,3,1]
scatter = ax.scatter(x,y,z,c=c,s=15,cmap='hot',vmin=0,vmax=1)
data = np.array(scatter._offsets3d).T
print(scatter)  # prints mpl_toolkits.mplot3d.art3d.Path3DCollection
print(data)

# prints
# 
# [[  1.   1.  10.]
#  [  2.   3.  20.]
#  [  3.   3.  30.]
#  [  4.   5.  40.]]
Sign up to request clarification or add additional context in comments.

4 Comments

As a follow-on, is it possible to use ._offsets3d from to update/change the plotted data?
Yes, that is possible.
Isn't it possible to access this data using ax instead?
It think it could be accessed via ax using ax.collections[0]._offsets3d.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.