Pandas / Matplotlib - сглаживать линейный график из нескольких столбцов DataFrame - PullRequest
1 голос
/ 27 апреля 2020

Я хотел бы сгладить простой линейный график с фиктивными данными в DataFrame. Я знаю о интерполяции , но все учебники работают с более простыми numpy массивами; Мне бы хотелось, чтобы каждая из строк, сгенерированных столбцами, была гладкой. Если кто-то имеет опыт или знает, как это сделать, был бы очень признателен.

Для справки приведем некоторый код и полученный график.

# amps

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

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

# wp

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

, который выдает:

         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

Затем я строю столбцы, устанавливая ось x на «Issues», а метку y на «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()

И результирующий график генерируется.

enter image description here

1 Ответ

1 голос
/ 27 апреля 2020

Как вы сказали, вам нужно интерполировать кривые, чтобы увеличить разрешение. Таким образом, вы можете сохранить известные значения ваших данных, в то же время эффективно сглаживая кривые. Чтобы сделать это, вы можете использовать одномерную интерполяцию scipy: interp1d .

Мы хотим интерполировать большее число x-координат, чем у нас, но проблема в том, что у вас есть строки вместо чисел как независимые переменные ваших left, right и concorde "функций". Чтобы решить эту проблему, мы можем просто отобразить ваш столбец issue в монотонно увеличивающийся числовой вектор, затем интерполировать в новый вектор с предельными значениями, взятыми из него, и, наконец, сохранить метки x в виде строк.
Обновленный код может быть :

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()

Результат: enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...