Skip to content

scatter - set_facecolors is not working on Axes3D #9725

Closed

Description

@orena1

Bug report

Bug summary

Trying to replicate this code: https://matplotlib.org/examples/animation/rain.html , but in Axes3D does not work, it seems that it is not possible to change the facecolors of the scatter while axes is 3D (it does work in 2d)

Code for reproduction

import numpy as np
import matplotlib.pyplot as plt
import matplotlib
import matplotlib.cm as cmx
from mpl_toolkits.mplot3d import Axes3D
plt.figure()
jet = cm = plt.get_cmap('jet')
cNorm  = matplotlib.colors.Normalize(vmin=1, vmax=10)
scalarMap = cmx.ScalarMappable(norm=cNorm, cmap=jet)

cells = 10
ax = plt.subplot(1,1,1, projection='3d')
pos = np.random.uniform(0, 1, (10, 3))

scat = ax.scatter(pos[:,0],pos[:,1],pos[:,2],
                edgecolors=None,
                  facecolors= [scalarMap.to_rgba(1) for cond in range(10)])

scat.set_facecolors([scalarMap.to_rgba(10) for cond in range(10)])
plt.show()
##the dots should be red, but they are blue

Matplotlib version

  • Operating system: MacOs
  • Matplotlib version: 2.1.0
  • Matplotlib backend (print(matplotlib.get_backend())): MacOSX
  • Python version: 2.7.14
  • Jupyter version (if applicable):
  • Other libraries:

Activity

  1. changed the title [-]scatter, set_facecolors is not working on Axes3D[/-] [+]scatter - set_facecolors is not working on Axes3D[/+] on Nov 9, 2017
  2. afvincent commented on Nov 9, 2017

    @afvincent
    Contributor

    @orena1 Thank you for the report :).

    I can confirm that the dots were already blue since at least Matplotlib 1.5.3. (they probably never turned red...)

    Here is a smaller MWE, with a possible workaround for the moment (though I am not 100% sure why it works):

    import numpy as np
    import matplotlib.pyplot as plt
    from mpl_toolkits.mplot3d import Axes3D
    
    plt.figure()
    ax = plt.subplot(1, 1, 1, projection='3d')
    
    pos = np.random.uniform(0, 1, (10, 3))
    
    scat = ax.scatter(pos[:, 0], pos[:, 1], pos[:, 2],
                      edgecolors="none",
                      facecolors="blue")
    
    scat.set_facecolors("red")
    
    # Possible workaround that seems to trigger
    # the update of the facecolor values
    scat.set_3d_properties(pos[:, 2], "y")
    
    plt.show()

    Attn @WeatherGod

  3. modified the milestones: , v2.1.1 on Nov 9, 2017
  4. modified the milestones: v2.1.1, on Nov 13, 2017
  5. tacaswell commented on Nov 13, 2017

    @tacaswell
    Member

    Moved to 2.2 as this is not a regression.

  6. modified the milestones: , on Mar 5, 2018
  7. modified the milestones: v3.0, v3.1 on Aug 11, 2018
  8. stippingerm commented on Jan 8, 2019

    @stippingerm

    This is still an issue. Prior to finding this bug report I posted my own examples as a new bug report because the examples I found were all related to animation just like the context given here. Animation is not the cause.

    But, as pointed out in those examples, I believe the issue should be handled together with the issue of coexisting collection-level alpha value and alpha values coming from RGBA colors.

  9. modified the milestones: v3.1.0, v3.2.0 on Mar 18, 2019
  10. modified the milestones: v3.2.0, v3.3.0 on Aug 16, 2019
  11. modified the milestones: v3.3.0, v3.4.0 on May 27, 2020
  12. liuzhenqi77 commented on Jul 5, 2020

    @liuzhenqi77

    Ran into this issue when updating color limits with scat.clim(), the displayed image from plt.show() is correct, but saved image with plt.savefig() shows wrong (different) facecolor and edgecolor. Using the suggested workaround set_3d_properties() works for now.

    Matplotlib version: Ubuntu 16.04, 3.3.0rc1+149.g8c2fbda, Qt5Agg backend, Python 3.7.6

  13. tacaswell commented on Jul 5, 2020

    @tacaswell
    Member

    @liuzhenqi77 Do you have a mininal example where it looks right on the screen but saving it comes out wrong?

  14. liuzhenqi77 commented on Jul 5, 2020

    @liuzhenqi77

    @tacaswell I tried more cases, and find that my case could be related to plt.colorbar(), but I'm not 100% sure. This MWE is adapted from above. They look the same on screen but different as files.

    import numpy as np
    import matplotlib.pyplot as plt
    
    pos = np.random.uniform(0, 1, (10, 3))
    
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')
    scat = ax.scatter(pos[:, 0], pos[:, 1], pos[:, 2], c=range(10), cmap="Reds")
    plt.colorbar(scat, ax=ax)
    fig.savefig("test1.png")
    
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='3d')
    scat = ax.scatter(pos[:, 0], pos[:, 1], pos[:, 2], c=range(10), cmap="Reds")
    # plt.colorbar(scat, ax=ax)
    fig.savefig("test2.png")

    My original user case was,
    When setting color with c=, there could be two ways to adjust the color limit:

    • setting vmax and vmin, this works for show but not for savefig
    • setting scat.clim(), this is not working for both cases, although the colorbar changes.
  15. linked a pull request that will close this issueFIX: Add get/set methods for 3D collections #18189on Sep 17, 2020
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