import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
from mpl_toolkits.axes_grid1.inset_locator import inset_axes
from .basefuncs import *
[docs]def vmin_vmax_pl(arr, funcforpl):
"""Computes minimum and maximum values for plt.imshow(funcforpl(arr)).
Parameters
----------
arr : ndarray
Array to be plotted.
funcforpl : ufunc
Function applied to array.
Returns
-------
float, float
Minimum and maximum values to be used by plt.imshow(funcforpl(arr)). 7
"""
if ((funcforpl == np.log10) | (funcforpl == np.log)):
proper_indexes = arr > 0
elif (funcforpl == np.sqrt):
proper_indexes = arr >= 0
else:
proper_indexes = np.fabs(funcforpl(arr)) != np.inf
vmin = np.nanmin(funcforpl(arr[proper_indexes]))
vmax = np.nanmax(funcforpl(arr[proper_indexes]))
return vmin, vmax
[docs]def plot_hist2d(hm2d, edy, edx, funcforpl=np.log10, vmin_plot=None, vmax_plot=None, add_eps_in_plot=False, cmap=None,
show_color_bar=True, fig=None, cb_loc=None, xlab=None, ylab=None, cblab=None, interpolation='none'):
"""Plots 2D histogram hm2d of edges edy and ex. Can plot only images with pixels of fixed dx and dy.
Parameters
----------
hm2d : ndarray
(Ny, Nx) 2D histogram to plot
edy : ndarray
(Ny+1,) y edges
edx : ndarray
(Nx+1,) x edges
funcforpl : ufunc, default = np.log10
Function applied to hm2d.
vmin_plot : float or `None`, default = `None`
Minimum value of funcforpl(hm2d) to be plotted. If `None`, set
by :func:`~galaximview.funcsplots.vmin_vmax_pl`.
vmax_plot : float or `None`, default = `None`
Maximum value of funcforpl(hm2d) to be plotted. If `None`, set
by :func:`~galaximview.funcsplots.vmin_vmax_pl`.
add_eps_in_plot : bool, default = `False`
Add machine precision epsilon in plots (for aesthetical purpose).
cmap : matplotlib color map or `None`
Matplotlib color map. Defaults to `None` and is in this case the default matplotlib color map.
show_color_bar : bool, default = `True`
`True` if one wants to show the color bar. Defaults to True.
fig : matplotlib figure, optional
Figure to plot color bar on if cb_loc is not `None`.
cb_loc : matplotlib axis, optional
Matplotlib axis to add color bar to. Defaults to `None` and in this case, add it to current axis.
xlab, ylab : str, optional
x axis label.
cblab : str, optional
Color bar label. Defaults to `None` (no label).
interpolation: str, optional
Type of matplotlib interpolation. Defaults to 'none'.
Returns
-------
object
plt.imshow object
"""
extentxy = [edx[0], edx[-1], edy[0], edy[-1]]
if ((vmin_plot is None) | (vmax_plot is None)):
vmin_plot, vmax_plot = vmin_vmax_pl(hm2d, funcforpl)
if (funcforpl != identity_function):
if (add_eps_in_plot):
eps = np.finfo(float).eps
hm2d += eps
hm2d[np.isnan(hm2d)] = eps
hm2d = funcforpl(hm2d)
im = plt.imshow(hm2d, origin='lower', interpolation=interpolation, extent=extentxy, vmin=vmin_plot, vmax=vmax_plot,
cmap=cmap)
plt.xlabel(xlab)
plt.ylabel(ylab)
if (show_color_bar):
if cb_loc is None:
cbar = plt.colorbar()
else:
axins = inset_axes(cb_loc, width="5%", # width = 5% of parent_bbox width
height="100%", # height : 50%
loc='lower left', bbox_to_anchor=(1.02, 0., 1, 1), bbox_transform=cb_loc.transAxes,
borderpad=0, )
cbar = fig.colorbar(im, cax=axins)
cbar.set_label(cblab)
return im
[docs]def plot_hist2d_with_pdfs(hm2dxy, hmdx, hmdy, edx, edy, funcforpl=np.log10, funcforplx=np.log10, funcforply=np.log10,
vmin_plot=None, vmax_plot=None, cmap=None, show_color_bar=False, fig=None, xlab=None,
ylab=None, cblab=None, strtit=None, ax=None):
"""Plots 2D-histogram with marginal distributions.
Parameters
----------
hm2dxy : ndarray
(Ny, Nx) 2D histogram to plot.
hmdx : ndarray
(Nx,) 1D marginal histogram for x axis.
hmdy : ndarray
(Ny,) 1D marginal histogram for y axis.
edx : ndarray
(Nx+1,) x edges
edy : ndarray
(Ny+1,) y edges
funcforpl : ufunc, default = np.log10
Function applied to hm2dxy. Defaults to np.log10.
funcforplx : ufunc
Function applied to hmdx. Defaults to np.log10.
funcforply : ufunc
Function applied to hmdy. Defaults to np.log10.
vmin_plot : float or None, default = None
Minimum value of funcforpl(hm2dxy) to be plotted. Defaults to None and is in this case set by the
function vmin_vmax_pl.
vmax_plot : float or None, default = None
Maximum value of funcforpl(hm2dxy) to be plotted. Defaults to None and is in this case set by the
function vmin_vmax_pl.
cmap : matplotlib color map or None
Matplotlib color map. Defaults to None and is in this case the default matplotlib color map.
show_color_bar : bool, default = `True`
`True` if one wants to show the color bar. Defaults to True.
fig : matplotlib figure.
Figure to plot on. Defaults to None and in this case, plots on current figure or, if none, on new
figure.
xlab, ylab : str, optional
x axis label.
cblab : str or None, optional
Color bar label. Defaults to None (no label).
strtit : strtit: str or None, optional
Title of figure. Defaults to None.
ax : matplotlib axis aobject
Matplotlib axis. Defaults to None.
Returns
-------
3 matplotlib axis objects
3 matplotlib axes
"""
extentxy = [edx[0], edx[-1], edy[0], edy[-1]]
print(extentxy)
if ((vmin_plot is None) | (vmax_plot is None)):
vmin_plot, vmax_plot = vmin_vmax_pl(hm2dxy, funcforpl)
hm2dxy = funcforpl(hm2dxy)
hmdx = funcforplx(hmdx)
hmdy = funcforply(hmdy)
if fig is None:
fig = plt.gcf()
axy = fig.add_subplot(1, 1, 1)
else:
if ax is None:
raise ValueError('ax must be provided.')
axy = ax
im = axy.imshow(hm2dxy, origin='lower', interpolation='none', extent=extentxy, vmin=vmin_plot, vmax=vmax_plot,
cmap=cmap)
axy.set_aspect('auto')
if (strtit is not None):
fig.suptitle(strtit)
divider = make_axes_locatable(axy)
axz = divider.append_axes("top", 1, pad=0., sharex=axy)
azy = divider.append_axes("right", 1, pad=0., sharey=axy)
axy.set_xlabel(xlab)
axy.set_ylabel(ylab)
axz.set_adjustable("datalim")
azy.set_adjustable("datalim")
xforhmdx = 0.5 * (edx[:-1] + edx[1:])
xforhmdy = 0.5 * (edy[:-1] + edy[1:])
axz.plot(xforhmdx, hmdx)
azy.plot(hmdy, xforhmdy)
plt.setp(axz.get_xticklabels() + azy.get_yticklabels(), visible=False)
if (show_color_bar):
cax = fig.add_axes([0.85, 0.05, 0.05, 0.9])
cbar = fig.colorbar(im, cax=cax)
cbar.set_label(cblab)
colticks = 'k'
widthticks = 1
for ax in [axy, axz, azy]:
ax.tick_params(axis='both', colors=colticks, width=widthticks, direction='in', labelcolor='k', top=True,
right=True)
return axy, axz, azy
[docs]def plot_1d(xarr, yarr, xlimit_pl=None, ylimit_pl=None, xlab=None, ylab=None, leglab=None, funcofy=identity_function,
linestyle='-', linewidth=1, color=None):
"""Simple 1D plot of funcofy(yarr) as a function of xarr.
Parameters
----------
xarr : ndarray
(N,) array such that funcofy(yarr) is plotted as a function of xarr.
yarr : ndarray
(N,) array such that funcofy(yarr) is plotted as a function of xarr.
xlimit_pl : (float, float) or None, default = None
x axis limits used for plot. Defaults to None (auto-adjusts).
ylimit_pl : (float, float) or None, default = None
y axis limits used for plot. Defaults to None (auto-adjusts).
xlab, ylab : str, optional
x axis label.
leglab : str, optional
Line label.
funcofy : ufunc
Function such that funcofy(yarr) is plotted as a function of xarr. Defaults to identity_function.
linestyle : matplotlib linestyle, optional
Matplotlib linestyle for plot. Defaults to '-' (solid line).matplotlib linestyle
linewidth : matplotlib linewidth, optional
Matplotlib linewidth for plot. Defaults to 1 (normal width).
color : matplotlib color
Matplotlib color of dots. Defaults to None (thus follows matplotlib colors order).
"""
if ((funcofy == np.log10) | (funcofy == np.log)):
proper_indexes = yarr > 0
elif (funcofy == np.sqrt):
proper_indexes = yarr >= 0
else:
proper_indexes = np.fabs(funcofy(yarr)) != np.inf
yarr[proper_indexes] = funcofy(yarr[proper_indexes])
yarr[~proper_indexes] = np.nan
plt.plot(xarr, yarr, linestyle, lw=linewidth, label=leglab, color=color)
plt.xlabel(xlab)
plt.ylabel(ylab)
plt.xlim(xlimit_pl)
if (ylimit_pl is not None):
plt.ylim(ylimit_pl)
if leglab is not None:
plt.legend()
plt.show()
[docs]def plot_3d(xarr, yarr, zarr, xlimit_pl, ylimit_pl, zlimit_pl, xlab=None, ylab=None, zlab=None, leglab=None,
linestyle='-', ax=None, color=None):
"""Plots dots of coordinates xarr, yarr, zarr in a box of edge 2 * rmax.
Parameters
----------
xarr, yarr, zarr : ndarray
(N,) array for corresponding axis.
xlimit_pl, ylimit_pl, zlimit_pl : (float, float)
x axis limits used for plot.
xlab, ylab, zlab : str, optional
Axis label.
leglab : str, optional
Matplotlib legend for 3D dots. Defaults to None (no legend).
linestyle : matplotlib linestyle, optional
Matplotlib linestyle for plot. Defaults to '-' (solid line).matplotlib linestyle
color : matplotlib color
Matplotlib color of dots. Defaults to None (thus follows matplotlib colors order).
ax: matplotlib axis or None, optional
Specific matplotlib axis to plot on. Defaults to None.
"""
if ax is None:
ax = plt.subplot(projection='3d')
ax.plot(xarr, yarr, zarr, linestyle, label=leglab, color=color)
ax.set_xlabel(xlab)
ax.set_ylabel(ylab)
ax.set_zlabel(zlab)
max_range = np.amax(
np.array([xlimit_pl[1] - xlimit_pl[0], ylimit_pl[1] - ylimit_pl[0], zlimit_pl[1] - zlimit_pl[0]]))
xxb = 0.5 * max_range * np.mgrid[-1:2:2, -1:2:2, -1:2:2][0].flatten() + 0.5 * (np.amax(xarr) + np.amin(xarr))
yyb = 0.5 * max_range * np.mgrid[-1:2:2, -1:2:2, -1:2:2][1].flatten() + 0.5 * (np.amax(yarr) + np.amin(yarr))
zzb = 0.5 * max_range * np.mgrid[-1:2:2, -1:2:2, -1:2:2][2].flatten() + 0.5 * (np.amax(zarr) + np.amin(zarr))
for xb, yb, zb in zip(xxb, yyb, zzb):
ax.plot([xb], [yb], [zb], 'w')
ax.set_xlim(xlimit_pl[0], xlimit_pl[1])
ax.set_ylim(ylimit_pl[0], ylimit_pl[1])
ax.set_zlim(zlimit_pl[0], zlimit_pl[1])
if leglab is not None:
plt.legend()
plt.show()