0

I would like to plot in 3D with Pandas / MatplotLib (Wireframe or other, I do not care) but in a specific way..

I'm using RFID sensors and I'm trying to record the signal I receive at different distance + different angles. And I want to see the correlation between the rising of the distance and the angle.

So that's why I want to plot in 3D :

X Axis -> the Distance, Y Axis -> the Angle, Z Axis -> the signal received which means a float

My CSV file from where I generate my DataFrame is organized like this a double entry table :

Distance;0;23;45;90;120;180
0;-53.145;-53.08;-53.1;-53.035;-53.035;-53.035
5;-53.145;-53.145;-53.05;-53.145;-53.145;-53.145
15;-53.145;-53.145;-53.145;-53.145;-53.145;-53.145
25;-53.145;-52.145;-53.145;-53.002;-53.145;-53.145
40;-53.145;-53.002;-51.145;-53.145;-54.255;-53.145
60;-53.145;-53.145;-53.145;-53.145;-53.145;-53.145
80;-53.145;-53.145;-53.145;-53.145;-60;-53.145
100;-53.145;-52;-53.145;-54;-53.145;-53.145
120;-53.145;-53.145;-53.145;-53.145;-53.002;-53.145
140;-51.754;-53.145;-51.845;-53.145;-53.145;-53.145
160;-53.145;-53.145;-49;-53.145;-53.145;-53.145
180;-53.145;-53.145;-53.145;-53.145;-53.145;-53.002
200;-53.145;-53.145;-53.145;-53.145;-53.145;-53.145

On the first label row we've different angles : 0°, 23°, 45°, ... And the index of the DataFrame is the distance : 0 cm, 15 cm...

And the matrix inside represents the signal, so, values of Z Axis...

But I do not know how to generate a 3D Scatter, WireFrame... because in every tutorial I see people that use specific columns as axis.

Indeed, in my CSV file on the first row I've the label of all columns

Distance;0  ;23 ;45 ;90 ;120;180

And I do not know how to generate a 3D plot with a double entry table.

Do you know how to do it ? Or, to generate my CSV file in a better way to see the same result at the end !

I would be grateful if you would help me about this !

Thank you !

2
  • Hm, your z-values are always -45. Do you have more data or different subset which you can share? Commented May 18, 2018 at 17:37
  • These data are just informative. Indeed, the data should be between -20 and -70 Commented May 18, 2018 at 18:02

3 Answers 3

1

maybe contour is enough

b = np.array([0,5,15,25,40,60,80,100,120,140,160,180,200])
a = np.array([0,23,45,90,120,180])
x, y = np.meshgrid(a, b)
z = np.random.randint(-50,-40, (x.shape))

scm = plt.contourf(x, y, z, cmap='inferno')
plt.colorbar(scm)
plt.xticks(a)
plt.yticks(b)
plt.xlabel('Distance')
plt.ylabel('Angle')
plt.show()

displays

enter image description here

Sign up to request clarification or add additional context in comments.

Comments

1

You can get a contour plot with something like this (but for the data shown it is not very interesting since all the values are constant at -45):

df = pd.read_csv(sep=';')
df = df.set_index('Distance')
x = df.index
y = df.columns.astype(int)
z = df.values
X,Y = np.meshgrid(x,y)
Z = z.T
plt.contourf(X,Y,Z,cmap='jet')
plt.colorbar()
plt.show()

Comments

1

Welcome to stackoverflow, your question can be split into several steps:

Step 1 - read the data

I have stored your data in a file called data.txt.

I don't know Pandas very well but this can also be handled with the nice simple function of Numpy called loadtxt. Your data is a bit problematic because of the text 'Distance' value in the first column and first row. But don't panic we load the file as a matrix of strings:

raw_data = np.loadtxt('data.txt', delimiter=';', dtype=np.string_)

Step 2 - transform the raw data

To extract the wanted data from the raw data we can do the following:

angle    = raw_data[0 , 1:].astype(float)
distance = raw_data[1:, 0 ].astype(float)
data     = raw_data[1:, 1:].astype(float)

With indexing the raw data we select the data that we want and with astype we change the string values to numbers.

Intermediate step - making the data a bit fancier

Your data was a bit boring, only the value -45, i took the liberty to make it a bit fancier:

data = (50 + angle[np.newaxis,:]) / (10 + np.sqrt(distance[:,np.newaxis])) 

Step 4 - make a wireframe plot

The example at matplotlib.org looks easy enough:

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_wireframe(X, Y, Z)
plt.show()

But the trick is to get the X, Y, Z parameters right...

Step 3 - make the X and Y data

The Z data is simply our data values:

Z = data

The X and Y should also be 2D array's such that plot_wireframe can find the x and y for each value of Z in the 2D arrays X an Y at the same array locations. There is a Numpy function to create these 2D array's:

X, Y = np.meshgrid(angle, distance)

Step 5 - fancing it up a bit

ax.set_xticks(angle)
ax.set_yticks(distance[::2])
ax.set_xlabel('angle')
ax.set_ylabel('distance')

Putting it together

All steps together in the right order:

# necessary includes...
from mpl_toolkits.mplot3d import axes3d
import matplotlib.pyplot as plt
import numpy as np

raw_data = np.loadtxt('data.txt', delimiter=';', dtype=np.string_)

angle    = raw_data[0 , 1:].astype(float)
distance = raw_data[1:, 0 ].astype(float)
data     = raw_data[1:, 1:].astype(float)


# make the example data a bit more interesting...
data = (50 + angle[np.newaxis,:]) / (10 + np.sqrt(distance[:,np.newaxis])) 

# setting up the plot
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

# the trickey part creating the data that plot_wireframe wants
Z = data
X, Y = np.meshgrid(angle, distance)

ax.plot_wireframe(X, Y, Z)

# fancing it up a bit
ax.set_xticks(angle)
ax.set_yticks(distance[::2])
ax.set_xlabel('angle')
ax.set_ylabel('distance')

# and showing the plot ...
plt.show()

2 Comments

Niceeee that works perfectly ! I mean check this out (with specific values in data) imgur.com/a/7H5IFkT... But do you know how to plot in a 'popup' window. I mean, it would be better if I could you know, move the camera the show from an another view the Wireframe ! (thanks btw !)
I've my perfect data now and I don't know how to reach them with this row data = (50 + angle[np.newaxis,:]) / (10 + np.sqrt(distance[:,np.newaxis])). I would like to take my data in the array instead

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.