3

I am testing an optimization algorithm and would like to view the decision variable as it evolves on a plot of the cost function and constraints. For example, the following code:

import matplotlib.pyplot as plt
from sympy import symbols, plot_implicit
from sympy.plotting.plot import Plot, ContourSeries
from sympy.utilities.lambdify import lambdify

(x1, x2) = symbols('x1 x2')

func = x1**4 + x2**4

p1 = Plot(ContourSeries(func,(x1,-1,5),(x2,-1,5)))
p1.extend(plot_implicit(x1 < 0,(x1,-1,5),(x2,-1,5),line_color='red',show=False))
p1.extend(plot_implicit(x2 < 2,(x1,-1,5),(x2,-1,5),line_color='red',show=False))

p1.show()

produces a contour plot of a cost function, and shows some constraints as a red area, but how would I add a single point to this plot? The following:

x1 = [4,4]
x2 = [4,4]
plt.scatter(x1,x2)

creates a new, separate plot.

SeBeast
  • 47
  • 5
  • Sympy's `plot` has a `markers=` parameter which could help here. See [How do I use the markers parameter of a sympy plot?](https://stackoverflow.com/questions/71469474/how-do-i-use-the-markers-parameter-of-a-sympy-plot). E.g. `Plot(ContourSeries(func,(x1,-1,5),(x2,-1,5)), markers=[{'args': [[4,4], [4,4], 'ro']}])` – JohanC Mar 15 '22 at 15:58

2 Answers2

0

This doesn't seem to actually be supported by sympy, but the following does work:

p1._backend.ax.scatter(x1, x2)
p1._backend.save('im.png')

enter image description here

ngoldbaum
  • 5,430
  • 3
  • 28
  • 35
  • Thank you for this! Is it possible to explain the use of _backend here please? – SeBeast May 15 '18 at 09:27
  • I have just tried this, and the scatter appears in the saved image 'im.png', but is not present in the image displayed by Python. Is there any other way of adding the scatter plot so that it is viewable at the time it is created? – SeBeast May 15 '18 at 09:55
  • like I said, this doens't seem to be supported by sympy. My use of `_backend` is making use of private implementation details. Given the way the plotting code is written I don't think there's an easy way to get what you want using just the sympy plotting code. – ngoldbaum May 16 '18 at 04:06
0

Plot.show() calls matplotlib.pyplot.show() (source code), which seems to block modifications to the backend object.

However, in an iPython notebook, just creating the backend object triggers rendering, and you can modify the plot as shown above:

import sympy

x = sympy.Symbol('x')
expr = x**2
xs = range(0, 10)
ys = list(map(lambda n: n**2, xs))

p1 = sympy.plot(expr, show=False)
p1._backend = p1.backend(p1)
p1._backend.process_series()
p1._backend.ax[0].scatter(xs, ys, marker='x', color='r')