2

I am trying to fit a plane to a point cloud using RANSAC in scikit.

I am not able to understand how to do it, how to plot the plane which I obtain from ransac.predict.

import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D

from sklearn import datasets, linear_model

diabetes = datasets.load_diabetes()
X_train = diabetes.data[:-20, (0,1)]

y_train = diabetes.target[:-20]

ransac = linear_model.RANSACRegressor(
                                        linear_model.LinearRegression()
                                     )

ransac.fit(X_train, y_train)

fig = plt.figure()
plt.clf()

ax = Axes3D(fig)

ax.plot_surface([-5,5],[-5,5], ransac.predict(X_train))

I am getting error message

ValueError: shape mismatch: objects cannot be broadcast to a single shape
formatkaka
  • 1,278
  • 3
  • 13
  • 27
  • Did you look at the [docs for plot_surface](http://matplotlib.org/1.5.1/mpl_toolkits/mplot3d/tutorial.html#mpl_toolkits.mplot3d.Axes3D.plot_surface)? Here it states that `X`, `Y`, and `Z` must be 2d arrays [of the same shape] which is not the case in your code. – lanery Aug 26 '16 at 06:14
  • I am getting confused about how to plot the plane . I am not even sure if `plot_surface` is right method. – formatkaka Aug 26 '16 at 06:16
  • My guess is that it's not. Judging by the documentation/examples [here](http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.RANSACRegressor.html), the dimensionality of your data, and the names `linear_model` and `linear_regressor`, you should be looking at line plots as opposed to surface plots. – lanery Aug 26 '16 at 06:51
  • there are two input features and one output, so the fit isindeed a plane in 3d. But you need to provide matching shapes to the plot_surface function. Also, showing the traceback is usually helpful. – Andreas Mueller Aug 26 '16 at 14:50
  • hi did u find the plane using RANSAC? @formatkaka – Kazi Dec 25 '19 at 10:11

1 Answers1

3

In this example, you only use 2 features to the fit is not a PLANE but a line.

This can also be seen from:

ransac.estimator_.coef_
array([266.63361536, -48.86064441])

that contains a weight for each of the 2 features that you have.


Let's make a real 3D case:

import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.mplot3d import Axes3D

from sklearn import datasets, linear_model

diabetes = datasets.load_diabetes()
X_train = diabetes.data[:-20, (0,1,2)]

y_train = diabetes.target[:-20]

ransac = linear_model.RANSACRegressor(linear_model.LinearRegression())
ransac.fit(X_train, y_train)


# the plane equation
z = lambda x,y: (-ransac.estimator_.intercept_ - ransac.estimator_.coef_[0]*x - ransac.estimator_.coef_[1]*y) / ransac.estimator_.coef_[2]

tmp = np.linspace(-5,5,50)
x,y = np.meshgrid(tmp,tmp)

fig = plt.figure()
ax  = fig.add_subplot(111, projection='3d')
ax.plot3D(X_train[:,0], X_train[:,1], X_train[:,2], 'or')
ax.plot_surface(x, y, z(x,y))
ax.view_init(10, 60)
plt.show()

enter image description here

seralouk
  • 30,938
  • 9
  • 118
  • 133