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.
Files changed (25) hide show
  1. {plotastrodata-1.9.8/plotastrodata.egg-info → plotastrodata-1.9.9}/PKG-INFO +1 -1
  2. {plotastrodata-1.9.8 → plotastrodata-1.9.9}/plotastrodata/__init__.py +1 -1
  3. {plotastrodata-1.9.8 → plotastrodata-1.9.9}/plotastrodata/plot_utils.py +126 -107
  4. {plotastrodata-1.9.8 → plotastrodata-1.9.9/plotastrodata.egg-info}/PKG-INFO +1 -1
  5. {plotastrodata-1.9.8 → plotastrodata-1.9.9}/LICENSE +0 -0
  6. {plotastrodata-1.9.8 → plotastrodata-1.9.9}/MANIFEST.in +0 -0
  7. {plotastrodata-1.9.8 → plotastrodata-1.9.9}/README.md +0 -0
  8. {plotastrodata-1.9.8 → plotastrodata-1.9.9}/plotastrodata/analysis_utils.py +0 -0
  9. {plotastrodata-1.9.8 → plotastrodata-1.9.9}/plotastrodata/const_utils.py +0 -0
  10. {plotastrodata-1.9.8 → plotastrodata-1.9.9}/plotastrodata/coord_utils.py +0 -0
  11. {plotastrodata-1.9.8 → plotastrodata-1.9.9}/plotastrodata/ext_utils.py +0 -0
  12. {plotastrodata-1.9.8 → plotastrodata-1.9.9}/plotastrodata/fft_utils.py +0 -0
  13. {plotastrodata-1.9.8 → plotastrodata-1.9.9}/plotastrodata/fits_utils.py +0 -0
  14. {plotastrodata-1.9.8 → plotastrodata-1.9.9}/plotastrodata/fitting_utils.py +0 -0
  15. {plotastrodata-1.9.8 → plotastrodata-1.9.9}/plotastrodata/los_utils.py +0 -0
  16. {plotastrodata-1.9.8 → plotastrodata-1.9.9}/plotastrodata/matrix_utils.py +0 -0
  17. {plotastrodata-1.9.8 → plotastrodata-1.9.9}/plotastrodata/noise_utils.py +0 -0
  18. {plotastrodata-1.9.8 → plotastrodata-1.9.9}/plotastrodata/other_utils.py +0 -0
  19. {plotastrodata-1.9.8 → plotastrodata-1.9.9}/plotastrodata.egg-info/SOURCES.txt +0 -0
  20. {plotastrodata-1.9.8 → plotastrodata-1.9.9}/plotastrodata.egg-info/dependency_links.txt +0 -0
  21. {plotastrodata-1.9.8 → plotastrodata-1.9.9}/plotastrodata.egg-info/not-zip-safe +0 -0
  22. {plotastrodata-1.9.8 → plotastrodata-1.9.9}/plotastrodata.egg-info/requires.txt +0 -0
  23. {plotastrodata-1.9.8 → plotastrodata-1.9.9}/plotastrodata.egg-info/top_level.txt +0 -0
  24. {plotastrodata-1.9.8 → plotastrodata-1.9.9}/setup.cfg +0 -0
  25. {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.8
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
@@ -1,4 +1,4 @@
1
1
  import warnings
2
2
 
3
3
  warnings.simplefilter('ignore', FutureWarning)
4
- __version__ = '1.9.8'
4
+ __version__ = '1.9.9'
@@ -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 = {'drawstyle': 'steps-mid', 'color': 'k'}
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
- if type(coords) is str:
1247
- coords = [coords]
1248
- f = kwargs2instance(AstroFrame, _kw)
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
- if 'ylabel' in _kw:
1257
- ylabel = _kw['ylabel']
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, gauss(v, *gfitres['best'][i]), **_kwgauss)
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='dashed', color='k')
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 type(title[i]) is str:
1298
- title[i] = {'label': 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 = 'Jet', alpha: float = 0.08,
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
- plot_on_wall(sign=sign, axis=axis, **kw)
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.8
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