LeGOATJames23
LeGOATJames23

Reputation: 121

Matplotlib: Creating a 3d cube plot

I am trying to learn how to create a 3D cube plot to visualize data. Here I am creating some mock data to represent sales of items. On the x axis, I am trying to plot the year, Y axis I am trying to plot the items sold, and the Z axis would have the prices these items sold at. This would be an example of one row of the mock dataset:

year    category    sales
2002    clothes     275

again, having year on the x-axis, category on the y-axis, and sales on the z-axis.

What I currently have is:

def plot_cube():
    x = []
    y = []
    z = []

    #creating data to plot. 300 total samples. x list will contain years (2001, 2002, and 2003
    for i in range(100):
        x.append(2001)
    for i in range(100):
        x.append(2002)
    for i in range(100):
        x.append(2003)

    # creating data to plot. 300 total samples. y list will contain items being sold (clothes, shoes, and hats)
    for i in range(100):
        y.append("clothes")
    for i in range(100):
        y.append("shoes")
    for i in range(100):
        y.append("hats")

    # creating data to plot. 300 samples. z list will contain how much in sales
    for i in range(300):
        z.append(random.randint(200, 300))

    arr = []

    for i in range(300):
        arr.append([x[i], y[i], z[i], 0])

    data = zip(*arr)

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

    ax.scatter(data[0], data[1], data[2], c=data[3])
    pyplot.show()

    #returning x,y,z as lists
    return x, y, z

I grabbed methods from different forums to put this together, as I saw a lot of people using the zip() function. However, this is currently not working for me, as it returns the error:

TypeError: 'zip' object is not subscriptable

I saw some people fix this by changing 'data = zip(*arr)' to 'data = list(zip(*arr))', but when I do this, I then get a different error: ValueError: could not convert string to float: 'clothes'

Any ideas?

Upvotes: 0

Views: 659

Answers (2)

thmslmr
thmslmr

Reputation: 1302

ax.scatter() takes as input the lists of X values, Y values and Z values. So no need to create the intermediary arrays arr and data.

Then, X, Y and Z need to be numeric values, so map "clothes", "shoes" and "hat" string values to numeric values (e.g 0, 1, 2) and set the yticks labels afterward.

Here is a working example:

import random
import matplotlib.pyplot as plt


x = [2001] * 100 + [2002] * 100 + [2003] * 100
    # clothes   # shoes     # hats
y = [0] * 100 + [1] * 100 + [2] * 100
z = [random.randint(200, 300) for i in range(300)]

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

ax.scatter(x, y, z, c=z)

ax.set_yticks([0, 1, 2], ["clothes", "shoes", "hats"])

enter image description here

Upvotes: 0

Marko Knöbl
Marko Knöbl

Reputation: 512

If you want to have the category on an axis, it has to be a numeric value - e.g. 1, 2, 3 - instead of clothes, shoes, hats

Upvotes: 0

Related Questions