3

I have a few questions about what how to work with graphics, using Sympy.

My code:

from sympy import *
x, y = symbols("x y")
plot_implicit(Eq(x**2 + y**2, 4), (x, -3, 3), (y, -3, 3))

1) The graph is obtained stretched along the x axis.

enter image description here

How to make so that the curve looked like a circle?

2) How to add other elements to the chart. For example, the point O(0, 0) and the line y = x.

enter image description here

JohanC
  • 71,591
  • 8
  • 33
  • 66
pank
  • 803
  • 1
  • 11
  • 16

2 Answers2

5

According to the docstring of plot.py, you can get the backend wrapper of the Matplotlib axes and figure that SymPy uses, through _backend attribute, and then modify properties as any other Matplotlib objects. Check this example:

import matplotlib.pyplot as plt
import numpy as np
%matplotlib notebook
from sympy import *

x, y = symbols("x y")
hp = plot_implicit(Eq(x**2 + y**2, 4), (x, -3, 3), (y, -3, 3))
fig = hp._backend.fig
ax = hp._backend.ax
xx = yy = np.linspace(-3,3)
ax.plot(xx,yy) # y = x
ax.plot([0],[0],'o') # Point (0,0)
ax.set_aspect('equal','datalim')
fig.canvas.draw()

The Sympy Plot objects have append and extend methods that allows add a Plot object to other, but this don't work (at least for me and using Jupyter).

Another option is use only Matplotlib:

import matplotlib.pyplot as plt
import numpy as np

fig, ax = plt.subplots(1,1)
xx,yy = np.linspace(-3,3), np.linspace(-3,3)
x,y = np.meshgrid(xx,yy)
ax.contour(x, y, (x**2+y**2-4), [0]);
ax.plot([0],[0],"o")
ax.plot(xx,yy)
ax.set_aspect('equal','datalim')
  • The first option for me also not working. However, the second method is ideal! If use eval: `ax.contour(x, y, eval(str(a_symbolic_expression)), [0]);`. – pank Nov 23 '16 at 11:12
  • I don't know why, but the first method is worked for me if I add `plt.ion()` at the beginning and `plt.show(block=True)` at the end. (Python 3.6.2, matplotlib 1.1.1) – nekketsuuu Sep 03 '18 at 15:37
  • 1
    With sympy 1.7.1 I needed `ax = hp._backend.ax[0]` to get the first of a list of axes. – JohanC Jun 05 '21 at 15:39
0

Sympy's plot functions have a parameter aspect_ratio= which can be the tuple (1,1) for an equal ratio.

They also support markers= and annotations= keywords. These are lists of dictionaries towards matplotlib's plot and annotate functions.

from sympy import symbols, Eq, plot_implicit

x, y = symbols("x y")
plot_implicit(Eq(x ** 2 + y ** 2, 4), (x, -3, 3), (y, -3, 3), aspect_ratio=(1, 1),
              markers=[{'args': [0, 0], 'color': "blue", 'marker': "o", 'ms': 5},
                       {'args': [[-3, 3], [-3, 3]], 'color': "blue", 'ls': '-', 'lw': 2}],
              annotations=[{'xy': (0, 0), 'text': "  0", 'ha': 'left', 'va': 'top', 'color': 'blue'},
                           {'xy': (2, 2), 'text': "x=y ", 'ha': 'right', 'va': 'bottom', 'color': 'blue'}])

sympy plot with extra lines, markers and annotations

JohanC
  • 71,591
  • 8
  • 33
  • 66