import dustpy.constants as c
from dustpy.utils import read_data
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider
[docs]
def panel(data, filename="data", extension="hdf5", im=0, ir=0, it=0, show_limits=True, show_St1=True):
"""Simple plotting script for data files or simulation objects.
Parameters
----------
data : ``dustpy.Simulation`` or string
Either instance of ``dustpy.Simulation`` or path to data directory to be plotted
filename : string, optional, default : "data"
extension : string, optional, default : "hdf5"
Plotting script is looking for files with pattern ``<data>/<filename>*.<extension>``
im : int, optional, default : 0
Number of mass bin along which density distribution is plotted
ir : int, optional, default : 0
Number of radial grid index along density distribution is plotted
it : int, optional, default : 0
Index of snapshot to be plotted
show_limits : boolean, optional, default : True
If True growth limits are plotted
show_St1 : boolean, optional, default : True
If True St=1 line is plotted"""
data = read_data(data, filename=filename, extension=extension)
# Helper
# Fix indices if necessary
it = np.maximum(0, it)
it = np.minimum(it, data.Nt-1)
it = int(it)
im = np.maximum(0, im)
im = np.minimum(im, data.grid.Nm-1)
im = int(im)
ir = np.maximum(0, ir)
ir = np.minimum(ir, data.grid.Nr-1)
ir = int(ir)
# Get limits/levels
sd_max = np.ceil(np.log10(data.dust.sigma.max()))
sg_max = np.ceil(np.log10(data.gas.Sigma.max()))
Mmax = np.ceil(np.log10(data.gas.M.max()/c.M_sun)) + 1
levels = np.linspace(sd_max-6, sd_max, 7)
width = 3.5
fig = plt.figure(figsize=(3.*width, 2.*width/1.618), dpi=150)
ax00 = fig.add_subplot(231)
ax01 = fig.add_subplot(232)
ax02 = fig.add_subplot(233)
ax10 = fig.add_subplot(234)
ax11 = fig.add_subplot(235)
ax11r = ax11.twinx()
# Density distribution
plt00 = ax00.contourf(data.grid.r[it, ...]/c.au,
data.grid.m[it, ...],
np.log10(data.dust.sigma[it, ...].T),
levels=levels,
cmap="magma",
extend="both"
)
if show_St1:
ax00.contour(data.grid.r[it, ...]/c.au,
data.grid.m[it, ...],
data.dust.St[it, ...].T,
levels=[1.],
colors="white",
linewidths=2
)
if show_limits:
ax00.contour(data.grid.r[it, ...]/c.au,
data.grid.m[it, ...],
(data.dust.St - data.dust.St_limits.drift[..., None])[it, ...].T,
levels=[0.],
colors="C2",
linewidths=1
)
ax00.contour(data.grid.r[it, ...]/c.au,
data.grid.m[it, ...],
(data.dust.St - data.dust.St_limits.frag[..., None])[it, ...].T,
levels=[0.],
colors="C0",
linewidths=1
)
ax00.axhline(data.grid.m[it, im], color="#AAAAAA", lw=1, ls="--")
ax00.axvline(data.grid.r[it, ir]/c.au, color="#AAAAAA", lw=1, ls="--")
cbar00 = plt.colorbar(plt00, ax=ax00)
cbar00.ax.set_ylabel(r"$\sigma_\mathrm{d}$ [g/cm²]")
cbar00ticklabels = []
for i in levels:
cbar00ticklabels.append("$10^{{{:d}}}$".format(int(i)))
cbar00.ax.set_yticklabels(cbar00ticklabels)
ax00.set_xlim(data.grid.r[it, 0]/c.au, data.grid.r[it, -1]/c.au)
ax00.set_xscale("log")
ax00.set_yscale("log")
ax00.set_xlabel("Distance from star [AU]")
ax00.set_ylabel("Particle mass [g]")
ax01.loglog(data.grid.m[it, ...], data.dust.sigma[it, ir, :], c="C3")
ax01.axvline(data.grid.m[it, im], color="#AAAAAA", lw=1, ls="--")
ax01.set_xlim(data.grid.m[it, 0], data.grid.m[it, -1])
ylim1 = np.ceil(np.log10(np.max(data.dust.sigma[it, ir, :])))
ylim0 = ylim1 - 6.
ax01.set_ylim(10.**ylim0, 10.**ylim1)
ax01.set_xlabel("Particle mass [g]")
ax01.set_ylabel(r"$\sigma_\mathrm{d}$ [g/cm²]")
if data.Nt < 3:
ax02.set_xticks([0., 1.])
ax02.set_yticks([0., 1.])
ax02.text(0.5,
0.5,
"Not enough data points.",
verticalalignment="center",
horizontalalignment="center",
size="large")
else:
ax02.loglog(data.t/c.year, data.gas.M/c.M_sun, c="C0", label="Gas")
ax02.loglog(data.t/c.year, data.dust.M /
c.M_sun, c="C1", label="Dust")
ax02.axvline(data.t[it]/c.year, c="#AAAAAA", lw=1, ls="--")
ax02.set_xlim(data.t[1]/c.year, data.t[-1]/c.year)
ax02.set_ylim(10.**(Mmax-6.), 10.**Mmax)
ax02.legend()
ax02.set_xlabel("Time [yrs]")
ax02.set_ylabel(r"Mass [$M_\odot$]")
ax10.loglog(data.grid.r[it, ...]/c.au, data.dust.sigma[it, :, im], c="C3")
ax10.axvline(data.grid.r[it, ir]/c.au, color="#AAAAAA", lw=1, ls="--")
ax10.set_xlim(data.grid.r[it, 0]/c.au, data.grid.r[it, -1]/c.au)
ylim1 = np.ceil(np.log10(np.max(data.dust.sigma[it, :, im])))
ylim0 = ylim1 - 6.
ax10.set_xlabel("Distance from star [au]")
ax10.set_ylabel(r"$\sigma_\mathrm{d}$ [g/cm²]")
ax11.loglog(data.grid.r[it, ...]/c.au, data.gas.Sigma[it, ...], label="Gas")
ax11.loglog(data.grid.r[it, ...]/c.au,
data.dust.Sigma[it, ...].sum(-1), label="Dust")
ax11.axvline(data.grid.r[it, ir]/c.au, color="#AAAAAA", lw=1, ls="--")
ax11.set_xlim(data.grid.r[it, 0]/c.au, data.grid.r[it, -1]/c.au)
ax11.set_ylim(10.**(sg_max-6), 10.**sg_max)
ax11.set_xlabel("Distance from star [AU]")
ax11.set_ylabel(r"$\Sigma$ [g/cm²]")
ax11.legend()
ax11r.loglog(data.grid.r[it, ...]/c.au, data.dust.eps[it, ...], color="C7", lw=1)
ax11r.set_ylim(1.e-5, 1.e1)
ax11r.set_ylabel("Dust-to-gas ratio")
fig.set_layout_engine("tight")
plt.show()
[docs]
def ipanel(data, filename="data", extension="hdf5", im=0, ir=0, it=0, show_limits=True, show_St1=True):
"""Simple interactive plotting script for data files or simulation objects.
Parameters
----------
data : ``dustpy.Simulation`` or string
Either instance of ``dustpy.Simulation`` or path to data directory to be plotted
filename : string, optional, default : "data"
extension : string, optional, default : "hdf5"
Plotting script is looking for files with pattern ``<data>/<filename>*.<extension>``
im : int, optional, default : 0
Number of mass bin along which density distribution is plotted
ir : int, optional, default : 0
Number of radial grid index along density distribution is plotted
it : int, optional, default : 0
Index of snapshot to be plotted
show_limits : boolean, optional, default : True
If True growth limits are plotted
show_St1 : boolean, optional, default : True
If True St=1 line is plotted"""
global plt00
global plt00Dr
global plt00Fr
global plt00St
data = read_data(data, filename=filename, extension=extension)
# Fix indices if necessary
it = np.maximum(0, it)
it = np.minimum(it, data.Nt-1)
it = int(it)
im = np.maximum(0, im)
im = np.minimum(im, data.grid.Nm-1)
im = int(im)
ir = np.maximum(0, ir)
ir = np.minimum(ir, data.grid.Nr-1)
ir = int(ir)
# Get limits/levels
sd_max = np.ceil(np.log10(data.dust.sigma.max()))
sg_max = np.ceil(np.log10(data.gas.Sigma.max()))
Mmax = np.ceil(np.log10(data.gas.M.max()/c.M_sun)) + 1
levels = np.linspace(sd_max-6, sd_max, 7)
width = 3.5
fig = plt.figure(figsize=(3.*width, 2.*width/1.618), dpi=150)
ax00 = fig.add_subplot(231)
ax01 = fig.add_subplot(232)
ax02 = fig.add_subplot(233)
ax10 = fig.add_subplot(234)
ax11 = fig.add_subplot(235)
ax11r = ax11.twinx()
# Density distribution
plt00 = ax00.contourf(data.grid.r[it, ...]/c.au,
data.grid.m[it, ...],
np.log10(data.dust.sigma[it, ...].T),
levels=levels,
cmap="magma",
extend="both"
)
if show_St1:
plt00St = ax00.contour(data.grid.r[it, ...]/c.au,
data.grid.m[it, ...],
data.dust.St[it, ...].T,
levels=[1.],
colors="white",
linewidths=2
)
if show_limits:
plt00Dr = ax00.contour(data.grid.r[it, ...]/c.au,
data.grid.m[it, ...],
(data.dust.St - data.dust.St_limits.drift[..., None])[it, ...].T,
levels=[0.],
colors="C2",
linewidths=1
)
plt00Fr = ax00.contour(data.grid.r[it, ...]/c.au,
data.grid.m[it, ...],
(data.dust.St - data.dust.St_limits.frag[..., None])[it, ...].T,
levels=[0.],
colors="C0",
linewidths=1
)
plt00hl = ax00.axhline(data.grid.m[it, im], color="#AAAAAA", lw=1, ls="--")
plt00vl = ax00.axvline(data.grid.r[it, ir]/c.au, color="#AAAAAA", lw=1, ls="--")
cbar00 = plt.colorbar(plt00, ax=ax00)
cbar00.ax.set_ylabel(r"$\sigma_\mathrm{d}$ [g/cm²]")
cbar00ticklabels = []
for i in levels:
cbar00ticklabels.append("$10^{{{:d}}}$".format(int(i)))
cbar00.ax.set_yticklabels(cbar00ticklabels)
ax00.set_xlim(data.grid.r[it, 0]/c.au, data.grid.r[it, -1]/c.au)
ax00.set_xscale("log")
ax00.set_yscale("log")
ax00.set_xlabel("Distance from star [AU]")
ax00.set_ylabel("Particle mass [g]")
plt01 = ax01.loglog(data.grid.m[it, ...], data.dust.sigma[it, ir, :], c="C3")
plt01vl = ax01.axvline(data.grid.m[it, im], color="#AAAAAA", lw=1, ls="--")
ax01.set_xlim(data.grid.m[it, 0], data.grid.m[it, -1])
ylim1 = np.ceil(np.log10(np.max(data.dust.sigma[it, ir, :])))
ylim0 = ylim1 - 6.
ax01.set_ylim(10.**ylim0, 10.**ylim1)
ax01.set_xlabel("Particle mass [g]")
ax01.set_ylabel(r"$\sigma_\mathrm{d}$ [g/cm²]")
if data.Nt < 3:
ax02.set_xticks([0., 1.])
ax02.set_yticks([0., 1.])
ax02.text(0.5,
0.5,
"Not enough data points.",
verticalalignment="center",
horizontalalignment="center",
size="large")
else:
ax02.loglog(data.t/c.year, data.gas.M/c.M_sun, c="C0", label="Gas")
ax02.loglog(data.t/c.year, data.dust.M /
c.M_sun, c="C1", label="Dust")
plt02vl = ax02.axvline(data.t[it]/c.year, c="#AAAAAA", lw=1, ls="--")
ax02.set_xlim(data.t[1]/c.year, data.t[-1]/c.year)
ax02.set_ylim(10.**(Mmax-6.), 10.**Mmax)
ax02.legend()
ax02.set_xlabel("Time [yrs]")
ax02.set_ylabel(r"Mass [$M_\odot$]")
plt10 = ax10.loglog(data.grid.r[it, ...]/c.au,
data.dust.sigma[it, :, im], c="C3")
plt10vl = ax10.axvline(data.grid.r[it, ir]/c.au, color="#AAAAAA", lw=1, ls="--")
ax10.set_xlim(data.grid.r[it, 0]/c.au, data.grid.r[it, -1]/c.au)
ylim1 = np.ceil(np.log10(np.max(data.dust.sigma[it, :, im])))
ylim0 = ylim1 - 6.
ax10.set_ylim(10.**ylim0, 10.**ylim1)
ax10.set_xlabel("Distance from star [au]")
ax10.set_ylabel(r"$\sigma_\mathrm{d}$ [g/cm²]")
plt11g = ax11.loglog(data.grid.r[it, ...]/c.au,
data.gas.Sigma[it, ...], label="Gas")
plt11d = ax11.loglog(data.grid.r[it, ...]/c.au,
data.dust.Sigma[it, ...].sum(-1), label="Dust")
plt11vl = ax11.axvline(data.grid.r[it, ir]/c.au, color="#AAAAAA", lw=1, ls="--")
ax11.set_xlim(data.grid.r[it, 0]/c.au, data.grid.r[it, -1]/c.au)
ax11.set_ylim(10.**(sg_max-6), 10.**sg_max)
ax11.set_xlabel("Distance from star [AU]")
ax11.set_ylabel(r"$\Sigma$ [g/cm²]")
ax11.legend()
plt11d2g = ax11r.loglog(data.grid.r[it, ...]/c.au,
data.dust.eps[it, ...], color="C7", lw=1)
ax11r.set_ylim(1.e-5, 1.e1)
ax11r.set_ylabel("Dust-to-gas ratio")
fig.tight_layout()
width = ax02.get_position().x1 - ax02.get_position().x0
fig._widgets = []
if data.Nt > 2:
axSliderTime = plt.axes([ax02.get_position().x0 + 0.15 * width,
0.375,
0.75 * width,
0.02], facecolor="lightgoldenrodyellow")
sliderTime = Slider(axSliderTime, "Time", 0, int(data.Nt -
1), valinit=it, valfmt="%i")
axSliderTime.set_title("t = {:9.3e} yr".format(data.t[it]/c.year))
fig._widgets += [sliderTime]
axSliderMass = plt.axes([ax02.get_position().x0 + 0.15 * width,
0.25,
0.75 * width,
0.02], facecolor="lightgoldenrodyellow")
sliderMass = Slider(axSliderMass, "Mass", 0,
int(data.grid.Nm-1), valinit=im, valfmt="%i")
axSliderMass.set_title("m = {:9.3e} g".format(data.grid.m[it, im]))
fig._widgets += [sliderMass]
axSliderDist = plt.axes([ax02.get_position().x0 + 0.15 * width,
0.125,
0.75 * width,
0.02], facecolor="lightgoldenrodyellow")
sliderDist = Slider(axSliderDist, "Distance", 0,
int(data.grid.Nr-1), valinit=ir, valfmt="%i")
axSliderDist.set_title("r = {:9.3e} AU".format(data.grid.r[it, ir]/c.au))
fig._widgets += [sliderDist]
def update(val):
global plt00
global plt00Dr
global plt00Fr
global plt00St
it = 0
if data.Nt > 2:
it = int(np.floor(sliderTime.val))
axSliderTime.set_title("t = {:9.3e} yr".format(data.t[it]/c.year))
im = int(np.floor(sliderMass.val))
axSliderMass.set_title("m = {:9.3e} g".format(data.grid.m[it, im]))
ir = int(np.floor(sliderDist.val))
axSliderDist.set_title("r = {:9.3e} AU".format(data.grid.r[it, ir]/c.au))
plt00.remove()
plt00 = ax00.contourf(data.grid.r[it, ...]/c.au,
data.grid.m[it, ...],
np.log10(data.dust.sigma[it, ...].T),
levels=np.linspace(sd_max-6, sd_max, 7),
cmap="magma",
extend="both"
)
if show_St1:
plt00St.remove()
plt00St = ax00.contour(data.grid.r[it, ...]/c.au,
data.grid.m[it, ...],
data.dust.St[it, ...].T,
levels=[1.],
colors="white",
linewidths=2
)
if show_limits:
plt00Dr.remove()
plt00Dr = ax00.contour(data.grid.r[it, ...]/c.au,
data.grid.m[it, ...],
(data.dust.St - data.dust.St_limits.drift[..., None])[it, ...].T,
levels=[0.],
colors="C2",
linewidths=1
)
plt00Fr.remove()
plt00Fr = ax00.contour(data.grid.r[it, ...]/c.au,
data.grid.m[it, ...],
(data.dust.St - data.dust.St_limits.frag[..., None])[it, ...].T,
levels=[0.],
colors="C0",
linewidths=1
)
plt00vl.set_xdata([data.grid.r[it, ir]/c.au, data.grid.r[it, ir]/c.au])
plt00hl.set_ydata([data.grid.m[it, im], data.grid.m[it, im]])
plt01[0].set_xdata(data.grid.m[it, ...])
plt01[0].set_ydata(data.dust.sigma[it, ir, :])
ax01.set_xlim(data.grid.m[it, 0], data.grid.m[it, -1])
ylim1 = np.ceil(np.log10(np.max(data.dust.sigma[it, ir, :])))
ylim0 = ylim1 - 6.
ax01.set_ylim(10.**ylim0, 10.**ylim1)
plt01vl.set_xdata([data.grid.m[it, im], data.grid.m[it, im]])
plt01vl.set_ydata([0., 1.e100])
if data.Nt > 2:
plt02vl.set_xdata([data.t[it]/c.year, data.t[it]/c.year])
plt10vl.set_xdata([data.grid.r[it, ir]/c.au, data.grid.r[it, ir]/c.au])
plt11vl.set_xdata([data.grid.r[it, ir]/c.au, data.grid.r[it, ir]/c.au])
plt10[0].set_xdata(data.grid.r[it, ...]/c.au)
plt10[0].set_ydata(data.dust.sigma[it, :, im])
ax10.set_xlim(data.grid.r[it, 0]/c.au, data.grid.r[it, -1]/c.au)
ylim1 = np.ceil(np.log10(np.max(data.dust.sigma[it, :, im])))
ylim0 = ylim1 - 6.
ax10.set_ylim(10.**ylim0, 10.**ylim1)
plt10vl.set_xdata([data.grid.r[it, ir]/c.au, data.grid.r[it, ir]/c.au])
plt10vl.set_ydata([0., 1.e100])
plt11g[0].set_xdata(data.grid.r[it, ...]/c.au)
plt11g[0].set_ydata(data.gas.Sigma[it, ...])
plt11d[0].set_xdata(data.grid.r[it, ...]/c.au)
plt11d[0].set_ydata(data.dust.Sigma[it, ...].sum(-1))
plt11vl.set_xdata([data.grid.r[it, ir]/c.au, data.grid.r[it, ir]])
plt11vl.set_ydata([0., 1.e100])
plt11d2g[0].set_xdata(data.grid.r[it, ...]/c.au)
plt11d2g[0].set_ydata(data.dust.eps[it, ...])
if data.Nt > 2:
sliderTime.on_changed(update)
sliderMass.on_changed(update)
sliderDist.on_changed(update)
plt.show()