Skip to content

Conversation

@trygvrad
Copy link
Contributor

PR summary

This PR is in response to and closes #22969 [ENH]: Voxels as mappable for colorbar

This change allows axes3d.voxels() to take scalar data as input, and map it to color using a colorbar. The colors are applied to the voxels before shading.

The following code demonstrates the new functionality:

import numpy as np
import matplotlib.pyplot as plt

#Mock data
X,Y,Z = np.meshgrid(np.linspace(0,5,10), np.linspace(0,5,10), np.linspace(0,5,10), indexing="ij")
Hist = np.zeros((9,9,9))
Hist[2,5,5], Hist[5,5,3], Hist[5,7,5], Hist[5,0,5] = 1, 55, 4, 39
Hist[5,1,5] = 39
Hist[Hist == 0] = np.nan

# plot
fig=plt.figure()
ax = fig.add_subplot(projection='3d')
res = ax.voxels(X, Y, Z, Hist, cmap='rainbow', norm='log', alpha=0.5)
fig.colorbar(res)
res.colorizer.norm.vmin = 3
image

The technical implementation is such that:

  • scalar data can be input instead of boolean for the filled argument
  filled : 3D np.array of bool or float
       If bool, with truthy values indicate which voxels to fill.
       If float, voxels with finite values are shown with color
       mapped via *cmap* and *norm*, while voxels with nan are ignored.
  • The return type is changed from a dict of Poly3DCollection to a single Poly3DCollection. This change is needed so that we can call fig.colorbar() on the return value.
  • Poly3DCollection gets a new member function .update_scalarmappable() which overloads Collection.update_scalarmappable(). The new member function is needed to combine the color from the colormap with the shading. This has the additional impact that we can also allow other 3d surface plots to use both cmap and shading [ax.surface(), ax.plot_trisurf()].

Next step

Before we move further with this I would like to have some discussion with the maintainers if it is OK to change the return type here. I think is is really important that the user is able to call fig.colorbar() in an easy way, but there may be other ways to achieve this goal. It is probably a good idea to discuss this at a weekly developer meeting.

If we choose to move on with this I will need to add an example to the docs, a release note, and I think it would also be prudent to add more testing.


NOTE on the modification of the test images:
The change in return type change impacts how the rendering is executed, which leads to a very minor change in how PNGs are rendered [notably, no differences are observed when exporting as SVG]. This change causes all existing image-comparison tests to fail. I believe the current behaviour is a [relatively insignificant] bug, and the changes in this PR improves the rendering quality ever so slightly.

The change is illustrated using the following test image:
voxels-xyz

Rendered with 300 DPI and zoomed in:
before:
image
after:
image

I have added a line as a guide to the eye, so that the difference is visible. The discrepancy becomes greater with lower DPI, but it is also more difficult to see what is going on if the DPI is lower.

PR checklist

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.

[ENH]: Voxels as mappable for colorbar

1 participant