Home > Software engineering >  Plotting a surface in Python from three measurment arrays
Plotting a surface in Python from three measurment arrays

Time:05-26

Hello I have three arrays x, y, and z where i want to view the, magnitude of variable z at the co-ords of x and y. I.e. I want to plot a surface of three [6147,1] arrays. using the code below i get Value Error: cannot reshape array of size 6147 into shape (6147,6147) can anyone trouble shoot this and help me get this visualisation to work?

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits import mplot3d
import numpy as np
import matplotlib.pyplot as plt

data_frame = pd.read_excel (r'\Users\alexd\OneDrive\Documents\University\Monash Motor Sport\Junior Project\Junior Project\MotionControlData.xlsx') #place "r" before the path string to address special character, such as '\'. Don't forget to put the file name at the end of the path   '.xlsx'

df_x = pd.DataFrame(data_frame, columns= ['x'])

df_y = pd.DataFrame(data_frame, columns= ['y'])

df_angle = pd.DataFrame(data_frame, columns= ['angle'])

df_vel = pd.DataFrame(data_frame, columns= ['vel'])


# Creating dataset
x = np.array(df_x)
y = np.array(df_y)
angle = np.array(df_angle)
vel = np.array(df_vel)

z = vel
 
x = np.reshape(x, (6147, 6147))
y = np.reshape(y, (6147, 6147))
z = np.reshape(z, (6147, 6147))


fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

ax.plot_surface(x, y, z)

ax.set_xlabel('X Label')
ax.set_ylabel('Y Label')
ax.set_zlabel('Z Label')

plt.show()


Photo reference from comment section

Array of z plotted


New code for new context to comments

# -*- coding: utf-8 -*-
"""
Created on Fri May 13 18:30:41 2022

@author: alexd
"""
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits import mplot3d
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm

data_frame = pd.read_excel (r'\Users\alexd\OneDrive\Documents\University\Monash Motor Sport\Junior Project\Junior Project\MotionControlData.xlsx') #place "r" before the path string to address special character, such as '\'. Don't forget to put the file name at the end of the path   '.xlsx'

df_x = pd.DataFrame(data_frame, columns= ['x'])

df_y = pd.DataFrame(data_frame, columns= ['y'])

df_angle = pd.DataFrame(data_frame, columns= ['angle'])

df_vel = pd.DataFrame(data_frame, columns= ['vel'])


# Creating dataset
x = np.array(df_x)
y = np.array(df_y)
angle = np.array(df_angle)
vel = np.array(df_vel)

z = vel
 


fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

xx, yy = np.meshgrid(np.squeeze(x), np.squeeze(y))

ax.plot_surface(x, y, z.T, cmap=cm.coolwarm,
                       linewidth=1, antialiased=False)


ax.set_xlabel('X ')
ax.set_ylabel('Y ')
ax.set_zlabel('Velocity ')

plt.show()

Current Graph

Variable Explorer for variables of interest

CodePudding user response:

It's much easier to do this kind of thing with xarray, because it can construct the NumPy array for you without you needing to worry about the order in which you read in the data, or the shape of the dataset.

In a nutshell, xarray gives you Pandas-like indexing for n-dimensional NumPy arrays (and a lot more besides). So, for instance, you can have geographic (x, y) coordinates for your 2-D NumPy array, instead of having to use NumPy's 0-based integer indices.

There are two main data structures: the xarray.DataArray, which is basically like a NumPy array, and the xarray.Dataset which is like a collection of DataArray objects that share coordinates.

So you'll either want to use xarray.DataArray.from_series for a single variable (e.g. angle) or xarray.Dataset.from_dataframe for multiple variables (e.g. angle and vel). In each case, the dataframe's index or multi-index is used for the coordinate(s), so you'll want to set that first.

You'll want to start with something like:

import xarray as xr

df = df.set_index(['x', 'y'])
ds = xr.Dataset.from_dataframe(df)
ds['angle'].plot()

CodePudding user response:

I am not sure what your data exactly are, so I cannot run a test case. However it seems a pretty standard case. Assuming z is indeed long enough to be reshaped into (6147, 6147), you probably need just

xx, yy = np.meshgrid(np.squeeze(x), np.squeeze(y))
ax.plot_surface(x, y, z.T)
  • Related