Skip to content

Alpha parameter doesn't work in bar3d #9559

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
ngonthier opened this issue Oct 24, 2017 · 16 comments
Closed

Alpha parameter doesn't work in bar3d #9559

ngonthier opened this issue Oct 24, 2017 · 16 comments
Labels
status: inactive Marked by the “Stale” Github Action topic: mplot3d
Milestone

Comments

@ngonthier
Copy link

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.

@WeatherGod
Copy link
Member

WeatherGod commented Oct 24, 2017 via email

@anntzer
Copy link
Contributor

anntzer commented Oct 24, 2017

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 :/

@WeatherGod
Copy link
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...

@WeatherGod
Copy link
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?

@anntzer
Copy link
Contributor

anntzer commented Oct 24, 2017

$ 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?

@WeatherGod
Copy link
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'>

@anntzer
Copy link
Contributor

anntzer commented Oct 24, 2017

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

@WeatherGod
Copy link
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...)?

@jsh9
Copy link

jsh9 commented Apr 23, 2018

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.

@jsh9
Copy link

jsh9 commented Apr 23, 2018

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.

@anntzer
Copy link
Contributor

anntzer commented Apr 23, 2018

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.

@rth
Copy link
Contributor

rth commented May 30, 2018

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.

@ImportanceOfBeingErnest
Copy link
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?

@rth
Copy link
Contributor

rth commented May 30, 2018

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.

@github-actions
Copy link

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!

@github-actions github-actions bot added the status: inactive Marked by the “Stale” Github Action label Apr 21, 2023
@ksunden
Copy link
Member

ksunden commented Apr 21, 2023

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

@ksunden ksunden closed this as completed Apr 21, 2023
@QuLogic QuLogic added this to the v3.1.0 milestone Apr 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: inactive Marked by the “Stale” Github Action topic: mplot3d
Projects
None yet
Development

No branches or pull requests

9 participants