0

I have a dataframe z1 with entries as follows:

z1.ix[1:10,1:3]
            2017-04-01  2017-05-01
2017-01-04         NaN    0.993549
2017-01-05         NaN         NaN
2017-01-06    0.830973    0.978463
2017-01-09    0.926456         NaN
2017-01-10    0.998371    0.997590
2017-01-11    0.997539    0.999364
2017-01-12    NaN         0.989801
2017-01-13    0.999701    0.998526
2017-01-16    0.995119    0.998891

I am trying to create the surface plot using the row index as X-axis, column names as Y-axis and values on Z-axis.

I tried the following:

    import matplotlib as mpl
    import matplotlib.pyplot as plt
    from mpl_toolkits.mplot3d import Axes3D

    x = z1.columns
    y = z1.index
    X, Y = np.meshgrid(x, y)
    Z = z1
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')
    ax.plot_surface(X, Y, Z)

I get following error:

TypeError: ufunc multiply cannot use operands with types dtype('float64') and dtype('<M8[ns]')

Both the column names and row index for my dataframe are datetimes. How can I improve my code to make the 3D SMOOTH surface plot.

z1.shape
(182, 32)

1 Answer 1

1

I think some of these libraries does not support datetime type.
You should convert your data to an appropriate format first. Here is the example (sorry for the io thing, it's just for simple copy-paste dataframe)

from io import StringIO
import pandas as pd
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D

s = StringIO("""
            2017-04-01  2017-05-01
2017-01-04         NaN    0.993549
2017-01-05         NaN         NaN
2017-01-06    0.830973    0.978463
2017-01-09    0.926456         NaN
2017-01-10    0.998371    0.997590
2017-01-11    0.997539    0.999364
2017-01-12    NaN         0.989801
2017-01-13    0.999701    0.998526
2017-01-16    0.995119    0.998891""")
z1 = pd.DataFrame.from_csv(s, sep='\s+')


def string_date_to_numeric(li):
    series = pd.Series(li)
    datetime = pd.to_datetime(series)
    numeric = pd.to_numeric(datetime)
    return numeric


x = string_date_to_numeric(z1.columns)
y = string_date_to_numeric(z1.index)
X, Y = np.meshgrid(x, y)
print(X, Y)
Z = z1.values
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_surface(X, Y, Z)
fig.savefig('plot.png')

figure:

enter image description here

You can rename axis afterward.

ax.set_xticklabels(z1.columns)
ax.set_yticklabels(z1.index)
Sign up to request clarification or add additional context in comments.

1 Comment

added to code example, you can set size, formatting and everything else.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.