Skip to content

Alpha parameter doesn't work in bar3d #9559

Closed

Description

@ngonthier

Bug report

I have the same problem than on this Stackoverflow webpage :

Code for reproduction

from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import matplotlib.pyplot as plt

def main():
	plt.ion()
	rho = np.random.random((4,4))
	xpos = np.arange(0,4,1)
	ypos = np.arange(0,4,1)
	xpos, ypos = np.meshgrid(xpos, ypos)
	xpos = xpos.flatten()
	ypos = ypos.flatten()
	zpos = np.zeros(4*4)
	dx = 0.5 * np.ones_like(zpos)
	dy = dx.copy()
	dz = rho.flatten()
	alpha = 0.5
	fig = plt.figure()
	ax = fig.gca(projection='3d')
	ax.bar3d(xpos,ypos,zpos, dx, dy, dz, alpha=alpha, linewidth=0)
	plt.show()
	input("Press Enter to continue...")

if __name__ == '__main__':
	main()

Actual outcome

The bar on the plot are not transparent at all but they should be.

Matplotlib version

  • Operating system: Ubuntu 16.04
  • Matplotlib version: 2.0.2
  • Matplotlib backend (print(matplotlib.get_backend())): Qt5Agg
  • Python version: 3.6

Matplotlib have been installerd from conda.

