【问题标题】:Plotting functions at a specific y-interval以特定 y 间隔绘制函数
【发布时间】:2014-02-09 21:17:36
【问题描述】:

我需要在同一个图上绘制几条指数曲线 - 约束条件是图在 y=1 处结束。

供参考,代码如下:

from numpy import arange
from matplotlib import pyplot as plt

T = arange(60,89)
curve1 = 2**(T - 74)
curve2 = 2**(T - 60)
plt.plot(T,curve1 )
plt.plot(T,curve2 )
plt.show()

结果如下: 第二条曲线几乎看不到,因为值相对较低。

我遇到的问题是所有这些曲线都相当迅速地上升到 700000+,但我只对 (0,1) 的范围感兴趣。我如何仅绘制这些位,但具有良好的平滑曲线(这样一条曲线不会只在中途停止)?

【问题讨论】:

  • 您只是在问如何设置绘图的 y 限制吗?或者如何仅绘制小于 1 的曲线部分? (即plt.plot(T[data < 1], data[data < 1]) vs plt.ylim([0, 1])
  • 我只想要小于 1 的曲线部分,但没有任何曲线突然停止。
  • 您只想对这些特定曲线执行此操作吗?还是您在寻找通用方法?
  • @goncalopp 一个通用的方法会很好,但我现在只设置 plt.ylim([0,1]) 。
  • 将来,如果您发布一个完整的工作代码示例,那就太好了。目前,您的代码由于多种原因而失败,succsucc1 未定义,T 不是 numpy 数组,因此无法像在T-74 中那样操作,等等......它也是不是minimial,我们真的需要看图例来回答这个问题吗?它还有助于拼写检查标题:)

标签: python matplotlib exponentiation


【解决方案1】:

如您所见,如果您为添加的每个函数调整范围 (T),这很容易做到。但是,如果您需要更改功能,则需要重新检查。

一般来说,您要处理的问题是在给定 y 范围的情况下计算某些函数的 x 范围 - 或者,正如数学家所说,确定与范围相对应的函数的 domain其形象。虽然,对于任意函数,这是不可能的,但如果你的函数是 injective,这是可能的,就像这种情况一样。

假设我们有一个函数y=f(x),yrange 是[y1,y2]。 x 范围将是 [f^(-1)(y1), f^(-1)(y2]f^-1 是 f 的 inverse function

由于我们需要绘制多个函数,因此 x_range 只是最大范围 - 在所有范围中 - 最终范围的下部是所有范围下部中的最小值,而上部是上部的最大值。

这里有一些代码可以举例说明这一切,将步数作为参数,并在 x 范围内计算正确的 T

from numpy import arange
from matplotlib import pyplot as plt
from sympy import sympify, solve

f1= '2**(T - 74)' #note these are strings
f2= '2**(T - 60)'

y_bounds= (0.001, 1) #exponential functions never take 0 value, so we use 0.001
mm= (min, max)
x_bounds= [m(solve(sympify(f+"-"+str(y)))[0] for f in (f1,f2)) for y,m in zip(y_bounds, mm)]
print x_bounds

N_STEPS=100 #distributed over x_bounds
T = arange(x_bounds[0], x_bounds[1]+0.001, (x_bounds[1]-x_bounds[0])/N_STEPS)

curve1 = eval(f1) #this evaluates the function over the range, by evaluating the string as a python expression
curve2 = eval(f2)
plt.plot(T,curve1)
plt.plot(T,curve2)
plt.ylim([0,1])
plt.show()

代码输出 x 范围 (50.03, 74) 和此图:

【讨论】:

  • 谢谢!这正是我要找的!
【解决方案2】:

这个真的很简单:很抱歉浪费了时间。

只需将 y 限制设置为 [0,1] 通过

plt.ylim([0,1])

你就完成了。

【讨论】:

  • 我不认为你应该道歉,在这个问题中有一个不小的问题:如何选择合适的范围(你的T)使得曲线平滑并且没有浪费的计算.如果您想要一个通用方法,使用 sympy 评估表达式可能是要走的路
  • @goncalopp 理想情况下,这就是我想要的 - 这只是在 1 之后切断曲线,破坏了我所期待的曲线的平滑度。
  • 您将通过绘制更多点来获得“更平滑”的曲线 - 因为只有 100 个绘图点它的跳跃如此之快,所以除了阶跃函数之外不可能以任何其他方式看到过渡。跨度>
  • @Hooked 100 分绝对足够绘制这些函数,如果你好好利用它们。没有必要绘制函数未定义或超出绘图范围的区域(请参阅我的答案)
  • @goncalopp 是的,100 分就足够了,如果你知道如何充分利用它们。先验地,您通常不知道函数在哪里发生变化,并且您不能总是依靠分析(sympy)解决方案来解决它。使用更多点的建议是因为绘制 100 点与 1000 点之间的时间差(通常)可以忽略不计。一旦你对函数增长有了一定的了解,你当然可以对其进行优化。
【解决方案3】:

除了其他答案之外,可能值得在对数尺度上绘制,因为函数的增长本质上是指数级的。例如:

from numpy import arange
from matplotlib import pyplot as plt

T = arange(60,89)
curve1 = 2**(T - 74)
curve2 = 2**(T - 60)
plt.semilogy(T,curve1 )
plt.semilogy(T,curve2 )
plt.show()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-12-12
    • 1970-01-01
    • 2022-01-02
    • 2011-01-09
    • 2013-11-22
    • 1970-01-01
    • 2019-04-14
    • 1970-01-01
    相关资源
    最近更新 更多