I need to make a 3d plot, where the axes will have labels in string instead of values. So I have 3 lists, the same size, and I need to have the first element of the first list to be my X coordinate, the first element of the second list to be my Y coordinate, and the first element of the third list to be my Z coordinate.
Here is my code:
x = ['7th generation', '7th generation', '7th generation', '7th generation', '7th generation', 'Dawn Ultra', 'Dawn Ultra', 'Dawn Ultra', 'Dawn Ultra', 'Dawn Ultra', 'Mrs Meyers', 'Mrs Meyers', 'Mrs Meyers', 'Mrs Meyers', 'Mrs Meyers', 'Ultra Palmolive', 'Ultra Palmolive', 'Ultra Palmolive', 'Ultra Palmolive', 'Ultra Palmolive']
y = ['0.05 ml : 25 ml', '0.05 ml : 25 ml', '0.05 ml : 25 ml', '0.05 ml : 25 ml', '0.05 ml : 37.5 ml', '0.05 ml : 37.5 ml', '0.05 ml : 37.5 ml', '0.05 ml : 37.5 ml', '0.05 ml : 50 ml', '0.05 ml : 50 ml', '0.05 ml : 50 ml', '0.05 ml : 50 ml', '0.05 ml : 62.5 ml', '0.05 ml : 62.5 ml', '0.05 ml : 62.5 ml', '0.05 ml : 62.5 ml', '0.05 ml : 75 ml', '0.05 ml : 75 ml', '0.05 ml : 75 ml', '0.05 ml : 75 ml']
z = [0, 0, 0, 0, 0, 0, 3, 0, 0, 1, 1, 0, 0, 4, 1, 0, 0, 0, 1, 6]
%matplotlib notebook
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(x, y, z, c=y)
ax.set_xlabel("$detergent$")
ax.set_ylabel("$concentration$")
ax.set_zlabel("$num_colon$");
But it returns to me an error:
ValueError: could not convert string to float: '7th generation'
The error is given since you are trying to plot a string in a numeric plot. You need to handle the conversion before. An option is to use a LabelEncoder by scikitlearn.
from sklearn.preprocessing import LabelEncoder
x_le = LabelEncoder()
y_le = LabelEncoder()
x_num = x_le.fit_transform(x)
y_num = y_le.fit_transform(y)
Then you can plot the values and set the original arrays as labels
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(x_num, y_num, z, c=y_num)
ax.set_xticks(range(0,len(x_le.classes_)))
ax.set_xticklabels(x_le.classes_)
ax.set_yticks(range(0,len(y_le.classes_)))
ax.set_yticklabels(y_le.classes_)