GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — FixedLocator: copy ndarray input instead of aliasing it by pranjalm37 · Pull Request #32367 · matplotlib/matplotlib

Conversation

@pranjalm37

@pranjalm37 pranjalm37 commented Sep 18, 2026

Copy link
Copy Markdown

Fixes #32313.

Root cause

FixedLocator.__init__ stores its tick locations via np.asarray(locs):

def __init__(self, locs, nbins=None):
    self.locs = np.asarray(locs)

np.asarray is a no-op when its input is already an ndarray — it returns the same array object, not a copy. Since Axis.set_ticks()/set_xticks() build a FixedLocator directly from whatever array the caller passed in, FixedLocator.locs ends up aliasing that array. Any later in-place mutation of it retroactively moves the axis' already-set tick locations:

import numpy as np
import matplotlib.pyplot as plt

fig, ax = plt.subplots()
theta = np.linspace(0, 2 * np.pi, 5, endpoint=False)
ax.set_xticks(theta)
theta += 2 * np.pi  # unrelated in-place mutation elsewhere in the program
# ax's ticks silently moved too

A plain list input doesn't show this, since converting a list to an array always produces a fresh one — which is presumably why this went unnoticed for a while.

Fix

Use np.array(locs) instead, which copies by default, so FixedLocator owns its storage regardless of whether the input was a list or an existing ndarray.

Testing

  • Added TestFixedLocator.test_locs_is_a_copy_of_ndarray_input, which constructs a FixedLocator from an ndarray, mutates the array in place afterward, and asserts .locs is unaffected. Verified it fails on unpatched ticker.py (fixed.locs is not locs → AssertionError) and passes with the fix.
  • Manually reproduced the original report's polar-plot example end-to-end (prebuilt matplotlib wheel with just ticker.py swapped in, since I couldn't build the C extensions from source in my sandbox — no network access for the bundled freetype/etc. fetch): confirmed ax.get_xticks() changes after mutating the input array on unpatched code, and stays stable with the fix. Also confirmed a plain-list set_xticks([1, 2, 3]) call is unaffected.
  • ruff check on both changed files — clean (matplotlib's pyproject.toml only configures ruff check, not ruff format, so I didn't run the formatter).

AI disclosure

I used Claude Code to investigate and draft this fix; I reviewed the diagnosis (traced set_ticks → FixedLocator.__init__ → np.asarray), verified the reproduction and fix behavior myself as described above, and reviewed every changed line before opening this PR.


🤖 Generated with Claude Code

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@pranjalm37
FixedLocator: copy ndarray input instead of aliasing it
0548fef
FixedLocator.__init__ stored locs via np.asarray(locs), which is a
no-op for an already-ndarray input -- it returns the same object
rather than a copy. Since set_ticks()/set_xticks() build their
FixedLocator directly from whatever array the caller passed, any
later in-place mutation of that array (e.g. `theta[i] += ...`) moved
the axis' already-set tick locations too, silently changing the plot.
A plain list input didn't have this problem, since converting a list
always produces a fresh array.

Use np.array(locs) instead, which copies by default, so FixedLocator
owns its own storage regardless of the input type.

Fixes matplotlib#32313.
@github-actions

github-actions Bot commented Sep 18, 2026

Copy link
Copy Markdown

Thank you for opening your first PR into Matplotlib!

If you have not heard from us in a week or so, please leave a new comment below and that should bring it to our attention. Most of our reviewers are volunteers and sometimes things fall through the cracks. We also ask that you please finish addressing any review comments on this PR and wait for it to be merged (or closed) before opening a new one, as it can be a valuable learning experience to go through the review process.

You can also join us on discourse chat for real-time discussion.

For details on testing, writing docs, and our review process, please see the developer guide.
Please let us know if (and how) you use AI, it will help us give you better feedback on your PR.

We strive to be a welcoming and open project. Please follow our Code of Conduct.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@github-actions github-actions Bot added topic: ticks axis labels first-contribution labels Sep 18, 2026
@rcomer

rcomer commented Sep 18, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

Hi @pranjalm37 and thank you for your interest in improving Matplotlib. From your PR description, it does not look like you read the comments on the issue. Please read those comments and say why you think this fix is still necessary in the light of them.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@pranjalm37

pranjalm37 commented Sep 18, 2026

Copy link
Copy Markdown
Author

You're right, and I didn't read the issue thread before opening this. I only looked at the reproduction.

Having read it now: Tim's point stands. Copying in FixedLocator only covers one layer, and the same aliasing exists where set_ticks converts units and for anyone constructing FixedLocator directly, so a real fix means extra copies in several places for behavior that isn't guaranteed anyway. I don't have a justification for merging this on its own, so I'm closing it. Sorry for the noise.

rcomer reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@pranjalm37 pranjalm37 closed this Sep 18, 2026
@Rudra-G-23 Rudra-G-23 mentioned this pull request Sep 19, 2026
[Bug]: Modifying NumPy array after passing to set_xticks() unexpectedly alters plot ticks #32313
Open
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

No reviews

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

first-contribution topic: ticks axis labels

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

[Bug]: Modifying NumPy array after passing to set_xticks() unexpectedly alters plot ticks

Uh oh!

There was an error while loading. Please reload this page.

2 participants

@pranjalm37 @rcomer
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.