简体   繁体   中英

In sympy plotting, how can I get a plot with a fixed aspect ratio?

If I plot a circle with this snippet

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

I will get a figure window like this one

在此处输入图片说明

Now the aspect ratio is not what I was expecting because I see an ellipse instead of a circle. Moreover, if I change the aspect ratio of the window (dragging the bottom-right corner of the window) I get also a change in the aspect ratio of the plot... The following image is what I get after dragging the corner in order to see a circle:

在此处输入图片说明

I would like to get a plot like the one you get in Matlab when you set axis equal , see http://it.mathworks.com/help/matlab/creating_plots/aspect-ratio-for-2-d-axes.html when you plot an ellipse

在此处输入图片说明

What am I missing?

I am using Jupyter and the version of the notebook server is 4.1.0 and is running on: Python 2.7.11 |Anaconda 2.5.0 (64-bit)| (default, Dec 6 2015, 18:08:32) [GCC 4.4.7 20120313 (Red Hat 4.4.7-1)]

I'm not sure if this is covered in Sympy's stable API, but you can extract matplotlib's figure and axis instance and the use standard matplotlib calls to change the appearance of your plot:

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)

This gives: 纵横比相等的紧轴

now in Sept 2019 this code works:

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()

Within the help for plot_implicit , the x_var and y_var -arguments are mentioned. Using them allows you to manually set limits to the x and y axis. If you scale those limits appropriately, you can achieve an even aspect ratio.

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))

(My Sympy-version: 1.1.1)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM