【问题标题】:How can I smoothen a line chart in matplotlib?如何平滑 matplotlib 中的折线图?
【发布时间】:2021-09-06 06:34:36
【问题描述】:

我已经尝试了所有方法并查看了此处的其他线程,但我找不到如何平滑 matplotlib 图表中的线条。问题是,在大多数教程中,两个轴都有数值,而在我的情况下,对于我的 x 轴,我有一个日期值......

这可能吗?如果没有,是否有任何其他可视化库可以让我这样做?

这是我的代码:

date = ["Jan", "Feb", "Mar", "Apr", "May"]
value = [4,12,15,7,25]
plt.plot(date,value)

plt.show() 

目前正在输出这个:

我想这样展示它:

非常感谢!

【问题讨论】:

  • 这能回答你的问题吗? Plot smooth line with PyPlot
  • No :( 也许我有点愚蠢,但这是我尝试过的线程之一。由于我的 X 值是定性的(日期),因此代码给了我这个错误:ValueError :无法将字符串转换为浮点数:'Jan'
  • 您或许可以先将月份转换为数字?另外这个问题似乎与熊猫无关,所以我删除了标签。如果这个问题有熊猫方面的问题,请edit您的问题反映这一点并添加标签。
  • 可能在数据上运行一些代码,在每个数据点之间创建点,从而将其平滑。
  • 您可以只使用数字0, 1, 2, ... 来表示样条函数。例如。 date_num=np.arange(len(date))。绘制曲线后调用`plt.xticks(date_num, date)`

标签: python matplotlib data-visualization


【解决方案1】:

我撤回了我的近距离投票,因为我错过了您在 x 轴上针对字符串进行绘图的问题(因此在它们之间进行插值更加困难)。正如其他人所建议的那样,关键是使用您的日期字符串来获取用于绘图和插值的数字。一旦你这样做了,this answer 仍然是一个很好的框架。

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

# original data
date = ["Jan", "Feb", "Mar", "Apr", "May"]
value = [4,12,15,7,25]

# create integers from strings
idx = range(len(date))
xnew = np.linspace(min(idx), max(idx), 300)

# interpolation
spl = make_interp_spline(idx, value, k=3)
smooth = spl(xnew)

# plotting, and tick replacement
plt.plot(xnew, smooth)
plt.xticks(idx, date)

idx(0, 1, 2, 3, 4)的值,用于绘图和插值。最后,对xticks 的调用用于使用日期字符串来标记这些刻度位置。

以上主要基于cmets(来自HenryEckerJohanC)。我想添加的新内容是另一种插值方法是将字符串转换为实际的日期时间:

import matplotlib.dates as mdates # for formatting
import matplotlib.pyplot as plt
from scipy.interpolate import make_interp_spline
import pandas as pd # for working with dates

# instead of ["Jan", "Feb", "Mar", "Apr", "May"], create datetime objects
date = pd.date_range('01-01-2020', freq='MS', periods=5)
# DatetimeIndex(['2020-01-01', '2020-02-01', '2020-03-01', '2020-04-01', '2020-05-01'], dtype='datetime64[ns]', freq='MS')

value = [4,12,15,7,25]

# now make new x positions using a date range, instead of linspace 
# see here: https://stackoverflow.com/a/50728640/13386979
xnew = pd.date_range(date.min(), date.max(), periods=300)

# interpolation
spl = make_interp_spline(date, value, k=3)
smooth = spl(xnew)

# plotting
plt.plot(xnew, smooth)

# using mdates to get the x-axis formatted correctly
months = mdates.MonthLocator()
fmt = mdates.DateFormatter('%b') # %b -> Month as locale’s abbreviated name
ax = plt.gca()
ax.xaxis.set_major_locator(months)
ax.xaxis.set_major_formatter(fmt)

后一种方法涉及一些额外的格式化工作(和导入),但它在绘制时间数据方面更加明确。我发现这可以更直观地使用。例如,如果您有多个时间序列,您可以轻松地将它们并排绘制;您可以在代码中更轻松地引用特定日期;您不必记住哪些索引指的是哪些日期(例如,本例中为 March 和 2)等...

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-16
    • 1970-01-01
    相关资源
    最近更新 更多