0

I have implemented this Heart curve (Wolfram Mathworld) via an implicit function script I found here Plot implicit equations in Python 3

import matplotlib.pyplot as plt
import numpy as np

delta = 0.025
xrange = np.arange(-2, 2, delta)
yrange = np.arange(-2, 2, delta)
X, Y = np.meshgrid(xrange,yrange)

# F is one side of the equation, G is the other
F = X**2
G = 1- (Y - (np.abs(X))**(2/3))**2
plt.contour((F - G), [0])
plt.show()

How would I extract the resulting array of x,y pairs defining this curve?

Mr. T
  • 11,960
  • 10
  • 32
  • 54
shoggananna
  • 545
  • 5
  • 9

2 Answers2

3

One could say this is "cheating" a bit, but a rough, concise recipe can be getting points in the mesh that roughly satisfy the condition and getting their coordinates as follows:

# subset points that are very close to satifying the exact condition
# and get their indices
x_id, y_id = np.nonzero(abs(F-G) < 8e-3)
# get coordinates corresponding to the indices
plt.scatter(xrange[x_id], yrange[y_id])

xrange[x_id], yrange[y_id] are the desired arrays of coordinates.

Davide Fiocco
  • 5,350
  • 5
  • 35
  • 72
2

I'm not really a matplotlib user and there may be much, much better ways of doing what you ask - so please wait and see if someone comes up with a proper answer...

However, for the moment, you appear to be plotting the array F-G, so I saved that as a TIF (because it can store floats) using PIL like this:

from PIL import Image

...
your code
...

contour = (F-G).astype(np.float32)
Image.fromarray(contour).save('contour.tif')

that gives this:

enter image description here

Inspection of contour shows that the range is -1 to 16:

print(contour.min(), contour.max())
-1.0 15.869446307662544

So, I deduce that your points are probably the ones near zero:

points = (contour>-0.1) & (contour<0.1)

enter image description here

So, I can get the list of X,Y with:

Y, X = np.where(points)
Mark Setchell
  • 191,897
  • 31
  • 273
  • 432