Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

python

plot

sympy

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

enter image description here

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:

enter image description here

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

enter image description here

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

like image 743
Alessandro Jacopson Avatar asked Apr 08 '16 17:04

Alessandro Jacopson


People also ask

What is Matplotlib aspect ratio?

The aspect ratio of a matplotlib plot refers to the aspect of the axis scaling, i.e. the ratio of y-unit to x-unit. This ratio can be modified by using the matplotlib. axes. Axes. set_aspect() function.

Which module is used for plotting plots in Matplotlib?

While Matplotlib contains many modules that provide different plotting functionality, the most commonly used module is pyplot.


2 Answers

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: Tight Axis with equal aspect ratio

like image 54
Dietrich Avatar answered Oct 19 '22 23:10

Dietrich


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()
like image 40
Erhy Avatar answered Oct 19 '22 23:10

Erhy