'Line chart to surface chart

[UPDATE: Sorry for not providing the piece where the author of the codes create example data. I have updated the codes]

I found an example of a 3D mesh line chart that satisfied what I need (colouring change with level on z dimension). However, instead of line, I want surface plot. How can I change the codes to have the 3d surface plot?

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib import animation, rc
from matplotlib.cm import get_cmap
from mpl_toolkits.mplot3d import Axes3D
from matplotlib.font_manager import FontProperties
from matplotlib.collections import LineCollection
from matplotlib.colors import ListedColormap
from mpl_toolkits.mplot3d.art3d import Line3DCollection
 
index_returns = np.random.normal(loc=1e-4, scale=5e-3, size=(783, 9))
index_returns = np.vstack((np.zeros(shape=(1, 9)) + 100, index_returns))
index_prices = np.cumprod(1 + index_returns, axis=0)
window = 261
df = np.zeros(shape=(index_prices.shape[0]-window, 9))
for i in range(window, index_prices.shape[0], 1):
    df[i-window] = (index_prices[i]/index_prices[i-window]) - 1
index = pd.date_range('2019-01-01', periods=index_prices.shape[0]-window, freq='B')
columns = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I']
df = pd.DataFrame(df, index=index, columns=columns)
# create the figure
    fig = plt.figure(figsize=(14.4, 9))
    ax = fig.add_subplot(111, projection='3d')
    fig.patch.set_alpha(1) 
    # get the cmap to use
    cmap = get_cmap('RdYlGn')
    # get the slice based on data frame 
    current_slice = df.values[:261, :]
    index_names = df.columns
    index_dates = df.index
    # list holding the lines
    lines = []
    # for each index...
    for i in range(current_slice.shape[1]):
        # get the coordinates
        x = np.array(np.arange(current_slice.shape[0]))
        y = np.tile(i, current_slice.shape[0])
        z = np.array(current_slice[:, i])
        # crete points and segments to color
        points = np.array([x, y, z]).T.reshape(-1, 1, 3)
        segments = np.concatenate([points[:-1], points[1:]], axis=1)
        # Create a continuous norm to map from data points to colors
        norm = plt.Normalize(-0.19, 0.19)
        lc = Line3DCollection(segments, cmap=cmap, norm=norm, zorder=current_slice.shape[1]-i)
        # Set the values used for colormapping
        lc.set_array(z)
        lc.set_linewidth(2)
        lc.set_color(cmap(z[-1] * 2.5 + 0.5))
        lc.set_label(index_names[i])
        lines.append(ax.add_collection(lc))
    # add the grids
    ax.legend(loc='center right', bbox_to_anchor=(1.1, 0.46), fancybox=True, facecolor=(.95,.95,.95,1), framealpha=1, shadow=False, frameon=True, ncol=1, columnspacing=0, prop={'family': 'DejaVu Sans Mono'})
    ax.set_zlabel('Rolling Equity 1Y', labelpad=10)
    ax.set_zlim(-0.39, 0.39)
    ax.set_zticklabels([' '* 3 + '{:.0%}'.format(val) for val in ax.get_zticks()], fontdict={'verticalalignment': 'center', 'horizontalalignment': 'center'})
    ax.set_xlabel('Date', labelpad=30)
    ax.set_xlim(0, current_slice.shape[0]-1)
    ax.set_xticklabels([index_dates[int(val)].strftime('%m/%y') for val in ax.get_xticks()[:-1]] + [''], rotation=0, fontdict={'verticalalignment': 'top', 'horizontalalignment': 'center'})
    ax.set_yticks(np.arange(current_slice.shape[1]))
    ax.set_yticklabels([index_names[i] for i in range(current_slice.shape[1])], rotation=-15, fontdict={'verticalalignment': 'center', 'horizontalalignment': 'left'})   
    # show the plot
    plt.show()


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source