【问题标题】:Plotted arc: anomaly in the plot绘制的弧线:图中的异常
【发布时间】:2015-08-03 18:25:30
【问题描述】:
import matplotlib.pyplot as plt
import numpy as np

def arc():
    x = np.arange((-np.pi)/4, (np.pi)/4, 0.001)

    f1 = lambda x: 3 * (np.cos(2 * x) )**0.5
    plt.vlines(0, 0, 5)
    plt.plot(x, f1(x), label = '$r=3\sqrt{\cos{2\phi}}$')

    plt.xlabel('$\phi$')
    plt.ylabel('$r(\phi)$')
    plt.legend(loc='best')


    axes = plt.gca()
    axes.set_xlim([-np.pi, np.pi])
    axes.set_ylim([0, 5])
    plt.show()

arc()

我不明白为什么它没有一直到右侧的\phi 轴。我能做些什么来解决这个问题?

【问题讨论】:

  • 请每个问题只问一个问题。

标签: python numpy matplotlib


【解决方案1】:

获得所需内容的最佳方式是使用linspace。要获得与您的示例几乎相同的向量x,您应该这样做

x = np.linspace(-np.pi/4, np.pi/4, round(np.pi / 2 / 0.001) + 1)

或者干脆

x = np.linspace(-np.pi/4, np.pi/4, npoints)

这会给您准确 npoints 点,并且保证包含开始和停止值。

使用np.arange(start, stop, step) 会为您提供start, start+step, start+2*step, ... 的点数,直到达到start+n*step < stop 的最终点数。由于浮点数不准确,最终点的n 是什么并不明显。 arangemanual备注:

当使用非整数步长时,例如 0.1,结果通常不会 始终如一。对于这些情况,最好使用 linspace。

通过生成一些 0 到 1 之间的可变步长范围,很容易证明这会导致不可预测的行为:

In [21]: for i in range(97,109):
    ...:     r = np.arange(0, 1, 1. / i)
    ...:     print 'step = 1.0 / {}, length = {}, last value = {}'.format(
    ...:         i, len(r), r[-1])
    ...:     
step = 1.0 / 97, length = 97, last value = 0.989690721649
step = 1.0 / 98, length = 99, last value = 1.0
step = 1.0 / 99, length = 99, last value = 0.989898989899
step = 1.0 / 100, length = 100, last value = 0.99
step = 1.0 / 101, length = 101, last value = 0.990099009901
step = 1.0 / 102, length = 102, last value = 0.990196078431
step = 1.0 / 103, length = 104, last value = 1.0
step = 1.0 / 104, length = 104, last value = 0.990384615385
step = 1.0 / 105, length = 105, last value = 0.990476190476
step = 1.0 / 106, length = 106, last value = 0.990566037736
step = 1.0 / 107, length = 108, last value = 1.0
step = 1.0 / 108, length = 108, last value = 0.990740740741

另请参阅this answer 的相关问题。

【讨论】:

    【解决方案2】:

    图表在右边没有一直到零的原因是因为arangestart(第一个参数)开始并添加step(第三个参数)直到它到达end (第二个参数。但是end 没有加在最后。 你应该做的是:

    x = np.concatenate((np.arange(-np.pi/4, np.pi/4, 0.001), [np.pi/4]))
    

    或使用简写np.r_

    x = np.r_[np.arange(-np.pi/4, np.pi/4, 0.001), np.pi/4]
    

    【讨论】:

    • 此解决方案可能适用于此特定问题,但在一般情况下可能会产生意外结果。正如我的示例所示,arange 的最终值可以变得非常接近停止值,例如 np.arange(0, 1, 1.0/98)[-1] - 1 == -1.11e-16,因此通过简单地连接最终值,最后 2 个点将非常接近.
    【解决方案3】:

    我变了 x = np.arange((-np.pi)/4, (np.pi)/4, 0.001)

    到:

    x = np.arange((-np.pi)/4, (np.pi)/4, 0.00001)

    我得到了

    本质上,只需更改步长以更接近曲线的末端即可。 然而,这更像是一个不该做什么的例子(我的猜测被证明是错误的)。 @Bas Swinckels 的建议更好:

    x = np.linspace(-np.pi/4, np.pi/4, npoints)

    它完全不需要将最后一个参数更改为更接近零的值,这只会使间隙更小(它不会消除间隙)。 linspace 更适合浮点不准确。

    【讨论】:

    • 是的,我确实考虑过添加 delta x 但它没有帮助,有趣的是,您的解决方案有效。一个谜。不过,谢谢。
    • 如果你放大你会发现仍然有差距。你只是把它变小了。
    • 是的,我知道,这就是为什么x = np.arange((-np.pi)/4, (np.pi)/4+0.001, 0.001) 更好。为了清楚起见,我将进行编辑
    • 没有。这又是同样的问题。我在回答中解释了 arange 的工作原理。
    猜你喜欢
    • 1970-01-01
    • 2014-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-06
    • 1970-01-01
    • 1970-01-01
    • 2014-05-28
    相关资源
    最近更新 更多