0
votes

Trying to understand exactly how the Surface plot inputs work for plotly. Every example I've seen has all values be numeric, and the desired input is for x or y to be a category.

In a test example, I have 3 states that have a 'count' value for each week. I want to see the progression of each state's 'count' on a week by week basis. Data is initially structured like so

import pandas as p
import plotly.graph_objects as go

# dummy categorical data
labels = ['state','week','count']
test_data = [
['Washington', 1, 5],
['Washington', 2, 3],
['Washington', 3, 1],
['Washington', 4, 0],
['California', 1, 2],
['California', 2, 4],
['California', 3, 6],
['California', 4, 8],
['New York', 1, 0],
['New York', 2, 5],
['New York', 3, 5],
['New York', 4, 15]]
dataFrame = p.DataFrame(test_data, columns=labels)

where it gets tricky afterwards is I'm not sure how this needs to be structured so when viewing the plot you have

  • an X axis containing each week
  • a Y axis containing each state
  • a Z axis showing the count for each state, on a week to week basis

I've tried a lot of different methods at this point, and I can tell it understands the max value for Z because the colorscale bar goes up to the max value in the dataframe but I can't figure out what I need to do so each state is properly displayed as its own tick, each week is displayed on the other axis, and the z corresponds directly with the week:state 'count' value from the dataframe. None of the attempted methods have been quite right with results so different it wouldn't add value to show them here.

Does anyone have a practical working example with real categorical data, or know the way to structure the above dataframe so the surface plot shows count by state over time?


A more specific way to ask it would be: how do you take a dataframe where 3 columns should be your X, Y, and Z and have them display as such in a Surface plot? between X and Y, one of them needs to be a string representing a category, and the other needs to be able to be a datetime or int.

1

1 Answers

0
votes

Ah, it takes the same inputs as a heatmap. The X and Y are more so the label values while your z data is what's going to contain all the plotted values. I was able to put it together as so using a previous example

# grab x/y labels, create storage for z data
states = dataFrame['state'].unique()
states.sort()
weeks = dataFrame['week'].unique()
weeks.sort()
z_data = []

# extract z data using x,y coordinates within the dataframe
for week in weeks:
  row = []
  for state in states:
    val = dataFrame[
      (dataFrame['state'] == state) &
      (dataFrame['week'] == week)]['count'].values[0]
    row.append(val)
  z_data.append(row)


# create and show the Surface plot
trace = go.Surface(x=states, y=weeks, z=z_data)
data = [trace]
fig = go.Figure(data=data)
fig.show()

enter image description here