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 — [Bug]: Modifying NumPy array after passing to set_xticks() unexpectedly alters plot ticks · Issue #32313 · matplotlib/matplotlib

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

New issue
Copy link
New issue
Copy link
Open
Open
[Bug]: Modifying NumPy array after passing to set_xticks() unexpectedly alters plot ticks#32313
Copy link
Labels
topic: ticks axis labels

Description

@williamlus
williamlus
opened on Sep 7, 2026
Issue body actions

Bug summary

When passing a NumPy array to ax.set_xticks(), Matplotlib retains a reference to the array instead of creating a copy. Any in-place modifications made to the array after calling set_xticks() directly mutate the plot's tick locations. Passing a standard Python list does not exhibit this issue, suggesting Matplotlib should create an explicit copy of array input internally.

Code for reproduction

import numpy as np
import matplotlib.pyplot as plt

attributes = ['Speed', 'Reliability', 'Comfort', 'Safety', 'Efficiency']
fig = plt.figure()
ax1 = fig.add_subplot(2, 1, 1, projection='polar')
theta = np.linspace(0, 2*np.pi, 5, endpoint=False)
# theta = np.linspace(0, 2*np.pi, 5, endpoint=False).tolist() # this works
ax1.set_xticks(theta)
ax1.set_xticklabels(attributes)
for i in range(5): theta[i] += np.pi * 2

Actual outcome

Image

Expected outcome

Image

Additional information

No response

Operating system

No response

Matplotlib Version

0.2.0.dev55193+unknown.g2153774ae

Matplotlib Backend

No response

Python version

No response

Jupyter version

No response

Installation

None

Activity

  1. timhoffm commented on Sep 7, 2026

    @timhoffm
    timhoffm
    on Sep 7, 2026
    Member
    More actions

    @williamlus are these actual production bugs you are stumbling over or are you running tools that inverstigate theoretical error paths.

    On the array-modification topic: I'm unclear whether we have a general guarantee that we isolate from passed parameters. Sometimes we do explicitly, but this is really a can of worms. Effectively, one would have to push copying down to https://github.com/matplotlib/matplotlib/blob/v3.11.1/lib/matplotlib/axis.py#L2309. But there unit conversion may or may not produce a new array. While we could change that to always make a copy, the result is passed in FixedLocator. But FixedLocator can also be used as public API directly, so that it itself would need to do a copy to defend against post-hoc modification. This means we need to do multiple unnecessary copies.

    Overall, I would say, that the behavior is explicitly not defined. You should not use modify ticks through this mechanism, but we also don't guarantee that objects are decoupled.

  2. melissawm
    added
    topic: ticks axis labels
    on Sep 7, 2026
  3. williamlus commented on Sep 8, 2026

    @williamlus
    williamlus
    on Sep 8, 2026
    Author
    More actions

    Sorry for bothering you with this! To be completely honest, I started out working in production, but later found software testing and bug hunting really fascinating, so I built a tool to help discover potential edge cases like this one.

    I shared it because I found the behavior quite interesting—modifying the array after passing it to the first subplot implicitly alters the tick locations for both subplots. Here is the complete minimal code snippet to demonstrate the behavior. In this case you still need to manually make a copy of the theta array for the second plot (for example, theta = theta + np.pi * 2) before modifying it.

    import numpy as np
    import matplotlib.pyplot as plt
    
    attributes = ['Speed', 'Reliability', 'Comfort', 'Safety', 'Efficiency']
    theta = np.linspace(0, 2*np.pi, len(attributes), endpoint=False)
    fig = plt.figure(figsize=(8, 6))
    
    ax1 = fig.add_subplot(2, 1, 1, projection='polar')
    ax1.set_xticks(theta)
    ax1.set_xticklabels(attributes)
    
    theta += np.pi * 2
    
    ax2 = fig.add_subplot(2, 1, 2, projection='polar')
    ax2.set_thetamin(360)
    ax2.set_thetamax(720)
    ax2.set_xticks(theta)
    ax2.set_xticklabels(attributes)
    
    plt.show()
    Image
  4. Rudra-G-23 commented on Sep 19, 2026

    @Rudra-G-23
    Rudra-G-23
    on Sep 19, 2026
    More actions

    Hi, I’m interested in investigating this issue. I read the discussion here and the closed #32367, and my understanding is that simply copying inside FixedLocator is not sufficient because the broader question is whether Matplotlib should guarantee isolation from mutations of caller-provided arrays.

    Before implementing anything, would you prefer this behavior to remain undefined, or is there an API boundary where you would consider copying the input appropriate? If a copy/isolation guarantee is desired, I’d be happy to trace the set_ticks/unit-conversion/FixedLocator paths and add tests for the agreed behavior.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    topic: ticks axis labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      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.