Python 3D Plot made simple, from text file data.
This brief article introduces how you can plot a 3D chart in Python from data that you would store in a data file (.csv or .txt). The exercise may sound trivial but in practice it is not so obvious, especially for a novice python programmer. And on top of this, charting such 3D illustration is a very recurrent use when performing numerical analysis.
In this post we explain how you could plot a rate surface (bootstrapped from a multicurve procedure), arranged by tenor and zero coupon rate maturity.
The data (a 3-column array sorted by maturity/tenor/rate) is attached in the Surface.txt file at the end of this article. I used Visual Studio 2010 and the Python Tools for Visual Studio extension.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
from mpl_toolkits.mplot3d import Axes3D from matplotlib import cm import matplotlib.pyplot as plt from matplotlib.mlab import griddata import numpy as np from math import log fig = plt.figure() ax = fig.gca(projection='3d') data = np.genfromtxt('Surface.txt') #zero coupon maturity dates y = data[:,0] #tenor x = data[:,1] #rates z = data[:,2] #maturity dates chart axis uniquemat = np.unique(y) end = log(np.max(uniquemat))/log(uniquemat[0]) #the zc rate maturity axis is arranged in log space yi = np.logspace(1, end,len(uniquemat),True,uniquemat[0]) #tenor chart axis xi = np.unique(x) X, Y = np.meshgrid(xi, yi) Z = griddata(x, y, z, xi, yi, interp='linear') # Plot rate surface print "Plotting rate surface ..." fig = plt.figure() fig.suptitle('EUR rate surface',fontsize=20) ax = fig.gca(projection='3d') surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1,alpha=0.3) ax.set_xlabel('Tenor') ax.set_ylabel('Zc maturity') ax.set_zlabel('Zc Rate (%)') # Override tenor axis labels labels = [item.get_text() for item in ax.get_xticklabels()] labels[0] = '1M' labels[1] = '3M' labels[2] = '6M' labels[4] = '1Y' ax.set_xticklabels(labels) # Plot 3D contour zzlevels = np.linspace(Z.min(),Z.max(),num=8,endpoint=True) xxlevels = np.linspace(X.min(),X.max(),num=8,endpoint=True) yylevels = np.linspace(Y.min(),Y.max(),num=8,endpoint=True) cset = ax.contour(X, Y, Z, zzlevels, zdir='z',offset=Z.min(), cmap=cm.coolwarm) cset = ax.contour(X, Y, Z, xxlevels, zdir='x',offset=X.min(), cmap=cm.coolwarm) cset = ax.contour(X, Y, Z, yylevels, zdir='y',offset=Y.max(), cmap=cm.coolwarm) plt.clabel(cset,fontsize=10, inline=1) ax.set_zlim3d(np.min(Z), np.max(Z)) plt.show() |
This is the output of this code, finally:
Leave a Reply