Reputation: 230
I'm learning to create graphs in Seaborn. Now I have a study case with a time series. I would like to make a line using differents types of interpolation between the points.
So my question is, is there some native method to create interpolated lines using Seaborn?
Is there a way similar to the Plotly's line_shape
(hv, vh, hvh, spline, linear)?
Reference in Plotly to the desired form:
(If not, which tool would you recommend to achieve the same effect?) Thanks!
Upvotes: 3
Views: 4100
Reputation: 4735
To choose the interpolant in seaborn, you rely on Matplotlib. As noted in https://seaborn.pydata.org/generated/seaborn.lineplot.html
kwargs key, value mappings Other keyword arguments are passed down to matplotlib.axes.Axes.plot().
So you can pass the drawstyle
argument, which lets you choose between linear or several different step-styles. See the second example at https://matplotlib.org/stable/gallery/lines_bars_and_markers/step_demo.html
import seaborn as sns
import matplotlib.pyplot as plt
x = [1, 2, 3, 4, 5]
y = [1, 3, 2, 3, 1]
dss=['default','steps-pre','steps-mid','steps-post']
fig = plt.figure()
for i,ds in enumerate(dss):
ax = fig.add_subplot(len(dss),1,1+i)
sns.lineplot(x=x,y=y,ax=ax,drawstyle=ds,markers='o')
ax.scatter(x,y)
plt.show()
As you see, there is no option for smoothers such as splines. Curve smoothing interpolants like that adds information not present in the data, and you should always be careful about that. And if you do want to add such preexisting knowedge, then use a manual interpolant as suggested in other answers.
Upvotes: 2
Reputation: 12496
In order to interpolate, you can use scipy.interpolate.interp1d
, which supports many different methods:
‘linear’, ‘nearest’, ‘nearest-up’, ‘zero’, ‘slinear’, ‘quadratic’, ‘cubic’, ‘previous’, or ‘next’
In order to reproduce the plot you provided, here is an example of code:
import numpy as np
from scipy.interpolate import interp1d
import matplotlib.pyplot as plt
import seaborn as sns
x = [1, 2, 3, 4, 5]
y = [1, 3, 2, 3, 1]
x_interp = np.linspace(x[0], x[-1], 1000)
methods = ['linear', 'nearest', 'nearest-up', 'zero', 'slinear', 'quadratic', 'cubic', 'previous', 'next']
fig, ax = plt.subplots()
for i, method in enumerate(methods, 0):
y_values = [y_i + 5*i for y_i in y]
y_interp = interp1d(x, y_values, kind = method)(x_interp)
sns.lineplot(x_interp, y_interp, label = method, ax = ax)
sns.scatterplot(x, y_values, ax = ax)
ax.legend(frameon = False, loc = 'upper left', bbox_to_anchor = (1.05, 1))
plt.tight_layout()
plt.show()
Upvotes: 3