Сегодня я на наглядном примере покажу, как привести достаточно угловатый контурный график в надлежащий красивый вид методом кубической интерполяции. С данной проблемой я столкнулся, когда строил график по экспериментальным данным, которые обычно далеки от совершенства. Основной проблемой в построении 3д графиков и контуров является понимание простой вещи - что такое 3д график. А 3д график это не что иное как составленные в ряд по одной оси (x или y) обычные двухмерные графики. Поэтому, проявив небольшую сноровку, можно легко начать пользоваться этим достаточно гибким инструментом визуализации. Обычно для графиков я не привык использовать кубическую интерполяцию. Для меня более правильным методом является аппроксимация, но так как задача стояла просто получить более красивый график из сырых данных я не стал сильно углубляться в этот раз.
Основным математическим аппаратом в среде Python для выполнения подобных действий является NumPy и SciPy. Данный пример написан предельно просто, стоит только пояснить, что данные X, Y, Z были получены при помощи стандартной функции, заложенной матплотлиб, но их можно задать как руками, так и другими способами. На данном примере можно поэкспериментировать со степенью "сырости" этих данных меняя параметр функции, как описано в комментарии. Для самой интерполяции данных мы как раз и будем использовать пакет SciPy. В данном примере показано, что вся интерполяция выполняется по сути одной строкой и функцией zoom и не представляет никакой сложности для понимания, а теперь перейдем непосредственно к коду и результату!
import matplotlib.pyplot as plt
import numpy as np
from scipy.ndimage import zoom
from mpl_toolkits.mplot3d import axes3d
# Receive standard Matplotlib data for 3d plot
X, Y, Z = axes3d.get_test_data(1) # '1' is a step requested data
#Calculate smooth data
pw = 10 #power of the smooth
Xsm, Ysm, Zsm = map((lambda x: zoom(x, pw)), (X, Y, Z))
#or simply make:
#Xsm = zoom(X, pw)
#Ysm = zoom(Y, pw)
#Zsm = zoom(Z, pw)
# Create blank plot
fig = plt.figure()
#Create subplots
ax1 = fig.add_subplot(211)
ax2 = fig.add_subplot(212)
# Plotting
ax1.contour(X, Y, Z)
ax2.contour(Xsm, Ysm, Zsm)
plt.show()