Reputation: 99
I am trying to make an evaluation of my area measurement. However, I can't get it to make an area from the points (Position_x, Position_y, Position_z) from a CSV file.
I always get the error: ValueError: Argument Z must be 2-dimensional. and don't know how to fix it.
Can someone please help me with this. I have given an example below.
CSV FILE
Position Y,Position X,Mediane
1.5,0.5,-69.00
1.5,1.0,-67.00
1.5,1.5,-68.00
1.5,2.0,-67.00
1.5,2.5,-63.00
1.5,3.0,-55.50
1.5,3.5,-59.00
1.5,4.0,-62.00
1.5,4.5,-65.00
1.5,5.0,-68.00
1.5,5.5,-65.00
1.5,6.0,-69.00
2,0.5,-72.00
2,1.0,-74.00
2,1.5,-67.00
2,2.0,-71.00
2,2.5,-66.00
Python Code:
import numpy as np
import matplotlib.pyplot as plt
import mpl_toolkits.mplot3d.axes3d as p3
import matplotlib.animation as animation
import pandas as pd
from sys import exit
df = pd.read_csv(r"C:\Users\ramsa\OneDrive\Desktop\Messungen\Auswertungen\Test_Auswertung.csv")
def update_lines(num, data, line):
line.set_data(data[0:2, :num])
line.set_3d_properties(data[2, :num])
return line
fig = plt.figure(figsize = (12,10))
ax = plt.axes(projection='3d')
x = df['Position X']
y = df['Position Y']
X, Y = np.meshgrid(x, y)
Z = df['Mediane']
surf = ax.plot_surface(X, Y, Z, cmap = plt.cm.cividis)
ax.set_xlabel('x', labelpad=20)
ax.set_ylabel('y', labelpad=20)
ax.set_zlabel('z', labelpad=20)
fig.colorbar(surf, shrink=0.5, aspect=8)
plt.show()
Upvotes: 2
Views: 298
Reputation: 99
The solution is.
import pandas as pd
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
# CSV-Datei einlesen
data = pd.read_csv(r"C:\Users\ramsa\OneDrive\Desktop\Messungen\Auswertungen\Test_Auswertung.csv")
# Daten extrahieren
position_y = data['Position Y']
position_x = data['Position X']
mediane = data['Mediane']
# Z-Werte sortieren
sorted_indices = mediane.argsort()
position_y = position_y[sorted_indices]
position_x = position_x[sorted_indices]
mediane = mediane[sorted_indices]
# 3D-Plot erstellen
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_trisurf(position_x, position_y, mediane, cmap='viridis')
# Achsenbeschriftung
ax.set_xlabel('Position X')
ax.set_ylabel('Position Y')
ax.set_zlabel('Mediane')
# Plot anzeigen
plt.show()
Upvotes: 1
Reputation: 542
The error message you're receiving is due to the fact that ax.plot_surface
requires a 2D array for Z
, while you're providing a 1D array.
The np.meshgrid
function generates a two-dimensional grid from the x and y vectors, so we need to make sure our Z
also corresponds to the shape of this grid.
However, the data from the CSV file does not form a regular grid which is necessary for plot_surface
function to work. You can use the scipy.interpolate.griddata
function to interpolate the irregularly spaced data to a regular grid.
Here is how you could do it:
import numpy as np
import matplotlib.pyplot as plt
import mpl_toolkits.mplot3d.axes3d as p3
import matplotlib.animation as animation
import pandas as pd
from sys import exit
from scipy.interpolate import griddata
df = pd.read_csv(r"C:\Users\ramsa\OneDrive\Desktop\Messungen\Auswertungen\Test_Auswertung.csv")
fig = plt.figure(figsize = (12,10))
ax = plt.axes(projection='3d')
# Construct the grid.
x = df['Position X']
y = df['Position Y']
z = df['Mediane']
# Interpolate Z values on 2D grid (Creating a 2D representation of Z values)
xi = np.linspace(x.min(), x.max(), len(x.unique()))
yi = np.linspace(y.min(), y.max(), len(y.unique()))
xi, yi = np.meshgrid(xi, yi)
zi = griddata((x, y), z, (xi, yi), method='cubic')
# Draw the surface plot
surf = ax.plot_surface(xi, yi, zi, cmap = plt.cm.cividis)
ax.set_xlabel('x', labelpad=20)
ax.set_ylabel('y', labelpad=20)
ax.set_zlabel('z', labelpad=20)
fig.colorbar(surf, shrink=0.5, aspect=8)
plt.show()
In this code, the griddata
function is used to create a 2D representation of Z values, which fits the 2D grid we created with np.meshgrid
.
Note that method='cubic'
is used to interpolate the values. This method is good for smooth data, but it could lead to artifacts for non-smooth data or data with large gradients. In such cases, you might want to try method='linear'
or method='nearest'
instead.
Upvotes: 2