【问题标题】:Plotting a curve with equidistant (arc-length) markers绘制具有等距(弧长)标记的曲线
【发布时间】:2014-09-16 01:40:44
【问题描述】:

我想绘制一些实验数据的图表,这些数据以相对较高的速率采样,但使用以相等弧长间隔间隔的标记近似平滑曲线,如下图所示:

我知道绘图的 markevery 参数,但这会将绘图右侧的标记聚集在一起,并且左侧的标记可能很少。解决方案应该独立于 x 和 y 轴上的比例。我愿意安装额外的模块,但它应该是 python+matplotlib 解决方案。

【问题讨论】:

  • 你有这个曲线/函数的代数公式吗?我认为有必要使用它的导数来计算弧长(很可能使用迭代解决方案)
  • 不,正如我提到的,曲线是实验的结果。不过,导数的数值近似应该没问题,尽管测量中有一点噪音我可以很容易地消除它。

标签: python matplotlib


【解决方案1】:

我认为我已经提出了一个比较好的解决方案。唯一的问题是以某种方式考虑数据比率,该方式还使用有关最终绘图的纵横比的信息。我还没有找到一个可靠的方法来做到这一点,虽然这个函数会接受一个数据比例,所以你可以玩直到输出看起来正确:

def spacedmarks(x, y, Nmarks, data_ratio=None):
    import scipy.integrate

    if data_ratio is None:
        data_ratio = plt.gca().get_data_ratio()

    dydx = gradient(y, x[1])
    dxdx = gradient(x, x[1])*data_ratio
    arclength = scipy.integrate.cumtrapz(sqrt(dydx**2 + dxdx**2), x, initial=0)
    marks = linspace(0, max(arclength), Nmarks)
    markx = interp(marks, arclength, x)
    marky = interp(markx, x, y)
    return markx, marky

使用示例(这个适用于iPython中的pylab模式):

x = linspace(0, 10*pi, 1000)
y = sin(x*2) + sin(x+1)

plot(x, y)
markx, marky = spacedmarks(x, y, 80)
plot(markx, marky, 'o', color='blue')

结果:

【讨论】:

【解决方案2】:

从 matplotlib 1.4 开始,您可以使用带有实数的 markevery 来实现这一点。

文档:http://matplotlib.org/api/lines_api.html#matplotlib.lines.Line2D.set_markevery

例子:

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 10*np.pi, 1000)
y = np.sin(x*2) + np.sin(x + 1)

plt.plot(x, y, marker='o', markevery=0.05)

plt.show()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多