Skip to content

[Bug]: contains_point() does not appear to work? #23178

@stallam-unb

Description

@stallam-unb

Bug summary

The method contains_point() of a circular patch does not appear to return the correct answer. Note that I have also tested solution proposed in #14207, but it did not help.

Code for reproduction

import numpy
from matplotlib.animation import FuncAnimation
import matplotlib.pyplot as plt
from matplotlib.patches import Circle


class SimpleDemo:
    def __init__(self):
        fig, ax = plt.subplots()
        self.figure = fig
        self.axes = ax
        self.axes.set_aspect("equal")
        self.patches = [
            Circle((0.0, 1.5), 1, color="red"),
            Circle((0.0, -1.5), 1, color="red")
        ]

        self.cursor, = ax.plot(
            [],
            [],
            linestyle="None",
            marker="d",
            markersize=10,
            markerfacecolor="blue",
        )

        for patch in self.patches:
            self.axes.add_patch(patch)

        self.sample_num = 1
        self.rate = 0.01

    def update(self, frame_num):
        new_coordinates = numpy.exp(1j*2*numpy.pi*self.rate*self.sample_num)
        self.sample_num += 1
        cart_coords = [new_coordinates.real, new_coordinates.imag]

        self.cursor.set_xdata(cart_coords[0])
        self.cursor.set_ydata(cart_coords[1])

        for patch in self.patches:

            # Case 1: Manually test if point is inside circle.
            # centre = numpy.array(patch.get_center())
            # diff_val = cart_coords - centre
            #
            # if numpy.hypot(diff_val[0], diff_val[1]) <= 1:
            #     patch.set_color("green")
            # else:
            #     patch.set_color("red")

            # Case 2: Use contains_point(). Does not work.
            # if patch.contains_point(tuple(cart_coords)):
            #     patch.set_color("green")
            # else:
            #     patch.set_color("red")

            # Case 3: Use contains_point() with transform(). Also does not work.
            if patch.contains_point(patch.get_transform().transform(tuple(cart_coords))):
                patch.set_color("green")
            else:
                patch.set_color("red")

        artists = []
        artists.extend(self.patches)
        artists.append(self.cursor)

        return artists


def main():
    demo = SimpleDemo()
    fig = demo.figure

    ani = FuncAnimation(fig,
                        demo.update,
                        frames=100,
                        interval=100,
                        repeat=False,
                        blit=True)
    # plt.show()
    ani.save('Case_3.mp4', fps=10, extra_args=['-vcodec', 'libx264'])


if __name__ == '__main__':
    main()

Actual outcome

Case 2 (calling contains_point() without transform):

Case_2.mp4

Case 3 (calling contains_point() with transform):

Case_3.mp4

Expected outcome

Case 1 (manually checking point):

Case_1.mp4

Additional information

No response

Operating system

Windows

Matplotlib Version

3.5.2

Matplotlib Backend

Qt5Agg

Python version

3.10.4

Jupyter version

NA

Installation

conda

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions