Source code for biogeme.tools.ellipse

"""
Representation of an ellipse

Michel Bierlaire
Sat Dec 21 16:45:00 2024
"""

from dataclasses import dataclass

from matplotlib import pyplot as plt
from matplotlib.patches import Ellipse as MatplotEllipse
import numpy as np


[docs] @dataclass class Ellipse: """Contains the information needed to draw an ellipse""" center_x: float center_y: float sin_phi: float cos_phi: float axis_one: float axis_two: float
[docs] def draw_ellipse(ellipse: Ellipse, ax=None, **kwargs): """ Draws an ellipse using matplotlib. :param ellipse: An Ellipse object containing the parameters of the ellipse. :param ax: A matplotlib Axes object. If None, a new figure and axes will be created. :param kwargs: Additional keyword arguments passed to matplotlib.patches.Ellipse. """ # Compute the rotation angle of the ellipse in degrees phi = np.arctan2(ellipse.sin_phi, ellipse.cos_phi) angle = np.degrees(phi) # Create the matplotlib ellipse patch = MatplotEllipse( (ellipse.center_x, ellipse.center_y), # Center of the ellipse width=2 * ellipse.axis_one, # Major axis (diameter) height=2 * ellipse.axis_two, # Minor axis (diameter) angle=angle, # Rotation angle in degrees **kwargs # Additional styling options ) # Add the ellipse to the axes if ax is None: fig, ax = plt.subplots(figsize=(6, 6)) ax.add_patch(patch) # Set limits for better visualization ax.set_xlim( ellipse.center_x - 1.5 * ellipse.axis_one, ellipse.center_x + 1.5 * ellipse.axis_one, ) ax.set_ylim( ellipse.center_y - 1.5 * ellipse.axis_two, ellipse.center_y + 1.5 * ellipse.axis_two, ) ax.set_aspect('equal', adjustable='datalim') # Add labels and grid ax.axhline(0, color='gray', linestyle='--', linewidth=0.5) ax.axvline(0, color='gray', linestyle='--', linewidth=0.5) ax.set_xlabel('X-axis') ax.set_ylabel('Y-axis') ax.grid(True) # Show plot if ax was None if ax is None: plt.show()