Draw a curve from the scatter plot in matplotlib in Python? - python

My Question:
How can i draw a curve though this data, thus describing an equation for this plot..
I generated this scatter plot by following code, but I am not able to figure out how to generate an equation for this data and draw the corresponding curve on this plot simultaneously. Please Help.!
def draw(data,xlabel,ylabel):
print('length of data : ',len(data))
x,y = [],[]
for i in data:
x.append((i[1]))
y.append((i[0]))
plt.scatter(x, y,marker=r'o',color='b')
plt.xlabel(xlabel)
plt.ylabel(ylabel)
plt.show()
Basically I want something like this:

You have to perform a curve fitting procedure, which is called a regression problem in mathematics. In your case it seems that data is more or less exponential, but you can fit arbitrary function through scipy.optimize.curve_fit
http://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.curve_fit.html

Related

How to get corner plots from a MCMC parameters

I have a MCMC results and trying to plot with corner.py I only obtain one plot instead of three. I have one parameter that I want to plot but I don't know what's happening.
I used my data results (gamma) as follows:
figure = corner.corner(nh, labels=[r"$\Gamma$", r"$\Gamma$"],
quantiles=[0.16, 0.5, 0.84], show_titles=True, title_kwargs={"fontsize": 12},)
#corner.corner(gamma*2, fig=figure, color='red')
plt.show()

How to label multiple arrows in the same quiver plot using python

