# The `Curve`

and its operations#

In GraphingLib, all curves are objects which are instances of the `Curve`

class. You can create a curve in two ways. The first is to create a curve from lists (or numpy arrays) of x and y values, and the second is to create a curve from a function.

```
# Create a curve from lists of x and y values
x_values = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
y_values = [0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
curve_1 = gl.Curve(x_values, y_values, line_style="--")
# Create a curve from a function
curve_2 = gl.Curve.from_function(lambda x: -20 * (x - 5) ** 2 + 400, x_min=0, x_max=10)
fig = gl.Figure()
fig.add_elements(curve_1, curve_2)
fig.show()
```

## Basic curve arithmetic#

The `Curve`

class has a number of methods which can be used to create new curves from basic mathematical operations on existing ones. For example, you can add two curves together, or multiply a curve by a constant.

```
curve_1 = gl.Curve.from_function(
lambda x: np.sin(x) + 10, np.pi, 10 * np.pi, label="Curve 1", number_of_points=100,
)
curve_2 = gl.Curve.from_function(
lambda x: x, np.pi, 10 * np.pi, label="Curve 2", number_of_points=100,
)
curve_sum = curve_1 + curve_2
curve_sum.label = "Sum"
fig = gl.Figure()
fig.add_elements(curve_1, curve_2, curve_sum)
fig.show()
```

Addition, subtraction, multiplication and division is generally supported between any two curves, as long as they are plotted using the same number of points. These four operations are also supported between a curve and a constant. When creating new curves with +, -, *, or /, you can still access and change the curve properties such as the color and label through the new curve object using dot notation.

You can also find the the maximum and minimum values of a curve (maximum or minimum y value) using the standard Python functions `max()`

and `min()`

.

```
max_value = max(curve_1)
min_value = min(curve_1)
```

## Identifying points on a curve#

The `Curve`

class includes interpolation methods for creating coordinates and points on a curve at a specific x or y value. The `get_coordinates_at_x()`

method returns a tuple of coordinates (x, y) representing a point on the curve at a given x value. Similarly, the `get_coordinates_at_y()`

method returns a list of tuples (since a function can cross a y value at multiple points), each representing the coordinates of a point on the curve at the given y value. Alternatively, the `create_point_at_x()`

and `create_points_at_y()`

methods create a `Point`

object or a list of such objects which can then be added to a Figure. Additionally, the `get_intersection_coordinates()`

and `create_intersection_points()`

methods, which identify the points of intersection between two curves, also follow this logic.

```
curve_1 = gl.Curve.from_function(lambda x: 5 * np.sin(x), 0, 10)
curve_2 = gl.Curve.from_function(
lambda x: 0.3 * (x - 4) ** 3 - 0.5 * x**2 + 20 * np.sin(1.5 * x), 0, 10
)
# Get the points of intersection between the two curves
intersection_points = curve_1.create_intersection_points(curve_2, marker_styles="P", colors="red")
# Get points where curve 1 crosses the x axis (where y = 0)
cross_x_axis_points = curve_1.create_points_at_y(0, color="blue")
# Print coordinates of first intersection point
first_int = curve_1.get_intersection_coordinates(curve_2)[0]
print(f"First intersection point: {first_int}")
fig = gl.Figure()
fig.add_elements(curve_1, curve_2)
# Use the * operator to add a list of elements to the figure all at once
fig.add_elements(*intersection_points, *cross_x_axis_points)
fig.show()
```

```
First intersection point: (0.5651742229068757, 2.677727491121997)
```

## Curve calculus#

There are a number of methods which can be used to perform calculus on a curve. The `create_derivative_curve()`

and `create_integral_curve()`

both return new `Curve`

objects. You can also use the `create_tangent_curve()`

and `create_normal_curve()`

methods to plot tangents and normals to other curves at a given x value.

```
curve_1 = gl.Curve.from_function(lambda x: x**2 - 5, x_min=-5, x_max=5)
derivative_curve = curve_1.create_derivative_curve(label="Derivative")
integral_curve = curve_1.create_integral_curve(label="Integral")
normal_curve = curve_1.create_normal_curve(2, label="Normal at x=2")
tangent_curve = curve_1.create_tangent_curve(2, label="Tangent at x=2")
fig1 = gl.Figure(y_lim=(-6, 25))
fig1.add_elements(curve_1, derivative_curve, integral_curve)
fig2 = gl.Figure(x_lim=(-5, 5), y_lim=(-6, 4))
fig2.add_elements(curve_1, normal_curve, tangent_curve)
multifig = gl.MultiFigure.from_row([fig1, fig2], size=(12, 6), reference_labels=False)
multifig.show()
```

The `get_area_between()`

method can be used to calculate the area under a curve between two x values (and shade it in if you want). The `get_slope_at()`

method can be used to calculate the slope of a curve at a given x value, and the `get_arc_length_between()`

method can be used to calculate the arc length of a curve between two x values.

```
curve_1 = gl.Curve.from_function(lambda x: x**3 - 4 * x + 15, -3, 2, label="Curve 1")
# fill_between argument shades in the area under the curve
area = curve_1.get_area_between(-2, 1, fill_between=True)
slope = curve_1.get_slope_at(0)
arc_length = curve_1.get_arc_length_between(0, 2)
print(f"Area under the curve between x = -2 and x = 1: {area}")
print(f"Slope of the curve at x = 0: {slope}")
print(f"Arc length of the curve between x = 0 and x = 2: {arc_length}")
fig = gl.Figure()
fig.add_elements(curve_1)
fig.show()
```

```
Area under the curve between x = -2 and x = 1: 47.24991797167644
Slope of the curve at x = 0: -3.9998273099304695
Arc length of the curve between x = 0 and x = 2: 6.634026509067356
```

## Other methods#

Also available are the `create_slice_x()`

and `create_slice_y()`

methods, which create a slice of a curve between two x or y values. These are especially useful when you have a noisy patch in your data and you want to create a fit of just the clean part of the curve.

```
curve_1 = gl.Curve.from_function(lambda x: x**2 - 5, x_min=-5, x_max=5)
slice_x = curve_1.create_slice_x(-3, 3)
slice_y = curve_1.create_slice_y(1, 5)
```