曲线拟合和matplotlib

时间:2019-09-20 18:20:12

标签: python matplotlib curve-fitting

我具有这三个变量,我想绘制其中两个变量之间的关系:

x = [0.125735  , 0.11753342, 0.11572967, 0.11963533, 0.1255283 ,
       0.13183589, 0.13904629, 0.14754317, 0.15548172, 0.16429631,
       0.17474308, 0.18641375]
y = [0.11917991, 0.10663986, 0.09897077, 0.09291739, 0.08743263,
       0.08346636, 0.08161819, 0.08132199, 0.08216186, 0.0834759 ,
       0.08551088, 0.08770163]
z = [1, 2, 3, 4, 5,
       6, 7, 8, 9, 10 ,
       11, 12]

enter image description here

该图像显示x,y。我想拟合一条贯穿所有这些点的线,并用z标记每个点。

2 个答案:

答案 0 :(得分:3)

无中心

这是在极坐标中拟合点的快速示例:

x = [0.125735  , 0.11753342, 0.11572967, 0.11963533, 0.1255283 ,
     0.13183589, 0.13904629, 0.14754317, 0.15548172, 0.16429631,
     0.17474308, 0.18641375]
y = [0.11917991, 0.10663986, 0.09897077, 0.09291739, 0.08743263,
     0.08346636, 0.08161819, 0.08132199, 0.08216186, 0.0834759 ,
     0.08551088, 0.08770163]
z = [1, 2, 3, 4, 5,
     6, 7, 8, 9, 10 ,
     11, 12]

# you need numpy
import numpy as np
import matplotlib.pyplot as plt

x = np.array(x)
y = np.array(y)

r = np.sqrt(x*x + y*y)
theta = np.arctan2(x, y)

plt.scatter(theta, r, z, z)
plt.colorbar()
plt.grid()
plt.title('polar coords')
plt.xlabel('$\\theta$ [rad]')
plt.ylabel('r')

p = np.polyfit(theta, r, 2)
xfit = np.linspace(0.8, 1.15, 15)
yfit = np.polyval(p, x)

plt.plot(xfit, yfit, '--')
plt.legend(['original data', 'fit'])

polar coordinate fit

具有居中

如果我们先将点居中,我们可能会做得更好:

# find the averages to find the centroid of the data
x_avg = x.mean()
y_avg = y.mean()

# center the data
x_star = x - x_avg
y_star = y - y_avg

# now find the radii
r = np.sqrt(x_star*x_star + y_star*y_star)

# make sure points are between 0 adn 360[degrees]
theta = np.degrees(np.arctan2(y_star, x_star)) % 360

plt.scatter(theta, r, z, z)
plt.colorbar()
plt.grid()
plt.title('polar coords')
plt.ylabel('r')
plt.xlabel('$\\theta$ [degrees]')

# fit with 3rd order polynomial
# because there are 2 inflection points
p = np.polyfit(theta, r, 3)

# plot fit
x_fit = np.linspace(90, 360, 270)
y_fit = np.polyval(p, x_fit)
plt.plot(x_fit, y_fit, '--')
plt.legend(['original data', 'fit'])

centered and rotated

最终输出拟合线

这是原始数据的最终输出拟合线:

x_out = y_fit * np.cos(np.radians(x_fit)) + x_avg
y_out = y_fit * np.sin(np.radians(x_fit)) + y_avg

plt.scatter(x, y, z, z)
plt.plot(x_out, y_out, '--')
plt.colorbar()
plt.grid()
plt.title('output fit line')
plt.legend(['original data', 'fit'])

enter image description here

答案 1 :(得分:-1)

这是带有3D散点图,3D表面图和轮廓图的图形3D表面装配工。等高线图表明表面明显弯曲,这就是为什么本示例的方程式比平面更适合拟合的原因。您应该能够在3D图上单击并拖动,然后将它们旋转3个空间以进行视觉检查。使用数据和简单的幂方程“ z = a * pow(x,b)+ c * pow(y,d)”,并拟合参数a = 2.14091547e + 02,b = 1.56841786e + 00,c = -2.24366942 e + 03,d = 2.69437535e + 00,得出RMSE = 0.1122,R-sqiared = 0.9989

scatter

surface

contour

void AddItems () {
    Item itemToAdd = itemDatabase.items[0];
    if (inventoryItems[i].item.isStackable && IsInInventory(itemToAdd)) {
        for (int i = 0; i < inventoryItems.Count; i++) {
            if (inventoryItems[i].item == itemToAdd ) {
                if (inventoryItems[i].stackSize+itemToAdd.stackSize <= inventoryItems[i].item.stackSize) {
                    inventoryItems[i].stackSize += itemToAdd.stackSize;
                } else {
                    itemToAdd.stackSize -= inventoryItems[i].item.stackSize-inventoryItems[i].stackSize;
                    inventoryItems[i].stackSize = inventoryItems[i].item.stackSize;
                    AddItem(itemToAdd);
                }
                break;
            }
        }
    } else {
        AddItem(itemToAdd);
    }
}