You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
There is a @_plot2d decorator vith miscellaneous plots methods and a signature if one wants to build its own custom 2D plot method but no method for 3D plot while I believe we can already have 3D scatter and line plots.
Describe the solution you'd like
It would be great to have a voxel method wrapped on the matplotlib.pyplot in a proper _3Dplot method. It should deal with the label names, facetgrids or severals axes, the colorbar and the dimension.variables of the dataset we want to plot. Coding it for a 3D datarray would already be a very good start !
It is particularly useful for 3D Histograms the same way as pcolormesh is useful for 2D ones and is already implemented
I've written my own basic approach, I here are the plots to give you an idea :
As you can see the multiple axis dealing part can be seriously improved ahah
Describe alternatives you've considered
This is my code for the moment, I used some functions that you define the documentation to get the labels for example.
I got rid of most of the args checking bc my code is not intended to be used for others and I dropped the facegrid option bc I create my custom figs by hand
[Edit : colormap and levels working now, so it can be used by others if the voxels method is still not available]
`
def hist3Dplot(darray,bins,levels,ax=None,cmap="viridis", add_labels=True,add_colorbar=True,**kwargs):#colors=None,,cbar_ax=None
#bins could in theory be obtained by darray but [darray[dim].values for dim in darray.dims] give centered values and not interval borns
def bin2coord(bins):
#X,Y,Z are the coords of the bins hence the "+1"
return np.meshgrid(*[np.linspace(bin[0][0],bin[-1][1],len(bin)+1) for bin in bins])
NPArr=darray.to_numpy()
BoolArr=NPArr!=0 #won't draw non occuring voxels from the histogram
palette=mpl.cm.get_cmap("viridis",lut=levels).copy()
palette.set_under((0,0,0,0)) #for the cmap so that vmin is taken into account
CArr = palette(NPArr/np.max(NPArr))
CArr[:,:,:,3]=0.9
X, Y, Z = bin2coord(bins)
if ax==None:
fig=plt.figure()
ax = fig.add_subplot(projection='3d')
else:
fig=plt.gcf()
primitive = ax.voxels(X, Y, Z, BoolArr, facecolors=CArr)#,edgecolor=(236/250, 236/255, 236/255, 1))
dim_names=darray.dims
if add_labels:
#So that the long labels don't stack on the axis ticks
axis_labels=np.array([xr.plot.utils.label_from_attrs(darray[dim_names[i]]) for i in range(3)])
labelpad=np.where(np.char.str_len(axis_labels)>50,20,5)
ax.set_xlabel(axis_labels[0],fontsize=15,labelpad=labelpad[0])
ax.set_ylabel(axis_labels[1],fontsize=15,labelpad=labelpad[1])
ax.set_zlabel(axis_labels[2],fontsize=15,labelpad=labelpad[2])
ax.set_title(darray._title_for_slice())
if add_colorbar:
from matplotlib import cm
vmax=np.max(NPArr)
norm = mpl.colors.Normalize(0,vmax)
m = cm.ScalarMappable(cmap=palette,norm=norm)
m.set_array([])
ticks=np.linspace(1,vmax,levels+1)
fig.colorbar(m,ax=ax,extend="min",ticks=ticks)
return primitive
`
In this example I have a custom cmap to filter the 0 values as transparent (it's easier to read for a histogram) that's why I add a level in the colorbar and I created the axis before calling the function
I believe someone with a better understanding of the API could create a wrapper around matplotlib.pyplot.voxels easily. The _3dplot decorator would make some sense if you keep adding 3d plot methods on requests !
Additional context
No response
The text was updated successfully, but these errors were encountered:
Is your feature request related to a problem?
There is a @_plot2d decorator vith miscellaneous plots methods and a signature if one wants to build its own custom 2D plot method but no method for 3D plot while I believe we can already have 3D scatter and line plots.
Describe the solution you'd like
It would be great to have a voxel method wrapped on the matplotlib.pyplot in a proper _3Dplot method. It should deal with the label names, facetgrids or severals axes, the colorbar and the dimension.variables of the dataset we want to plot. Coding it for a 3D datarray would already be a very good start !
It is particularly useful for 3D Histograms the same way as pcolormesh is useful for 2D ones and is already implemented
I've written my own basic approach, I here are the plots to give you an idea :
As you can see the multiple axis dealing part can be seriously improved ahah
Describe alternatives you've considered
This is my code for the moment, I used some functions that you define the documentation to get the labels for example.
I got rid of most of the args checking bc my code is not intended to be used for others and I dropped the facegrid option bc I create my custom figs by hand
[Edit : colormap and levels working now, so it can be used by others if the voxels method is still not available]
`
`
In this example I have a custom cmap to filter the 0 values as transparent (it's easier to read for a histogram) that's why I add a level in the colorbar and I created the axis before calling the function
I believe someone with a better understanding of the API could create a wrapper around matplotlib.pyplot.voxels easily. The _3dplot decorator would make some sense if you keep adding 3d plot methods on requests !
Additional context
No response
The text was updated successfully, but these errors were encountered: