Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Deprecate linking mappables without data to a colormap #20630

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from

Conversation

timhoffm
Copy link
Member

If a mappable does not provide data for mapping via get_array(), it
makes no sense to allow linking it to a colormap.

Closes #20576

If a mappable does not provide data for mapping via get_array(), it
makes no sense to allow linking it to a colormap.

Closes matplotlib#20576
@timhoffm timhoffm added this to the v3.5.0 milestone Jul 11, 2021
@jklymak
Copy link
Member

jklymak commented Jul 11, 2021

But we should also check the dims of the array?

@timhoffm timhoffm marked this pull request as draft July 11, 2021 22:05
@timhoffm
Copy link
Member Author

Indeed. This is more difficult than I thought, and possibly, our API is not consistent:

  • For PointCollection (e.g. created by scatter()) `get_array() is None if explicit colors are given:
    import matplotlib.pyplot as plt
    import numpy as np
    
    x = np.random.random(10)
    y = np.random.random(10)
    c = np.random.random((10, 3))
    
    pc = plt.scatter(x, y, c=c)
    print(pc.get_array())
    plt.colorbar()
    
  • For AxesImage (e.g. created by imshow(), the array exists:
    data = np.random.random((10, 10, 3))
    
    im = plt.imshow(data)
    print(im.get_array())
    plt.colorbar()
    

This means we likely need some can_be_mapped() method to abstract away that mess. In any case, one needs to check every scalar mappable subclass how they handle things currently.

If anybody wants to pick this up, please post here. I'm not clear if I will have time to investigate in time for 3.5.

@jklymak
Copy link
Member

jklymak commented Jul 12, 2021

If get_array is None we aren't doing a colormapping?

For AxesImage the array exists, but its dims are >2, whereas if it is colormapped they are 2.

@greglucas
Copy link
Contributor

Just a note that I do sometimes make empty ScalarMappables just to make a defined colorbar without explicit linking to an image, so I'm not sure demanding an array should be a requirement.

sm = mpl.cm.ScalarMappable(norm=norm, cmap=cmap)
fig.colorbar(sm)

I do vaguely remember I used to have to force the array to something in the past (sm.set_array([]), but that requirement was lifted somewhat recently I think...

@jklymak
Copy link
Member

jklymak commented Jul 12, 2021

OK, so maybe there is something we can detect when we create the scalar mappable. In that case you have well-defined the norm and cmap. For an RGBA image the user could define those, but probably is not.

@timhoffm
Copy link
Member Author

timhoffm commented Jul 12, 2021

@jklymak

If get_array is None we aren't doing a colormapping?

I can't really say but I suppose it not a simple 1:1 relationship. In the two above examples only one has an array, but neither is colormapped. There's also special-casing for ContourSets in the code (but I didn't look into that).

@greglucas

Just a note that I do sometimes make empty ScalarMappables just to make a defined colorbar without explicit linking to an image

Indeed after looking up, this is the documented solution. There is however the possibility for Colorbar(ax, norm=norm, cmap=cmap) without a mappable, which creates a dummy ScalarMappable internally (actually thats the only reason Colorbar has parameters norm and cmap). Unfortunately, this is not accessible via Figure.colorbar() because that requires a mappable.

The current code is not clear as we can see from the confusion on get_array(), the inconsistent APIs between fig.colorbar() and Colorbar. And upon further inspection: Who owns the cmap and the norm? The ScalarMappable carries them around and the colorbar stores that internally, but it also stores norm and cmap again in its own attibutes. Posssibly, we should have a thourough look on the whole machinery.

@jklymak
Copy link
Member

jklymak commented Jul 12, 2021

And upon further inspection: Who owns the cmap and the norm? The ScalarMappable carries them around and the colorbar stores that internally, but it also stores norm and cmap again in its own attibutes. Posssibly, we should have a thourough look on the whole machinery.

Yes, getting all this sorted out before something like #19515 seems important.

Currently if we just do

norm = mpl.colors.Normalize(vmin=-1, vmax=1)

fig, ax = plt.subplots()
pc = ax.pcolormesh(np.random.randn(20, 20), norm=norm)
fig.colorbar(pc)
norm.vmin = 0
plt.show()

3.4.2

normtest342

Master

normtestmaster

I prefer the master behaviour, but the limits of the colorbar are not modified at draw time. Anyhow just an example of how this stuff is not properly sorted out for playing around with in real time.

@timhoffm
Copy link
Member Author

Yes, updates / change events is a whole additional dimension.

@greglucas
Copy link
Contributor

See #19553 for the updates portion of this discussion ;) With that PR, the Colorbar norm gets updated to reflect the vmin and there are no lower ticks.
Figure_1

@timhoffm timhoffm modified the milestones: v3.5.0, v3.6.0 Jul 29, 2021
@timhoffm timhoffm modified the milestones: v3.6.0, v3.7.0 May 1, 2022
@timhoffm timhoffm modified the milestones: v3.7.0, future releases Dec 15, 2022
@timhoffm timhoffm closed this Jul 19, 2024
@timhoffm timhoffm deleted the rgb-no-colorbar branch July 19, 2024 11:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Deprecate adding a (meaningless) colorbar to RGB or RGBA images
3 participants