5

I know matplotlib could plot an ellipse according to its center, semi-major axis length,semi-minor axis length and the angle between x-axis and major axis. But is there any easy way to plot an ellipse according to its general equation just like Matlab:

ezplot('3*x^2+2*x*y+4*y^2 = 5')

I find a way to calculate the center, semi-major axis length,semi-minor axis length and the angle between x-axis and major axis from the general formula. This is the website: link. I use this method and write a function to calculate parameters. Because I'm dealing with the data by drawing the ellipse.The experimental data give me the general equation of the ellipse.I would loop many times (for example, 500) and plot 500 ellipses on a single graph.If you do this every time before plotting, it slows the program down.So I'm looking for whether python provides a way to draw an ellipse directly from the general equation of the ellipse instead of calculating the parameters every time.

Thanks!

Cowflu
  • 332
  • 2
  • 12
Marcus
  • 199
  • 1
  • 13
  • 1
    I like the question but what have you tried so far? – Mr. T Jan 14 '20 at 13:43
  • Sorry for I didn't add what I have tried so far. I have added what I have tried and why I want to find a easy way to plot ellipse according to its general equation. Thanks. – Marcus Jan 14 '20 at 14:18

1 Answers1

5

With sympy, you just do:

from sympy import plot_implicit, Eq
from sympy.abc import x, y

plot_implicit (Eq(3*x**2+2*x*y+4*y**2, 5))

Note that Python needs ** for the power function, as ^ is reserved to bitwise xor. The expression can either be written as 3*x**2+2*x*y+4*y**2 - 5 or using the equation operator Eq(3*x**2+2*x*y+4*y**2, 5).

Extra parameters to plot_implicit can set the ranges for x and y as in plot_implicit (3*x**2+2*x*y+4*y**2 - 5, (x, -2, 2), (y, -2, 2)).

Alternatively, to get something more fancy, matplotlibs imshow can draw a complete area in x,y colored by a z-value. Choosing a diverging colormap, the ellipse will show up at the central z-value indicated by a diverging norm.

import numpy as np
from matplotlib import pyplot as plt
import matplotlib.colors as mcolors

xmin, xmax = -2, 2
ymin, ymax = -2, 2
x, y = np.meshgrid(np.linspace(xmin, xmax, 500), np.linspace(ymin, ymax, 500))
z = 3*x**2+2*x*y+4*y**2

divnorm = mcolors.DivergingNorm(vmin=z.min(), vcenter=5, vmax=z.max())

#plt.contourf(x, y, z, levels=15, norm=divnorm, cmap='seismic')
plt.imshow(z, interpolation='bilinear', norm=divnorm, cmap='seismic', origin='lower', extent=[xmin, xmax, ymin, ymax])

plt.colorbar()
plt.show()

example plot

JohanC
  • 71,591
  • 8
  • 33
  • 66
  • 1
    You can add the bounds of x and y for better framing. `plot_implicit (3*x**2+2*x*y+4*y**2 - 5, (x, -2, 2), (y, -2, 2))` – James Jan 14 '20 at 14:20