J Rock
J Rock

Reputation: 261

Smoothing out a Line chart with Matplotlib

I have a pandas data frame that looks like this:

import pandas as pd 
import matplotlib.pyplot

data = [{'A': 21, 'B': 23, 'C':19, 'D':26,'E':28,
        'F':26,'G':23,'H':22,'I':24,'J':21}] 

# Creates DataFrame. 
df = pd.DataFrame(data)

plt.figure(figsize=(12,8))

df.iloc[-1].plot(marker='o',markersize=5)

plt.show()

When I try and plot this in Matplotlib, I end up with a very jagged line.

Is there a way I can smooth the line out to make it look more curved and fluid?

I have tried to use scipy's interpolate, but have not been successful.

Thanks

Upvotes: 0

Views: 687

Answers (2)

sander
sander

Reputation: 1440

This should do the trick:

import pandas as pd 
import matplotlib.pyplot as plt
from scipy import make_interp_spline

data = [{'A': 21, 'B': 23, 'C':19, 'D':26,'E':28,
        'F':26,'G':23,'H':22,'I':24,'J':21}] 

# Creates DataFrame. 
df = pd.DataFrame(data)

y = np.array(df.iloc[-1].tolist())
x = np.arange(len(df.iloc[-1]))

xnew = np.linspace(x.min(), x.max(), 300) 
spl = make_interp_spline(x, y, k=3)
ysmooth= spl(xnew)

plt.plot(xnew, ysmooth)

enter image description here

Upvotes: 2

Mit
Mit

Reputation: 716

This is one option (not necessarily the ideal answer though):

You can try and use a polynomial approximation for the data, however you need numeric values for both you x and y axis, i've tried the below:

import pandas as pd 
import matplotlib.pyplot as plt
import numpy as np

#note i've changed the A,B,C... to 1,2,3...
data = [{1: 21, 2: 23, 3:19, 4:26,5:28,
    6:26,7:23,8:22,9:24,10:21}] 

#Creates DataFrame. 
df = pd.DataFrame(data)

#define your lists
xlist = df.columns.tolist()
ylist = df.values.tolist()
ylist = ylist[0]

#plot data
plt.figure()
poly = np.polyfit(xlist,ylist,5)
poly_y = np.poly1d(poly)(xlist)
plt.plot(xlist,poly_y)
plt.plot(xlist,ylist)
plt.show()

enter image description here

Another option could be the Spline interpolation, the s parameters will allow you to adjust the smoothness of the curve, you can test several values for s:

from scipy.interpolate import splrep, splev

plt.figure()
bspl = splrep(xlist,ylist,s=25)
bspl_y = splev(xlist,bspl)
plt.plot(xlist,ylist)
plt.plot(xlist,bspl_y)
plt.show()

enter image description here

Upvotes: 1

Related Questions