Skip to content

[Bug]: Tick class instantiation returns an error when labelcolor is a tuple #26588

Closed

Description

@jpdehollain

Bug summary

I have a function that uses custom colouring of different plot axes. When Matplotlib tries to render the figure, I am getting the following error shown below

Code for reproduction

Set the tick label color of a plot using a tuple and try to render.

Actual outcome

File [c:\Users\AppData\Local\miniconda3\lib\site-packages\matplotlib\axis.py:125](file:///C:/Users/v-jpd/AppData/Local/miniconda3/envs/laptop-2.2.91/lib/site-packages/matplotlib/axis.py:125), in Tick.__init__(self, axes, loc, size, width, color, tickdir, pad, labelsize, labelcolor, zorder, gridOn, tick1On, tick2On, label1On, label2On, major, labelrotation, grid_color, grid_linestyle, grid_linewidth, grid_alpha, **kwargs)
    [122] if labelcolor is None:
    [123]     labelcolor = mpl.rcParams[f"{name}.labelcolor"]
--> [125] if labelcolor == 'inherit':
    [126]     # inherit from tick color
    [127]     labelcolor = mpl.rcParams[f"{name}.color"]
    [129] if labelsize is None:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

Expected outcome

Plot with custom tick-label colors.

Additional information

No response

Operating system

Windows

Matplotlib Version

3.7.2

Matplotlib Backend

Have tried with inline and qt

Python version

No response

Jupyter version

3.10.12

Installation

pip

Activity

  1. rcomer commented on Aug 24, 2023

    @rcomer
    Member

    Thank you for the report @jpdehollain. Could you provide a minimal code example that reproduces the problem? Also, did this work with previous Matplotlib versions?

  2. anntzer commented on Aug 24, 2023

    @anntzer
    Contributor

    Seems like we should just use cbook._str_equal here.

  3. jpdehollain commented on Aug 24, 2023

    @jpdehollain
    Author

    Thank you for the report @jpdehollain. Could you provide a minimal code example that reproduces the problem? Also, did this work with previous Matplotlib versions?

    Thanks for looking into it @rcomer... here's a minimal example:

    import matplotlib.pyplot as plt
    import numpy as np
    
    fig, ax = plt.subplots(figsize=(12,8))
    twin1 = ax.twinx()
    colors = np.concatenate(([[0, 0, 0, 1]], plt.cm.tab10([3, 0])))
    x = np.linspace(0,1,100)
    y = x**2
    z = x**3
    
    ax.plot(x, y, color=colors[0])
    twin1.plot(x,z, color=colors[1])
    tkw = dict(size=4, width=1.5)
    ax.tick_params(axis="y", colors=ax.lines[0].get_color(), **tkw)
    twin1.tick_params(axis="y", colors=twin1.lines[0].get_color(), **tkw)
    ax.tick_params(axis="x", **tkw)
    

    I run it as a code cell in an interactive python session... The odd thing is that if I first just run up to the two plot commands, it displays the plot and then if I run the rest it'll modify the tick label colours with no errors. I only get the error when I run the whole code block in one go. Here's the full error trace:

    Traceback (most recent call last):
      File ".\matplotlib\backends\backend_qt.py", line 468, in _draw_idle
        self.draw()
      File ".\matplotlib\backends\backend_agg.py", line 400, in draw
        self.figure.draw(self.renderer)
      File ".\matplotlib\artist.py", line 95, in draw_wrapper
        result = draw(artist, renderer, *args, **kwargs)
      File ".\matplotlib\artist.py", line 72, in draw_wrapper
        return draw(artist, renderer)
      File ".\matplotlib\figure.py", line 3175, in draw
        mimage._draw_list_compositing_images(
      File ".\matplotlib\image.py", line 131, in _draw_list_compositing_images
        a.draw(renderer)
      File ".\matplotlib\artist.py", line 72, in draw_wrapper
        return draw(artist, renderer)
      File ".\matplotlib\axes\_base.py", line 3064, in draw
        mimage._draw_list_compositing_images(
      File ".\matplotlib\image.py", line 131, in _draw_list_compositing_images
        a.draw(renderer)
      File ".\matplotlib\artist.py", line 72, in draw_wrapper
        return draw(artist, renderer)
      File ".\matplotlib\axis.py", line 1376, in draw
        ticks_to_draw = self._update_ticks()
      File ".\matplotlib\axis.py", line 1264, in _update_ticks
        major_ticks = self.get_major_ticks(len(major_locs))
      File ".\matplotlib\axis.py", line 1602, in get_major_ticks
        tick = self._get_tick(major=True)
      File ".\matplotlib\axis.py", line 1551, in _get_tick
        return self._tick_class(self.axes, 0, major=major, **tick_kw)
      File ".\matplotlib\axis.py", line 478, in __init__
        super().__init__(*args, **kwargs)
      File ".\matplotlib\axis.py", line 125, in __init__
        if labelcolor == 'inherit':
    ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
    
  4. rcomer commented on Aug 25, 2023

    @rcomer
    Member

    The odd thing is that if I first just run up to the two plot commands, it displays the plot and then if I run the rest it'll modify the tick label colours with no errors. I only get the error when I run the whole code block in one go.

    I think the ticks are instantiated when the figure is first drawn. So if you only display right at the end then the ticks are instantiated with the options you put in tick_params. If you display before you change the colours then the ticks get instantiated with default values and then the colour change is applies via Tick._apply_params. The bug is only in the instantiation method.

  5. added this to the v3.7.3 milestone on Aug 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions