【问题标题】:In sympy plotting, how can I get a plot with a fixed aspect ratio?在 sympy 绘图中,如何获得具有固定纵横比的绘图?
【发布时间】:2016-04-08 17:26:43
【问题描述】:

如果我用这个 sn-p 画一个圆

from sympy import *
x, y = symbols('x y')        
p1 = plot_implicit(Eq(x**2 +y**2, 1),aspect_ratio=(1.,1.))

我会得到一个像这样的图形窗口

现在纵横比不是我所期望的,因为我看到的是椭圆而不是圆形。此外,如果我改变 window 的纵横比(拖动窗口的右下角),我也会改变绘图的纵横比......下图是我拖动角后得到一个圆圈:

当你设置axis equal 时,我想得到一个像你在 Matlab 中得到的那样的绘图,当你绘制一个椭圆时,请参见 http://it.mathworks.com/help/matlab/creating_plots/aspect-ratio-for-2-d-axes.html

我错过了什么?

我正在使用 Jupyter,笔记本服务器的版本是 4.1.0,并且正在运行:Python 2.7.11 |Anaconda 2.5.0 (64-bit)| (默认,2015 年 12 月 6 日,18:08:32)[GCC 4.4.7 20120313 (Red Hat 4.4.7-1)]

【问题讨论】:

  • 我试过window2010python 2.7.xsympy 1.0,和你的问题一样。我想知道python 2.7sympy 1.0 中是否有bug。我没有python 3.x,但需要尝试一下

标签: python plot sympy


【解决方案1】:

我不确定这是否包含在 Sympy 的稳定 API 中,但您可以提取 matplotlib 的图形和轴实例,并使用标准的 matplotlib 调用来更改绘图的外观:

import matplotlib.pyplot as plt
import sympy as sy

x, y = sy.symbols('x y')
p1 = sy.plot_implicit(sy.Eq(x**2 +y**2, 4))
fg, ax = p1._backend.fig, p1._backend.ax  # get matplotib's figure and ax

# Use matplotlib to change appearance: 
ax.axis('tight')  # list of float or {‘on’, ‘off’, ‘equal’, ‘tight’, ‘scaled’, ‘normal’, ‘auto’, ‘image’, ‘square’}
ax.set_aspect("equal") # 'auto', 'equal' or a positive integer is allowed
ax.grid(True)
fg.canvas.draw()


plt.show()  # enter matplotlib's event loop (not needed in Jupyter)

这给出:

【讨论】:

  • 能否请您写下您的Python环境的版本?我测试了你的代码,我得到的情节与你所附的情节不同。谢谢。
  • @AlessandroJacopson 我正在使用 Debian/Sid 和 matplotlib 1.5、ipython 2.4、Sympy 0.7.6.1 和 python 2.7/3.5。我重新运行它并在使用 pylab (在 ipython shell 中的%pylab 或 --pylab 作为参数)时得到了预期的结果,但在不使用它时却没有。我对可能的原因有点不知所措。
  • 在 Sympy 1.0 中它不起作用... plot.py 中的函数 show() 调用 self.plt.show() 而不是 self.fig.show()。快速解决方法/测试将 plt 替换为 fig 给出预期结果。
【解决方案2】:

现在在 2019 年 9 月,此代码有效:

import matplotlib.pyplot as plt
import sympy

x, y = sympy.symbols('x y')

plt.ion() #interactive on 

p1 = sympy.plot_implicit(sympy.Eq(x**2 +y**2, 4), block = False)

fg, ax = p1._backend.fig, p1._backend.ax  # get matplotib's figure and axes

# Use matplotlib to change appearance:
ax.axis('tight')  # list of float or {‘on’, ‘off’, ‘equal’, ‘tight’, ‘scaled’, ‘normal’, ‘auto’, ‘image’, ‘square’}
ax.set_aspect("equal") # 'auto', 'equal' or a positive integer is allowed
ax.grid(True)
plt.ioff() #interactive off
plt.show()

【讨论】:

  • 感谢您提供此代码 sn-p,它可能会提供一些有限的短期帮助。一个正确的解释would greatly improve 它的长期价值通过展示为什么这是一个很好的解决问题的方法,并将使它对未来有其他类似问题的读者更有用。请edit您的回答添加一些解释,包括您所做的假设。
  • 它对我不起作用 AttributeError: 'Plot' object has no attribute '_backend'
【解决方案3】:

plot_implicit 的帮助中,提到了x_vary_var 参数。使用它们可以手动设置 x 和 y 轴的限制。如果您适当地调整这些限制,您可以实现均匀的纵横比。

from sympy import *

x, y = symbols('x y')

scal = 3840/2400 # corresponds to your screen resolution
a = 1.05

p1 = plot_implicit(Eq(x**2+y**2,1),title='with xlim and ylim\n',\
                   xlim=(-1,1), ylim=(-1,1),aspect_ratio='equal')

p2 = plot_implicit(Eq(x**2+y**2,1),title='with x_var and y_var\n',\
                   x_var=(x,-a*scal,a*scal), y_var=(y,-a,a))

(我的 Sympy 版本:1.1.1)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-26
    • 2013-05-01
    • 2012-05-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多