1

I would like to smooth out a simple line graph with dummy data in a DataFrame. I'm aware of interpolate but all of the tutorials work with simpler numpy arrays ; i would like each of the lines generated by the columns to be smooth. If anyone has experience, or knows how to do this, would be greatly appreciated.

For reference, here is some code, and the resulting graph.

# amps

df=pd.read_csv("~/data/poli.csv")

#################################

# wp

wave = (df.right + df.left)**2
df['concord'] = wave
print(df)

which outputs:

         issue  right  left  concord
0      end div      1     1        4
1    for trump      1    -1        0
2  aisle cross      1     1        4
3      for blm     -1     1        0
4   help world      1     1        4
5      service      1     1        4
6    community      1     1        4

Then I plot the columns, setting the x axis to 'issues', and the y label to 'score'

plot = df.plot(x='issue',
             linewidth=9,
             alpha=0.36)

plot.set_ylabel('score')
plot.set_xlabel('issues')
plot.legend(bbox_to_anchor=(1, 1), loc='upper left', ncol=1)

concord=df['concord'].values
left=df['left'].values
right=df['right'].values

plt.show()

And the resulting plot is generated.

enter image description here

1
  • Smoothing each curve will inherently require additional data points at intermediate x values to be generated. These points will not correspond to either of the categories you currently have. Therefore, you will have to first smooth each column (splines should do?), plot them against a linearly increasing x axis (say, 0 to 30, depending on how many points your smoothing produces), and finally manually adjust the ticks so that each extremum corresponds to an entry in your first column. Commented Apr 27, 2020 at 7:05

1 Answer 1

2

As you said, you need to interpolate the curves to increase resolution. This way, you can keep the known values of your data while still effectivily smoothing the curves. To do that, you could use scipy's one dimensional interpolation: interp1d.

We want to interpolate to a bigger number of x-coordinates than we have, but the problem here is that you have strings instead of numbers as independent variables of your left, right, and concorde "functions". To solve this we can simply map your issue column into a monotonically increasing numerical vector, then interpolate in a new vector with limit values taken from it, and finally keep the x-labels as strings.
The updated code could be:

import numpy as np
import pandas as pd
from scipy import interpolate
import matplotlib.pyplot as plt

d = {
     'issue': ['end div', 'for trump', 'aisle cross', 'for blm', 'help world',
     'service', 'community'],
     'right': [1, 1, 1, -1, 1, 1, 1],
     'left': [1, -1, 1, 1, 1, 1, 1],
     'concord': [4, 0, 4, 0, 4, 4, 4]
     }
df = pd.DataFrame.from_dict(d)

x = df['issue'].values
concord = df['concord'].values
left = df['left'].values
right = df['right'].values

n = len(x)
x_map = np.arange(0,n)
dx = 0.1
x_int = np.arange(0, n - 1, dx)  # vector where we interpolate

# We create the interpolants our three datasets separately:
f_concord = interpolate.interp1d(x_map, concord, 'quadratic')
f_left = interpolate.interp1d(x_map, left, 'quadratic')
f_right = interpolate.interp1d(x_map, right, 'quadratic')

# And interpolate in the resampled x-coordinates:
concord_int = f_concord(x_int)
left_int = f_left(x_int)
right_int = f_right(x_int)

# Finally, plot the interpolated data:
fig, ax = plt.subplots()
ax.plot(x_int, right_int, lw = 9, alpha = 0.36, label = 'right')
ax.plot(x_int, left_int, lw = 9, alpha = 0.36, label = 'left')
ax.plot(x_int, concord_int, lw = 9, alpha = 0.36, label = 'concord')
ax.set_xlabel('issues')
ax.set_ylabel('score')
# Set the correct xticks
ax.set_xticks(x_map)
ax.set_xticklabels(x)
fig.legend(bbox_to_anchor=(0.7, 0.3), loc='upper left', ncol=1)
fig.show()

The result: enter image description here

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.