Andrew
Andrew

Reputation: 2157

How to make my plot smoother with my data?

I have such data:

[38, 54, 38, 52, 36, 49, 34, 45, 31, 52, 36, 51, 36, 49, 34, 46, 32, 42, 30, 52, 36, 51, 36, 49, 34, 46, 32, 42, 30, 56]

which I draw by this way:

plt.plot(x_arr, linewidth=1)
plt.show()

and receive such plot:

enter image description here

is it possible to make this plot smoother ? I tried to use

np.linspace

and such example also. But I received such error:

ValueError: Expect x to be a 1-D sorted array_like.

maybe I did smth wrong or I have to use another way for smoothing? This data I can't change because they were received from my experiments :(

Upvotes: 0

Views: 397

Answers (3)

benG
benG

Reputation: 11

If all you want is less "edgy" lines, then you could apply a quadratic spline interpolation like this

import matplotlib.pyplot as plt
import numpy as np
import scipy.interpolate as interpolate

# Define data and x-axis
data = [38, 54, 38, 52, 36, 49, 34, 45, 31, 52, 36, 51, 36, 49, 34, 
        46, 32, 42, 30, 52, 36, 51, 36, 49, 34, 46, 32, 42, 30, 56]
x_axis = np.arange(0, len(data))

# Spline interpolation
f = interpolate.interp1d(x_axis, data, kind = 'quadratic')
x_spline = np.linspace(0, len(data) - 1, 1000)

# Plot stuff
plt.figure()
plt.plot(x_axis, data, 'k.', label = 'Data')
plt.plot(x_spline, f(x_spline), 'k--', label = 'Spline interpolation')
plt.xlabel('x')
plt.ylabel('y')
plt.legend()
plt.show()

This gives the following plot: spline interpolation

You should however be careful using this as it does not necessarily represent your data in a good way.

Upvotes: 1

Oli
Oli

Reputation: 2602

For controlling the amount of smoothing, you can use a Gausian filter:

from matplotlib import pyplot as plt
import numpy as np
import scipy.ndimage

y = np.array([38, 54, 38, 52, 36, 49, 34, 45, 31, 52, 36, 51, 36, 49, 34, 46, 32, 42, 30, 52, 36, 51, 36, 49, 34, 46, 32, 42, 30, 56])
x = np.arange(y.shape[0])


plt.plot(x, y, label='original')

interp_x = np.linspace(np.min(x), np.max(x), 200)
interp_y = np.interp(interp_x, x, y)
for smoothing in (0.5, 1, 2, 10): # choose a smoothing value that works for your data
    smoothed_y = scipy.ndimage.gaussian_filter(interp_y, smoothing)
    
    plt.plot(interp_x, smoothed_y, label='smoothing='+str(smoothing))
plt.legend()
plt.show()

plot showing smoothed data

Upvotes: 1

Cheukting
Cheukting

Reputation: 264

I am suspect that you get that error because you are using the build-in list instead of a NumPy array. To achieve what you want to do with your data, it should be like this:

import matplotlib.pyplot as plt
import numpy as np
from scipy.interpolate import make_interp_spline

y=np.array([38, 54, 38, 52, 36, 49, 34, 45, 31, 52, 36, 51, 36, 49, 34, 46, 32, 42, 30, 52, 36, 51, 36, 49, 34, 46, 32, 42, 30, 56])
x=np.array(list(range(len(y_arr))))

X_Y_Spline = make_interp_spline(x, y)

X_ = np.linspace(x.min(), x.max(), 500)
Y_ = X_Y_Spline(X_)

plt.plot(X_, Y_)
plt.show()

example output

Notice the following:

  • the data you provided are the y-values
  • using the np.array instead of the Python building list in x and y

Upvotes: 2

Related Questions