Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

[ENH]: Add OrientedRectangleSelector (interactive rotated rectangle selector) #30442

Open
@saranmahadev

Description

@saranmahadev

Problem

Matplotlib’s currentRectangleSelector only supports axis-aligned rectangles. Many domains (image annotation, computer vision, OCR, remote sensing, microscopy, UI layout tools) needoriented/rotated bounding boxes with interactiveresize/rotate/translate. Today, users hack around this withPolygonSelector (4 points) or custom event handlers, which leads to inconsistent UX, no angle snapping, and a lot of duplicated code.

Proposed solution

Introduce a new widget:OrientedRectangleSelector, an interactive selector that behaves likeRectangleSelector but supportsarbitrary rotation. It provides:

  • Corner and edge handles for resizing (with optional aspect-ratio lock).
  • A rotation handle with optionalangle snapping.
  • Dragging the center to translate.
  • Live callbacks during interaction and a finalonselect on release.
  • Visual feedback (cursors, handles) and optional blitting for performance.

This mirrors the mental model ofRectangleSelector while adding rotation.

High-level API

frommatplotlib.widgetsimportOrientedRectangleSelectorors=OrientedRectangleSelector(ax,onselect=None,# called on mouse release with final paramsonmove_callback=None,# called during interaction with live params*,useblit=False,button=None,minspanx=0,minspany=0,spancoords="data",maxdist=10,# handle hit test (px)snap_angle=True,angle_snap_increment=1.0,# degreesmaintain_aspect_ratio=False,min_size=0.02,# in data unitsinitial_center=(0.5,0.5),initial_width=0.3,initial_height=0.2,initial_angle=0.0,# degreeshandle_props=None,# dict for corner/edge/rotate/center stylesline_props=None,# rectangle edge propsstate_modifier_keys=None,# {'rotate': 'shift', 'aspect_ratio': 'control', 'snap': 'alt'})

Returned/Callback params

{"center":np.ndarray([cx,cy]),"width":float,"height":float,"angle":float,# degrees"corners":np.ndarray(shape=(4,2)),# BL, BR, TR, TL in data coords"area":float}

Programmatic control

ors.set_rectangle(center=(x,y),width=w,height=h,angle=a)params=ors.get_rectangle_params()ors.update_properties({"snap_angle":False,"min_size":0.05})

Example usage

fig,ax=plt.subplots()ax.imshow(img,cmap="gray")defonmove(params):# live feedback (e.g., show crop/metrics)passdefondone(params):print(params["center"],params["width"],params["height"],params["angle"])ors=OrientedRectangleSelector(ax,onselect=ondone,onmove_callback=onmove,snap_angle=True,angle_snap_increment=1.0)plt.show()

UX details

  • Handles: 4 corners, 4 edge midpoints, 1 rotation handle, 1 center “+”.
  • Cursors: move/resize/rotate cursors based on hover target.
  • Snapping: configurable granularity (default 1°; can be 15° etc.).
  • Constraints: configurable minimum size; easy to add “keep inside axes” later.
Image

Implementation notes

A reference implementation is attached (ready to adapt to Matplotlib conventions):

  • Uses aRectangle patch drawn at the origin and transformed viaAffine2D (rotate + translate) for numerical stability.
  • Hit-testing in data space; handle detection uses pixel tolerance.
  • Optional blitting for smooth interaction.
  • Clean separation of interaction modes: translate, rotate, resize-corner, resize-edge.
  • Public methods mirrorRectangleSelector where possible; extras are additive.

Backward compatibility

No breakage. New widget, opt-in. Naming followsRectangleSelector. Consider adding an aliasRotatedRectangleSelector for searchability.

Performance

Blitting support keeps interaction smooth; complexity is similar to existing selectors. Handle count is fixed (small); transform math is minimal.

Testing

  • Unit tests for:
    • Local↔world transform correctness.
    • Angle snapping correctness.
    • Aspect-ratio lock.
    • Min-size constraint.
  • Image tests for handle placement and rotation rendering.
  • Event simulation tests (press/motion/release) to validate callbacks.

Documentation

  • User guide with interactive examples.
  • API reference with detailed parameter descriptions.
  • Changelog for version updates.

[I am ready to do that!]

Future extensions (non-blocking)

  • Constrain rectangle within axes/view limits.
  • Keyboard nudging & precise numeric entry.
  • Multi-rectangle manager as a helper (selection, add/remove).
  • Snapping to guide lines / other artists.

Note: I have more ideas for this widget and ready to take full ownership and I can implement them.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions


      [8]ページ先頭

      ©2009-2025 Movatter.jp