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()
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()
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)