2

The following problem has been researched - primarily with matplotlib in python.

"Basic" functions are possible, such as y = x^2, but if I want to plot an equation (which isn't necessarily a function due to multiple x-y associations), e.g.:

x^2 + y^2 = 1 (just a basic circle with a radius of 1 around the point (0/0) in a two-dimensional coordinate system).

Is there any way to plot such equation with matplotlib or any library alike?

The idea of re-writing the equation to a drawable function has come to my mind, but due to the absolute value assignment it just looks harder than the original equation, e.g. the equation above into a "function": |y| = sqrt(1-x²) with -y and +y.

//EDIT: On request from @mkrieger1 an edit of this question. The aim of my software is to use an input (given by another function; string representing any equation, e.g. "y^3-sqrt(sin(x^2)-2)*2 = 3x") and turn it into a plot. I personally failed with the approach to solve the functions for y (as mentioned previously), especially with more complex functions. Splitting these equations into "smaller pieces" is, given the broad variety of mathematical inputs, pretty hard as well, thus I thought that going with a Contour-solving approach would be the best part. (As @mkrieger1 suggested). Once again, this approach is critical due to a needed "editing" of the equation before implementing it in a plt.contour(X, Y, func, [0]), as well as a UserWarning later on.

JohanC
  • 71,591
  • 8
  • 33
  • 66
J. Doe
  • 61
  • 1
  • 2
  • 9
  • 1
    Does this answer your question? [Plot equation showing a circle](https://stackoverflow.com/questions/32092899/plot-equation-showing-a-circle) – mkrieger1 Jul 11 '20 at 18:46
  • @mkrieger1 thanks for the fast reply, but no. Unfortunately they just cover the specific case of a circle, whereas my questions aims to draw equations (with the example of a circle), but in general to plot any equation into a coordinate system where a y can't be single-associated with one x-value (like with my example). – J. Doe Jul 11 '20 at 18:48
  • Yes, it’s called a contour plot and the accepted answer to the question I've linked shows how to do one with matplotlib. You should be able to generalize this to other equations. If not, please show what you have tried and what exactly the problem was. – mkrieger1 Jul 11 '20 at 18:50
  • Matplotlib allows you to draw any sequence of x-y pairs. – Mad Physicist Jul 11 '20 at 18:54
  • @mkrieger1 sure, but still, the equation x^2 + y^2 = 1 would need to be formatted (from the given user input) into F = x^2 + y^2 - 1, which could easily (by automating) get the "standard" UserWarning for no contour levels given (in the data range). – J. Doe Jul 11 '20 at 18:59
  • @mkrieger1 Okay, maybe this all sounds confusing.. The goal is to take an input from another function. The equation (no specific formation) is being delivered within a string and can be rather complex, thus forming into a |y|-function is not applicable as mentioned previously. What I was trying to do is to take the given input and plot it right away (sounds a bit naive I guess), though even upon trying contour plotting, etc. I haven't found the "perfect" (or a good) solution. – J. Doe Jul 11 '20 at 19:02
  • Maybe you should update your question and show some specific examples of what you are trying to do, show what you have tried so far, and how it has failed. – mkrieger1 Jul 11 '20 at 19:03
  • Are you asking how to parse arbitrary equations from a string? – mkrieger1 Jul 11 '20 at 19:04
  • @mkrieger1 thanks, you're right. I hope my clarification edit is understandable. – J. Doe Jul 11 '20 at 19:11

2 Answers2

2

You can also use sympy to convert an expression in a string to an equation and then plot it. I left out the -2 of the example, as this would lead to a quite empty plot. Sympy's parser supports special functions to allow multiplication be left out (as in 3x) and to convert Python's xor function (^) to a power.

from sympy import plot_implicit, Eq
from sympy.parsing.sympy_parser import parse_expr
from sympy.parsing.sympy_parser import standard_transformations, convert_xor, implicit_multiplication

string = "y^3-sqrt(sin(x^2))*2 = 3x"
transformations = (standard_transformations + (implicit_multiplication,) + (convert_xor,))
lhs = parse_expr(string.split('=')[0], transformations=transformations)
rhs = parse_expr(string.split('=')[1], transformations=transformations)

plot_implicit(Eq(lhs, rhs))

sample plot

Another example:

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

plot_implicit(Eq(x/y, cos(y)), (x, -10, 10), (y, -10, 10))

Note that without explicitly setting the range for the variables, plot_implicit supposes default ranges between -5 and 5.

another example

JohanC
  • 71,591
  • 8
  • 33
  • 66
  • That's a genius solution! It completely nailed the description I was looking for. Thanks for your help! – J. Doe Jul 11 '20 at 19:37
0

If you use matplotlib at all, you will notice that plot accepts a pair of arrays of equal length, representing sequences of x-y pairs. It has no knowledge of functions, equations, or any of the other concepts you mention.

The assertion that plotting a simple function is supported is therefore largely meaningless, even if true. That being said, a standard approach to converting something that is a non-function in Cartesian space, like a circle, is to parametrize it. One possible parameterization for many popular non-functions is to use polar coordinates.

For example:

t = np.linspace(0, 2 * np.pi, 100)   # the parameter
x = np.cos(t)
y = np.sin(t)
Mad Physicist
  • 107,652
  • 25
  • 181
  • 264