I am working on a visualization script for a linear algebra class at the university and I am trying to show multiple vectors using the quiver function in python. I am trying to plot vectors coming from a 2x2 matrix in one quiver function, however, now that I am trying to label them I would like to access each vector individually.
import numpy as np
import matplotlib.pyplot as plt
A = np.array([[1,3], [2,2]])
# create figure
fig = plt.figure()
# creates variable containing current figure
ax = fig.gca()
baseArrow = ax.quiver(*origin, A[0,:], A[1,:], color=['r','g']', angles='xy', scale_units='xy', scale=1)
ax.quiverkey(baseArrow,.85,.85,0.8,'i-hat',labelcolor='k',labelpos='S', coordinates = 'figure')
# display grid
plt.grid()
# display figure
plt.show()
This alows me to label the first vector with the respective color (red). Now what I would like to do is label the second vector in green with a different label?
Maybe something like:
ax.quiverkey(baseArrow**[2]**,.85,.85,0.8,'i-hat',labelcolor='k',labelpos='S', coordinates = 'figure')
Is there any way to pull out each vector by itself or would it be better to plot them individually instead of as a vector? I looked at the following question but it doesn't really solve my issue. Matplotlib Quiver plot matching key label color with arrow color
My feeling is that the quiver function is better suited/intended to plot numerous vectors as you would find in a graph depicting magnetic forces, vortices (sic) or gradients (see meshgrid for example). And it's API reflects that, in that it accepts end and start coordinates separately: i.e. you need to split the components of your vectors as you have done above.
May I suggest you look into the plot or arrow functions which will give you greater control over your visualization (e.g. vector-independent labels) and will also provide greater clarity in your code, as you will be able to declare vectors (as np.arrays of course) and use them directly.
Finally note that you can obtain fig and ax in one call: fib, ax = plt.subplots().
Hope this helps!

How to specify the z values in a contour plot - seaborn / matplotlib

I am measuring the accuracy of a machine learning classifier which has two parameters. I would like to have the x and y axes represent these two parameters, and have the z index (the contour / depth) show the accuracy of the model.
The problem i'm having is that seaborn's kdeplot seems to be calculating the z index based on where the points are in the graph; It doesn't show the accuracy, but rather the concentration of points.
Is there a way to use the accuracy (the score of these points) to show the depth of the graph?
Or maybe this isn't the best way to represent this kind of information?
sns.jointplot(x="n_estimators", y="learning_rate",
data=data, height=8, ratio=10, space=0,
color="#383C65")\
.plot_joint(sns.kdeplot, zorder=0, shade=True, shade_lowest=False,
cmap=sns.cubehelix_palette(light=1, as_cmap=True), legend=True, cbar=False,
cbar_kws={})
Where data is a pandas Dataframe with three columns: learning_rate, n_estimators, accuracy
I have also used matplotlib's contourf to the same results. Would really appreciate any help. Thanks!

How to fit a 3D curve data without model?

I have a scatter curved data in 3D z=f(x,y), I want to fit it a smoothed curve. The fitted curve needs to be able to be extracted points from.
I don't have a model for it and I don't bother to make a model. I was thinking use polyfit but it seems only to work for 2D data. I have seen an answer that suggests to make one variable as independent and generate the other two w.r.t it, let's say x. I don't think it is a good idea as the relation between y and z is ignored.
I tried using scipy.interpolate.splprep. I later realised it was spline not fitting.
import numpy as np
import matplotlib.pyplot as plt
from scipy import interpolate
from mpl_toolkits.mplot3d import Axes3D
tck, u = interpolate.splprep([xdata,ydata,zdata], s=2)
x,y,z = interpolate.splev(u,tck)
fig1 = plt.figure(1)
ax3d = fig1.add_subplot(111, projection='3d')
ax3d.plot(xdata,ydata,zdata, 'bo')
ax3d.plot(x,y,z, 'r-')
Is there a way to make interpolate.splprep smoother? Or any other method to fit a 3D curve?
Edit
I have managed to make the curve smoother by increase quite a bit of s.
The x,y,z given by splev are distributed unevenly like the original data. How can I extract a even spread data from the smoothed curve.
Or I mean how I can get the smoothed spline model by splprep, I can np.linspace x and y then sub to the model and get a smoothed data set.
This is my data.
A curve
Fitting a polynomial using np.polyfit in 3 dimensions
Follow the second answer of this question, I managed to get a coefficient result by sklearn. But I don't know how to use it. How can I used it to get the smoothed data?
I am frustrating not able to find a way plot or extract data from it.

Number density contours in Python

I'm trying to reproduce this plot in python with little luck:
It's a simple number density contour currently done in SuperMongo. I'd like to drop it in favor of Python but the closest I can get is:
which is by using hexbin(). How could I go about getting the python plot to resemble the SuperMongo one? I don't have enough rep to post images, sorry for the links. Thanks for your time!
Example simple contour plot from a fellow SuperMongo => python sufferer:
import numpy as np
from matplotlib.colors import LogNorm
from matplotlib import pyplot as plt
plt.interactive(True)
fig=plt.figure(1)
plt.clf()
# generate input data; you already have that
x1 = np.random.normal(0,10,100000)
y1 = np.random.normal(0,7,100000)/10.
x2 = np.random.normal(-15,7,100000)
y2 = np.random.normal(-10,10,100000)/10.
x=np.concatenate([x1,x2])
y=np.concatenate([y1,y2])
# calculate the 2D density of the data given
counts,xbins,ybins=np.histogram2d(x,y,bins=100,normed=LogNorm())
# make the contour plot
plt.contour(counts.transpose(),extent=[xbins.min(),xbins.max(),
ybins.min(),ybins.max()],linewidths=3,colors='black',
linestyles='solid')
plt.show()
produces a nice contour plot.
The contour function offers a lot of fancy adjustments, for example let's set the levels by hand:
plt.clf()
mylevels=[1.e-4, 1.e-3, 1.e-2]
plt.contour(counts.transpose(),mylevels,extent=[xbins.min(),xbins.max(),
ybins.min(),ybins.max()],linewidths=3,colors='black',
linestyles='solid')
plt.show()
producing this plot:
And finally, in SM one can do contour plots on linear and log scales, so I spent a little time trying to figure out how to do this in matplotlib. Here is an example when the y points need to be plotted on the log scale and the x points still on the linear scale:
plt.clf()
# this is our new data which ought to be plotted on the log scale
ynew=10**y
# but the binning needs to be done in linear space
counts,xbins,ybins=np.histogram2d(x,y,bins=100,normed=LogNorm())
mylevels=[1.e-4,1.e-3,1.e-2]
# and the plotting needs to be done in the data (i.e., exponential) space
plt.contour(xbins[:-1],10**ybins[:-1],counts.transpose(),mylevels,
extent=[xbins.min(),xbins.max(),ybins.min(),ybins.max()],
linewidths=3,colors='black',linestyles='solid')
plt.yscale('log')
plt.show()
This produces a plot which looks very similar to the linear one, but with a nice vertical log axis, which is what was intended:
Have you checked out matplotlib's contour plot?
Unfortunately I couldn't view yours images. Do you mean something like this? It was done by MathGL -- GPL plotting library, which have Python interface too. And you can use arbitrary data arrays as input (including numpy's one).
You can use numpy.histogram2d to get a number density distribution of your array.
Try this example:
http://micropore.wordpress.com/2011/10/01/2d-density-plot-or-2d-histogram/

Categories

Resources