如何在 Python 中平滑图形中的线条?

4

使用以下代码,我可以画出一个有3条线的图形,但它们是角状的。是否有可能使这些线变得平滑?

import matplotlib.pyplot as plt
import pandas as pd

# Dataframe consist of 3 columns
df['year'] = ['2005, 2005, 2005, 2015, 2015, 2015, 2030, 2030, 2030']
df['name'] = ['A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C']
df['weight'] = [80, 65, 88, 65, 60, 70, 60, 55, 65]
fig,ax = plt.subplots()

# plot figure to see how the weight develops through the years
for name in ['A','B','C']:
    ax.plot(df[df.name==name].year,df[df.name==name].weight,label=name)

ax.set_xlabel("year")
ax.set_ylabel("weight")
ax.legend(loc='best')

@poke 我认为这不是同一个问题。我之前尝试过另一个问题的答案。我只是不知道为什么它不起作用,但我认为它有点不同,因为你必须在这里使用3列或数组,而另一个问题只有2个数组。 - Jolie
在绘制数据之前,您必须进行插值处理,SO上有很多示例。 - Zeugma
1个回答

10

你应该对数据进行插值,且不应该是“线性”的。这里我使用了scipy的interp1d进行“立方插值”。另外,需要注意的是,要使用立方插值,你的数据至少应该有4个点。因此,我添加了另一年2031,以及所有权重的另一个值(通过从权重的最后一个值减去1得到新的权重值):

以下是代码:

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

# df['year'] = ['2005, 2005, 2005, 2015, 2015, 2015, 2030, 2030, 2030']
# df['name'] = ['A', 'B', 'C', 'A', 'B', 'C', 'A', 'B', 'C']
# df['weight'] = [80, 65, 88, 65, 60, 70, 60, 55, 65]

df1 = pd.DataFrame()
df1['Weight_A'] = [80, 65,  60 ,59]
df1['Weight_B'] = [65, 60,  55 ,54]
df1['Weight_C'] = [88, 70,  65 ,64]
df1.index = [2005,2015,2030,2031]


ax = df1.plot.line()
ax.set_title('Before interpolation')
ax.set_xlabel("year")
ax.set_ylabel("weight")

f1 = interp1d(df1.index, df1['Weight_A'],kind='cubic')
f2 = interp1d(df1.index, df1['Weight_B'],kind='cubic')
f3 = interp1d(df1.index, df1['Weight_C'],kind='cubic')

df2 = pd.DataFrame()
new_index = np.arange(2005,2031)
df2['Weight_A'] = f1(new_index)
df2['Weight_B'] = f2(new_index)
df2['Weight_C'] = f3(new_index)
df2.index = new_index

ax2 = df2.plot.line()
ax2.set_title('After interpolation')
ax2.set_xlabel("year")
ax2.set_ylabel("weight")


plt.show()

结果如下:

插值前 插值后


哇,非常感谢你!我试了一整天来平滑这些线条,但最后放弃了。最后我只是在每个数据之间加了一个额外的点,稍微使其平滑了一点。你的代码帮了我很多,谢谢! - Jolie
@Jolie 没问题 :) - Kennet Celeste

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接