我想绘制一些实验数据的图表,这些数据以相对较高的速率采样,但使用以相等弧长间隔间隔的标记来近似平滑曲线,如下图所示:
我知道markevery
绘图的论点,但这会将绘图右侧的标记聚集在一起,并且左侧的标记可能很少。解决方案应该独立于 x 和 y 轴上的比例。我愿意安装其他模块,但它应该是 python+matplotlib 解决方案。
我想绘制一些实验数据的图表,这些数据以相对较高的速率采样,但使用以相等弧长间隔间隔的标记来近似平滑曲线,如下图所示:
我知道markevery
绘图的论点,但这会将绘图右侧的标记聚集在一起,并且左侧的标记可能很少。解决方案应该独立于 x 和 y 轴上的比例。我愿意安装其他模块,但它应该是 python+matplotlib 解决方案。
我想我已经提出了一个比较好的解决方案。唯一的问题是以某种方式考虑数据比率,该方式还使用有关最终绘图的纵横比的信息。我还没有找到一个可靠的方法来做到这一点,虽然这个函数会接受一个数据比率,所以你可以玩直到输出看起来正确:
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')
结果:
从 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()