Activity

  1. WeatherGod commented on Oct 24, 2017

    @WeatherGod
    Member
  2. anntzer commented on Oct 24, 2017

    @anntzer
    Contributor

    I can reproduce on tkagg and qt5agg (they both use the same renderer anyways so it'd have been a really weird bug if the result was different). This appears to be a regression somewhere between 1.5.0 and 2.0.0.
    Bisecting is a pain because a bunch of commits in the middle appear to have completely broken alpha support :/

  3. WeatherGod commented on Oct 24, 2017

    @WeatherGod
    Member

    Well, here is my image using v2.0.0 using TkAgg:

    figure_1

    And that is the same as the image I get using v2.0.1 and v2.1.0...

  4. WeatherGod commented on Oct 24, 2017

    @WeatherGod
    Member

    my though w.r.t. backends is more on the handling of the graphics context and whether or not the alpha gets passed around correctly. Doubtful, I know, but it is the only thing that made sense to me.

    The only other possibility that I can think of is if the mpl_toolkits/mplot3d is getting picked up from someplace different than where matplotlib is and is running a different "version" of mplot3d even though different versions of matplotlib are getting tested?

  5. anntzer commented on Oct 24, 2017

    @anntzer
    Contributor
    $ MPLBACKEND=tkagg MPLCONFIGDIR=/tmp/mpld python -c 'from mpl_toolkits import mplot3d; print(mplot3d)'
    <module 'mpl_toolkits.mplot3d' from '/home/antony/src/extern/matplotlib/lib/mpl_toolkits/mplot3d/__init__.py'>
    

    This is my source tree where I have 2.0 checked out.

    Can you confirm on your side?

  6. WeatherGod commented on Oct 24, 2017

    @WeatherGod
    Member

    For me, matplotlib and mpl_toolkits/mplot3d match up. They were installed via conda for the v2.0.0, v2.0.1, and v2.1.0 versions I checked.

    This for the v2.0.0 install I have:

    (hurricane) bash-4.2$ MPLBACKEND=tkagg MPLCONFIGDIR=/tmp/mpld python -c 'from mpl_toolkits import mplot3d; print(mplot3d)'
    <module 'mpl_toolkits.mplot3d' from '/home/broot/scratch/miniconda/envs/hurricane/lib/python2.7/site-packages/mpl_toolkits/mplot3d/__init__.pyc'>
    (hurricane) bash-4.2$ MPLBACKEND=tkagg MPLCONFIGDIR=/tmp/mpld python -c 'import matplotlib; print(matplotlib)'
    <module 'matplotlib' from '/home/broot/scratch/miniconda/envs/hurricane/lib/python2.7/site-packages/matplotlib/__init__.pyc'>
    (hurricane) bash-4.2$ ls -l /home/broot/scratch/miniconda/envs/hurricane/lib/python2.7/site-packages/mpl_toolkits/mplot3d/
    

    And this for the v2.1.0 install:

    bash-4.2$ MPLBACKEND=tkagg MPLCONFIGDIR=/tmp/mpld python -c 'from mpl_toolkits import mplot3d; print(mplot3d)'
    <module 'mpl_toolkits.mplot3d' from '/home/broot/scratch/miniconda/lib/python2.7/site-packages/mpl_toolkits/mplot3d/__init__.pyc'>
    bash-4.2$ MPLBACKEND=tkagg MPLCONFIGDIR=/tmp/mpld python -c 'import matplotlib; print(matplotlib)'
    <module 'matplotlib' from '/home/broot/scratch/miniconda/lib/python2.7/site-packages/matplotlib/__init__.pyc'>
    
  7. anntzer commented on Oct 24, 2017

    @anntzer
    Contributor

    Ah, of course, Py2 (I can confirm it works there for me too).
    So it's a Py3-only issue, probably some kwargs ordering...

  8. WeatherGod commented on Oct 24, 2017

    @WeatherGod
    Member

    The only possibility I can think of there is dictionary order... but we addressed those issues a long time ago, and usually that had to deal with the order of colliding properties...

    Maybe the alpha of the default color is overriding the user's alpha (doubtful...)?

  9. jsh9 commented on Apr 23, 2018

    @jsh9

    I just ran a small debugging check between Python 2 and Python 3 myself. And indeed I see that the key alpha in Python 2 remains the first key in kwargs, while in Python 3, alpha becomes the last key in kwargs (when zsort and facecolor are added into kwargs).

    I am not familiar with how matplotlib handles kwargs with different key orders though. Just offering my observations. Hope they help.

  10. jsh9 commented on Apr 23, 2018

    @jsh9

    And then I inserted this line

    kwargs = {k: kwargs[k] for k in reversed(list(kwargs.keys()))}
    

    immediately before this location (https://github.com/matplotlib/matplotlib/blob/master/lib/mpl_toolkits/mplot3d/art3d.py#L542), which simply created a new dictionary reversing the key order (so that alpha was the first key), and I was able to get semi-transparent 3D bars in Python 3.

    Admittedly this is only a temporary hack. The matplotlib developers should be able to come up with a rigorous patch.

  11. anntzer commented on Apr 23, 2018

    @anntzer
    Contributor

    Alternatively, something like

    diff --git a/lib/mpl_toolkits/mplot3d/axes3d.py b/lib/mpl_toolkits/mplot3d/axes3d.py
    index 1bd3cf7c0..2ad640943 100644
    --- a/lib/mpl_toolkits/mplot3d/axes3d.py
    +++ b/lib/mpl_toolkits/mplot3d/axes3d.py
    @@ -2529,8 +2529,8 @@ class Axes3D(Axes):
     
             col = art3d.Poly3DCollection(polys,
                                          zsort=zsort,
    -                                     facecolor=sfacecolors,
    -                                     *args, **kwargs)
    +                                     *args, **kwargs,
    +                                     facecolor=sfacecolors)
             self.add_collection(col)
     
             self.auto_scale_xyz((minx, maxx), (miny, maxy), (minz, maxz), had_data)
    

    also fixes the issue. But note that both patches only work on Py3.6 as they rely on kwargs conserving kwargs order.

    But it's really a problem of Poly3DCollection only updating the facecolors with the alpha if the alpha is already set when the colors are given (and the luck that on Py2, "alpha" comes before "facecolor" in dict iteration order...). Something like

    p = ax.bar3d(0, 0, 0, 1, 1, 1); p.set_alpha(.5)
    

    also fails to apply the alpha on Py2.

  12. rth commented on May 30, 2018

    @rth
    Contributor

    To follow up on the previous comment, bar3d passes the alpha to set_alpha,

    if 'alpha' in kwargs:
    p.set_alpha(kwargs['alpha'])

    For me with Python 3, p.set_alpha (where p is the Poly3DCollection object) also has no effect, so the issue is with this method IMO.

    Internally, set_alpha mostly consists of,

    try:
    self._facecolors = mcolors.to_rgba_array(
    self._facecolors3d, self._alpha)
    except (AttributeError, TypeError, IndexError):
    pass
    try:
    self._edgecolors = mcolors.to_rgba_array(
    self._edgecolors3d, self._alpha)
    except (AttributeError, TypeError, IndexError):
    pass
    self.stale = True

    Whereas using,

    p._facecolors3d = matplotlib.colors.to_rgba_array(
                              p._facecolors3d, p._alpha)
    p._edgecolors3d = matplotlib.colors.to_rgba_array(
                              p._edgecolors3d, p._alpha)

    and combining it with the fix proposed in #4067 (comment) (I was getting the corresponding error anyway),

    p._facecolors2d = p._facecolors3d
    p._edgecolors2d = p._edgecolors3d

    appears to make transparency work as expected.

  13. ImportanceOfBeingErnest commented on May 30, 2018

    @ImportanceOfBeingErnest
    Member

    Could be the same issue as #10237 for which there were already 2 attempted fixes, but none made it through yet. The one in #10487 looks promising and should just be a matter of getting merged?

  14. rth commented on May 30, 2018

    @rth
    Contributor

    Yes, I think this is a duplicate of #10237. The issue is ultimately with Poly3DCollection from what I saw. It's docstring states,

    Note that this class does a bit of magic with the _facecolors and _edgecolors properties.

    and some of that magic must not work as expected.

  15. github-actions commented on Apr 21, 2023

    @github-actions

    This issue has been marked "inactive" because it has been 365 days since the last comment. If this issue is still present in recent Matplotlib releases, or the feature request is still wanted, please leave a comment and this label will be removed. If there are no updates in another 30 days, this issue will be automatically closed, but you are free to re-open or create a new issue if needed. We value issue reports, and this procedure is meant to help us resurface and prioritize issues that have not been addressed yet, not make them disappear. Thanks for your help!

  16. ksunden commented on Apr 21, 2023

    @ksunden
    Member

    Appears to have been fixed by #13573 (at least that is what closed #10237, which this appears to be a duplicate of)

  17. added this to the v3.1.0 milestone on Apr 21, 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