plotastrodata 1.9.8__tar.gz → 1.9.9__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {plotastrodata-1.9.8/plotastrodata.egg-info → plotastrodata-1.9.9}/PKG-INFO +1 -1
- {plotastrodata-1.9.8 → plotastrodata-1.9.9}/plotastrodata/__init__.py +1 -1
- {plotastrodata-1.9.8 → plotastrodata-1.9.9}/plotastrodata/plot_utils.py +126 -107
- {plotastrodata-1.9.8 → plotastrodata-1.9.9/plotastrodata.egg-info}/PKG-INFO +1 -1
- {plotastrodata-1.9.8 → plotastrodata-1.9.9}/LICENSE +0 -0
- {plotastrodata-1.9.8 → plotastrodata-1.9.9}/MANIFEST.in +0 -0
- {plotastrodata-1.9.8 → plotastrodata-1.9.9}/README.md +0 -0
- {plotastrodata-1.9.8 → plotastrodata-1.9.9}/plotastrodata/analysis_utils.py +0 -0
- {plotastrodata-1.9.8 → plotastrodata-1.9.9}/plotastrodata/const_utils.py +0 -0
- {plotastrodata-1.9.8 → plotastrodata-1.9.9}/plotastrodata/coord_utils.py +0 -0
- {plotastrodata-1.9.8 → plotastrodata-1.9.9}/plotastrodata/ext_utils.py +0 -0
- {plotastrodata-1.9.8 → plotastrodata-1.9.9}/plotastrodata/fft_utils.py +0 -0
- {plotastrodata-1.9.8 → plotastrodata-1.9.9}/plotastrodata/fits_utils.py +0 -0
- {plotastrodata-1.9.8 → plotastrodata-1.9.9}/plotastrodata/fitting_utils.py +0 -0
- {plotastrodata-1.9.8 → plotastrodata-1.9.9}/plotastrodata/los_utils.py +0 -0
- {plotastrodata-1.9.8 → plotastrodata-1.9.9}/plotastrodata/matrix_utils.py +0 -0
- {plotastrodata-1.9.8 → plotastrodata-1.9.9}/plotastrodata/noise_utils.py +0 -0
- {plotastrodata-1.9.8 → plotastrodata-1.9.9}/plotastrodata/other_utils.py +0 -0
- {plotastrodata-1.9.8 → plotastrodata-1.9.9}/plotastrodata.egg-info/SOURCES.txt +0 -0
- {plotastrodata-1.9.8 → plotastrodata-1.9.9}/plotastrodata.egg-info/dependency_links.txt +0 -0
- {plotastrodata-1.9.8 → plotastrodata-1.9.9}/plotastrodata.egg-info/not-zip-safe +0 -0
- {plotastrodata-1.9.8 → plotastrodata-1.9.9}/plotastrodata.egg-info/requires.txt +0 -0
- {plotastrodata-1.9.8 → plotastrodata-1.9.9}/plotastrodata.egg-info/top_level.txt +0 -0
- {plotastrodata-1.9.8 → plotastrodata-1.9.9}/setup.cfg +0 -0
- {plotastrodata-1.9.8 → plotastrodata-1.9.9}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: plotastrodata
|
|
3
|
-
Version: 1.9.
|
|
3
|
+
Version: 1.9.9
|
|
4
4
|
Summary: plotastrodata is a tool for astronomers to create figures from FITS files and perform fundamental data analyses with ease.
|
|
5
5
|
Home-page: https://github.com/yusukeaso-astron/plotastrodata
|
|
6
6
|
Download-URL: https://github.com/yusukeaso-astron/plotastrodata
|
|
@@ -8,6 +8,7 @@ from typing import TypeVar
|
|
|
8
8
|
from plotastrodata.analysis_utils import AstroData, AstroFrame
|
|
9
9
|
from plotastrodata.coord_utils import (coord2xy, xy2coord,
|
|
10
10
|
get_hmdm, get_min, get_sec)
|
|
11
|
+
from plotastrodata.fitting_utils import gaussian1d
|
|
11
12
|
from plotastrodata.noise_utils import estimate_rms
|
|
12
13
|
from plotastrodata.other_utils import (close_figure, listing,
|
|
13
14
|
reform_grid, reform_data)
|
|
@@ -1199,6 +1200,55 @@ class PlotAstroData(AstroFrame):
|
|
|
1199
1200
|
return fig, self.ax[0]
|
|
1200
1201
|
|
|
1201
1202
|
|
|
1203
|
+
def _get_ylabel_profile(_kw: dict, Tb: bool, flux: bool, bunit: str
|
|
1204
|
+
) -> str:
|
|
1205
|
+
if "ylabel" in _kw:
|
|
1206
|
+
return _kw["ylabel"]
|
|
1207
|
+
if Tb:
|
|
1208
|
+
return r"$T_b$ (K)"
|
|
1209
|
+
if flux:
|
|
1210
|
+
return "Flux (Jy)"
|
|
1211
|
+
return bunit
|
|
1212
|
+
|
|
1213
|
+
|
|
1214
|
+
def _prep_plotprofile(width: int, coords: list | str,
|
|
1215
|
+
xlist: list, ylist: list, ellipse: list,
|
|
1216
|
+
ninterp: int, flux: bool, gaussfit: bool,
|
|
1217
|
+
_kw: dict) -> tuple:
|
|
1218
|
+
if isinstance(coords, str):
|
|
1219
|
+
coords = [coords]
|
|
1220
|
+
Tb = _kw.get("Tb", False)
|
|
1221
|
+
f = kwargs2instance(AstroFrame, _kw)
|
|
1222
|
+
d = kwargs2instance(AstroData, _kw)
|
|
1223
|
+
f.read(d)
|
|
1224
|
+
d.binning([width, 1, 1])
|
|
1225
|
+
v, prof, gfitres = d.profile(coords=coords, xlist=xlist, ylist=ylist,
|
|
1226
|
+
ellipse=ellipse, ninterp=ninterp,
|
|
1227
|
+
flux=flux, gaussfit=gaussfit)
|
|
1228
|
+
ylabel = _get_ylabel_profile(_kw, Tb, flux, d.bunit)
|
|
1229
|
+
if isinstance(ylabel, str):
|
|
1230
|
+
ylabel = [ylabel] * len(prof)
|
|
1231
|
+
_kw.setdefault("xlim", [v.min(), v.max()])
|
|
1232
|
+
pa2 = kwargs2instance(PlotAxes2D, _kw)
|
|
1233
|
+
return v, prof, gfitres, pa2, ylabel
|
|
1234
|
+
|
|
1235
|
+
|
|
1236
|
+
def _set_figax_plotprofile(fig, ax, nrows: int, ncols: int,
|
|
1237
|
+
nprof: int) -> tuple:
|
|
1238
|
+
if ncols == 1:
|
|
1239
|
+
nrows = nprof
|
|
1240
|
+
if fig is None:
|
|
1241
|
+
fig = plt.figure(figsize=(6 * ncols, 3 * nrows))
|
|
1242
|
+
if nprof > 1 and ax is not None:
|
|
1243
|
+
print("External ax is supported only when len(coords)=1.")
|
|
1244
|
+
ax = None
|
|
1245
|
+
ax = np.empty(nprof, dtype=object) if ax is None else [ax]
|
|
1246
|
+
for i in range(nprof):
|
|
1247
|
+
sharex = None if i < nrows - 1 else ax[i - 1]
|
|
1248
|
+
ax[i] = fig.add_subplot(nrows, ncols, i + 1, sharex=sharex)
|
|
1249
|
+
return fig, ax
|
|
1250
|
+
|
|
1251
|
+
|
|
1202
1252
|
def plotprofile(coords: list[str] | str = [],
|
|
1203
1253
|
xlist: list[float] = [], ylist: list[float] = [],
|
|
1204
1254
|
ellipse: list[float, float, float] | None = None,
|
|
@@ -1208,11 +1258,9 @@ def plotprofile(coords: list[str] | str = [],
|
|
|
1208
1258
|
title: list[str] | None = None,
|
|
1209
1259
|
text: list[str] | None = None,
|
|
1210
1260
|
nrows: int = 0, ncols: int = 1,
|
|
1211
|
-
fig: object | None = None,
|
|
1212
|
-
ax: object | None = None,
|
|
1261
|
+
fig: object | None = None, ax: object | None = None,
|
|
1213
1262
|
getfigax: bool = False,
|
|
1214
|
-
savefig: dict | str | None = None,
|
|
1215
|
-
show: bool = False,
|
|
1263
|
+
savefig: dict | str | None = None, show: bool = False,
|
|
1216
1264
|
**kwargs) -> tuple[object, object]:
|
|
1217
1265
|
"""Use Axes.plot of matplotlib to plot line profiles at given coordinates. kwargs must include the arguments of AstroData to specify the data to be plotted. kwargs must include the arguments of AstroFrame to specify the ranges and so on for plotting. kwargs can include the arguments of PlotAxes2D to adjust x and y axes.
|
|
1218
1266
|
|
|
@@ -1239,63 +1287,29 @@ def plotprofile(coords: list[str] | str = [],
|
|
|
1239
1287
|
Returns:
|
|
1240
1288
|
tuple: (fig, ax), where ax is a list, if getfigax=True. Otherwise, no return.
|
|
1241
1289
|
"""
|
|
1242
|
-
_kw = {
|
|
1290
|
+
_kw = {"drawstyle": "steps-mid", "color": "k",
|
|
1291
|
+
"xlabel": r"Velocity (km s$^{-1}$)", "samexy": False}
|
|
1243
1292
|
_kw.update(kwargs)
|
|
1244
1293
|
_kwgauss = {'drawstyle': 'default', 'color': 'g'}
|
|
1245
1294
|
_kwgauss.update(gauss_kwargs)
|
|
1246
|
-
|
|
1247
|
-
coords
|
|
1248
|
-
|
|
1249
|
-
d = kwargs2instance(AstroData, _kw)
|
|
1250
|
-
f.read(d)
|
|
1251
|
-
d.binning([width, 1, 1])
|
|
1252
|
-
v, prof, gfitres = d.profile(coords=coords, xlist=xlist, ylist=ylist,
|
|
1253
|
-
ellipse=ellipse, ninterp=ninterp,
|
|
1254
|
-
flux=flux, gaussfit=gaussfit)
|
|
1295
|
+
v, prof, gfitres, pa2, ylabel \
|
|
1296
|
+
= _prep_plotprofile(width, coords, xlist, ylist, ellipse,
|
|
1297
|
+
ninterp, flux, gaussfit, _kw)
|
|
1255
1298
|
nprof = len(prof)
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
elif d.Tb:
|
|
1259
|
-
ylabel = r'$T_b$ (K)'
|
|
1260
|
-
elif flux:
|
|
1261
|
-
ylabel = 'Flux (Jy)'
|
|
1262
|
-
else:
|
|
1263
|
-
ylabel = d.bunit
|
|
1264
|
-
if type(ylabel) is str:
|
|
1265
|
-
ylabel = [ylabel] * nprof
|
|
1266
|
-
|
|
1267
|
-
def gauss(x, p, c, w):
|
|
1268
|
-
return p * np.exp(-4. * np.log(2.) * ((x - c) / w)**2)
|
|
1269
|
-
|
|
1270
|
-
set_rcparams(20, 'w')
|
|
1271
|
-
if ncols == 1:
|
|
1272
|
-
nrows = nprof
|
|
1273
|
-
if fig is None:
|
|
1274
|
-
fig = plt.figure(figsize=(6 * ncols, 3 * nrows))
|
|
1275
|
-
if nprof > 1 and ax is not None:
|
|
1276
|
-
print('External ax is supported only when len(coords)=1.')
|
|
1277
|
-
ax = None
|
|
1278
|
-
ax = np.empty(nprof, dtype='object') if ax is None else [ax]
|
|
1279
|
-
if 'xlabel' not in _kw:
|
|
1280
|
-
_kw['xlabel'] = 'Velocity (km s$^{-1}$)'
|
|
1281
|
-
if 'xlim' not in _kw:
|
|
1282
|
-
_kw['xlim'] = [v.min(), v.max()]
|
|
1283
|
-
_kw['samexy'] = False
|
|
1284
|
-
pa2 = kwargs2instance(PlotAxes2D, _kw)
|
|
1299
|
+
set_rcparams(20, "w")
|
|
1300
|
+
fig, ax = _set_figax_plotprofile(fig, ax, nrows, ncols, nprof)
|
|
1285
1301
|
for i in range(nprof):
|
|
1286
|
-
sharex = None if i < nrows - 1 else ax[i - 1]
|
|
1287
|
-
ax[i] = fig.add_subplot(nrows, ncols, i + 1, sharex=sharex)
|
|
1288
1302
|
if gaussfit:
|
|
1289
|
-
ax[i].plot(v,
|
|
1303
|
+
ax[i].plot(v, gaussian1d(v, *gfitres["best"][i]), **_kwgauss)
|
|
1290
1304
|
ax[i].plot(v, prof[i], **_kw)
|
|
1291
|
-
ax[i].hlines([0], v.min(), v.max(), linestyle=
|
|
1305
|
+
ax[i].hlines([0], v.min(), v.max(), linestyle="dashed", color="k")
|
|
1292
1306
|
ax[i].set_ylabel(ylabel[i])
|
|
1293
1307
|
pa2.set_xyaxes(ax[i])
|
|
1294
1308
|
if text is not None:
|
|
1295
1309
|
ax[i].text(**text[i])
|
|
1296
1310
|
if title is not None:
|
|
1297
|
-
if
|
|
1298
|
-
title[i] = {
|
|
1311
|
+
if isinstance(title[i], str):
|
|
1312
|
+
title[i] = {"label": title[i]}
|
|
1299
1313
|
ax[i].set_title(**title[i])
|
|
1300
1314
|
if i <= nprof - ncols - 1:
|
|
1301
1315
|
plt.setp(ax[i].get_xticklabels(), visible=False)
|
|
@@ -1369,8 +1383,69 @@ def plotslice(length: float, dx: float | None = None, pa: float = 0,
|
|
|
1369
1383
|
close_figure(fig, savefig, show)
|
|
1370
1384
|
|
|
1371
1385
|
|
|
1386
|
+
def _plot_on_wall(d: AstroData, x: np.ndarray, y: np.ndarray, v: np.ndarray,
|
|
1387
|
+
measure: object, datalist: list,
|
|
1388
|
+
sign: int, axis: int, **kwargs):
|
|
1389
|
+
dx, dy, dv = x[1] - x[0], y[1] - y[0], v[1] - v[0]
|
|
1390
|
+
s, ds = [x, y, v], [dx, dy, dv]
|
|
1391
|
+
if kwargs == {}:
|
|
1392
|
+
return
|
|
1393
|
+
|
|
1394
|
+
match axis:
|
|
1395
|
+
case 2:
|
|
1396
|
+
shape = np.shape(d.data[:, :, 0])
|
|
1397
|
+
case 1:
|
|
1398
|
+
shape = np.shape(d.data[:, 0, :])
|
|
1399
|
+
case 0:
|
|
1400
|
+
shape = np.shape(d.data[0, :, :])
|
|
1401
|
+
if np.shape(kwargs['data']) != shape:
|
|
1402
|
+
print('The shape of the 2D data is inconsistent'
|
|
1403
|
+
+ ' with the shape of the 3D data.')
|
|
1404
|
+
return
|
|
1405
|
+
|
|
1406
|
+
_kw = {'levels': [3, 6, 12, 24, 48, 96, 192, 384],
|
|
1407
|
+
'sigma': 'hist', 'cmap': 'Jet', 'alpha': 0.3}
|
|
1408
|
+
_kw.update(kwargs)
|
|
1409
|
+
volume = _kw['data']
|
|
1410
|
+
levels = _kw['levels']
|
|
1411
|
+
cmap = _kw['cmap']
|
|
1412
|
+
alpha = _kw['alpha']
|
|
1413
|
+
sigma = estimate_rms(data=volume, sigma=_kw['sigma'])
|
|
1414
|
+
volume[np.isnan(volume)] = 0
|
|
1415
|
+
a = int(sign == -1)
|
|
1416
|
+
b = int(sign == 1)
|
|
1417
|
+
volume = np.moveaxis([volume * a, volume * b], 0, axis)
|
|
1418
|
+
if d.dx < 0:
|
|
1419
|
+
volume = volume[:, :, ::-1]
|
|
1420
|
+
if d.dy < 0:
|
|
1421
|
+
volume = volume[:, ::-1, :]
|
|
1422
|
+
if d.dv < 0:
|
|
1423
|
+
volume = volume[::-1, :, :]
|
|
1424
|
+
for lev in levels:
|
|
1425
|
+
if lev * sigma > np.max(volume):
|
|
1426
|
+
continue
|
|
1427
|
+
vertices, simplices, _, _ = measure.marching_cubes(volume, lev * sigma)
|
|
1428
|
+
Xg, Yg, Zg = [t[0] + i * dt for t, i, dt
|
|
1429
|
+
in zip(s, vertices.T[::-1], ds)]
|
|
1430
|
+
match axis:
|
|
1431
|
+
case 2:
|
|
1432
|
+
Xg = Xg * 0 + (x[-1] if sign == 1 else x[0])
|
|
1433
|
+
case 1:
|
|
1434
|
+
Yg = Yg * 0 + (y[-1] if sign == 1 else y[0])
|
|
1435
|
+
case 0:
|
|
1436
|
+
Zg = Zg * 0 + (v[-1] if sign == 1 else v[0])
|
|
1437
|
+
i, j, k = simplices.T
|
|
1438
|
+
mesh2d = dict(type='mesh3d', x=Xg, y=Yg, z=Zg,
|
|
1439
|
+
i=i, j=j, k=k,
|
|
1440
|
+
intensity=Zg * 0 + lev,
|
|
1441
|
+
colorscale=cmap, reversescale=False,
|
|
1442
|
+
cmin=np.min(levels), cmax=np.max(levels),
|
|
1443
|
+
opacity=alpha, name='', showscale=False)
|
|
1444
|
+
datalist.append(mesh2d)
|
|
1445
|
+
|
|
1446
|
+
|
|
1372
1447
|
def plot3d(levels: list[float] = [3, 6, 12],
|
|
1373
|
-
cmap: str = '
|
|
1448
|
+
cmap: str = 'jet', alpha: float = 0.08,
|
|
1374
1449
|
xlabel: str = 'R.A. (arcsec)',
|
|
1375
1450
|
ylabel: str = 'Dec. (arcsec)',
|
|
1376
1451
|
vlabel: str = 'Velocity (km/s)',
|
|
@@ -1461,67 +1536,11 @@ def plot3d(levels: list[float] = [3, 6, 12],
|
|
|
1461
1536
|
name='', line=dict(color='rgb(0,0,0)', width=1))
|
|
1462
1537
|
data.append(lines)
|
|
1463
1538
|
|
|
1464
|
-
def plot_on_wall(sign: int, axis: int, **kwargs):
|
|
1465
|
-
if kwargs == {}:
|
|
1466
|
-
return
|
|
1467
|
-
|
|
1468
|
-
match axis:
|
|
1469
|
-
case 2:
|
|
1470
|
-
shape = np.shape(d.data[:, :, 0])
|
|
1471
|
-
case 1:
|
|
1472
|
-
shape = np.shape(d.data[:, 0, :])
|
|
1473
|
-
case 0:
|
|
1474
|
-
shape = np.shape(d.data[0, :, :])
|
|
1475
|
-
if np.shape(kwargs['data']) != shape:
|
|
1476
|
-
print('The shape of the 2D data is inconsistent'
|
|
1477
|
-
+ ' with the shape of the 3D data.')
|
|
1478
|
-
return
|
|
1479
|
-
|
|
1480
|
-
_kw = {'levels': [3, 6, 12, 24, 48, 96, 192, 384],
|
|
1481
|
-
'sigma': 'hist', 'cmap': 'Jet', 'alpha': 0.3}
|
|
1482
|
-
_kw.update(kwargs)
|
|
1483
|
-
volume = _kw['data']
|
|
1484
|
-
levels = _kw['levels']
|
|
1485
|
-
cmap = _kw['cmap']
|
|
1486
|
-
alpha = _kw['alpha']
|
|
1487
|
-
sigma = estimate_rms(data=volume, sigma=_kw['sigma'])
|
|
1488
|
-
volume[np.isnan(volume)] = 0
|
|
1489
|
-
a = int(sign == -1)
|
|
1490
|
-
b = int(sign == 1)
|
|
1491
|
-
volume = np.moveaxis([volume * a, volume * b], 0, axis)
|
|
1492
|
-
if d.dx < 0:
|
|
1493
|
-
volume = volume[:, :, ::-1]
|
|
1494
|
-
if d.dy < 0:
|
|
1495
|
-
volume = volume[:, ::-1, :]
|
|
1496
|
-
if d.dv < 0:
|
|
1497
|
-
volume = volume[::-1, :, :]
|
|
1498
|
-
for lev in levels:
|
|
1499
|
-
if lev * sigma > np.max(volume):
|
|
1500
|
-
continue
|
|
1501
|
-
vertices, simplices, _, _ = measure.marching_cubes(volume, lev * sigma)
|
|
1502
|
-
Xg, Yg, Zg = [t[0] + i * dt for t, i, dt
|
|
1503
|
-
in zip(s, vertices.T[::-1], ds)]
|
|
1504
|
-
match axis:
|
|
1505
|
-
case 2:
|
|
1506
|
-
Xg = Xg * 0 + (x[-1] if sign == 1 else x[0])
|
|
1507
|
-
case 1:
|
|
1508
|
-
Yg = Yg * 0 + (y[-1] if sign == 1 else y[0])
|
|
1509
|
-
case 0:
|
|
1510
|
-
Zg = Zg * 0 + (v[-1] if sign == 1 else v[0])
|
|
1511
|
-
i, j, k = simplices.T
|
|
1512
|
-
mesh2d = dict(type='mesh3d', x=Xg, y=Yg, z=Zg,
|
|
1513
|
-
i=i, j=j, k=k,
|
|
1514
|
-
intensity=Zg * 0 + lev,
|
|
1515
|
-
colorscale=cmap, reversescale=False,
|
|
1516
|
-
cmin=np.min(levels), cmax=np.max(levels),
|
|
1517
|
-
opacity=alpha, name='', showscale=False)
|
|
1518
|
-
data.append(mesh2d)
|
|
1519
|
-
|
|
1520
1539
|
klist = [xplus, xminus, yplus, yminus, vplus, vminus]
|
|
1521
1540
|
slist = [1, -1, 1, -1, 1, -1]
|
|
1522
1541
|
alist = [2, 2, 1, 1, 0, 0]
|
|
1523
1542
|
for kw, sign, axis in zip(klist, slist, alist):
|
|
1524
|
-
|
|
1543
|
+
_plot_on_wall(d, x, y, v, measure, data, sign, axis, **kw)
|
|
1525
1544
|
|
|
1526
1545
|
if return_data_layout:
|
|
1527
1546
|
return {'data': data, 'layout': layout}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: plotastrodata
|
|
3
|
-
Version: 1.9.
|
|
3
|
+
Version: 1.9.9
|
|
4
4
|
Summary: plotastrodata is a tool for astronomers to create figures from FITS files and perform fundamental data analyses with ease.
|
|
5
5
|
Home-page: https://github.com/yusukeaso-astron/plotastrodata
|
|
6
6
|
Download-URL: https://github.com/yusukeaso-astron/plotastrodata
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|