plotastrodata 1.6.4__tar.gz → 1.7.0__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 (24) hide show
  1. {plotastrodata-1.6.4 → plotastrodata-1.7.0}/PKG-INFO +3 -3
  2. plotastrodata-1.7.0/plotastrodata/__init__.py +4 -0
  3. {plotastrodata-1.6.4 → plotastrodata-1.7.0}/plotastrodata/other_utils.py +17 -12
  4. {plotastrodata-1.6.4 → plotastrodata-1.7.0}/plotastrodata/plot_utils.py +56 -24
  5. {plotastrodata-1.6.4 → plotastrodata-1.7.0}/plotastrodata.egg-info/PKG-INFO +3 -3
  6. {plotastrodata-1.6.4 → plotastrodata-1.7.0}/plotastrodata.egg-info/requires.txt +1 -1
  7. {plotastrodata-1.6.4 → plotastrodata-1.7.0}/setup.cfg +2 -2
  8. plotastrodata-1.6.4/plotastrodata/__init__.py +0 -4
  9. {plotastrodata-1.6.4 → plotastrodata-1.7.0}/LICENSE +0 -0
  10. {plotastrodata-1.6.4 → plotastrodata-1.7.0}/README.md +0 -0
  11. {plotastrodata-1.6.4 → plotastrodata-1.7.0}/plotastrodata/analysis_utils.py +0 -0
  12. {plotastrodata-1.6.4 → plotastrodata-1.7.0}/plotastrodata/const_utils.py +0 -0
  13. {plotastrodata-1.6.4 → plotastrodata-1.7.0}/plotastrodata/coord_utils.py +0 -0
  14. {plotastrodata-1.6.4 → plotastrodata-1.7.0}/plotastrodata/ext_utils.py +0 -0
  15. {plotastrodata-1.6.4 → plotastrodata-1.7.0}/plotastrodata/fft_utils.py +0 -0
  16. {plotastrodata-1.6.4 → plotastrodata-1.7.0}/plotastrodata/fits_utils.py +0 -0
  17. {plotastrodata-1.6.4 → plotastrodata-1.7.0}/plotastrodata/fitting_utils.py +0 -0
  18. {plotastrodata-1.6.4 → plotastrodata-1.7.0}/plotastrodata/los_utils.py +0 -0
  19. {plotastrodata-1.6.4 → plotastrodata-1.7.0}/plotastrodata/matrix_utils.py +0 -0
  20. {plotastrodata-1.6.4 → plotastrodata-1.7.0}/plotastrodata.egg-info/SOURCES.txt +0 -0
  21. {plotastrodata-1.6.4 → plotastrodata-1.7.0}/plotastrodata.egg-info/dependency_links.txt +0 -0
  22. {plotastrodata-1.6.4 → plotastrodata-1.7.0}/plotastrodata.egg-info/not-zip-safe +0 -0
  23. {plotastrodata-1.6.4 → plotastrodata-1.7.0}/plotastrodata.egg-info/top_level.txt +0 -0
  24. {plotastrodata-1.6.4 → plotastrodata-1.7.0}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: plotastrodata
3
- Version: 1.6.4
3
+ Version: 1.7.0
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,10 +8,10 @@ Author: yusukeaso-astron
8
8
  License: GNU General Public License Version 3
9
9
  Keywords: astronomy,FITS,plot
10
10
  Classifier: Programming Language :: Python :: 3
11
- Requires-Python: >=3.10
11
+ Requires-Python: >=3.12
12
12
  Description-Content-Type: text/markdown
13
13
  License-File: LICENSE
14
- Requires-Dist: astropy
14
+ Requires-Dist: astropy>=7.2
15
15
  Requires-Dist: corner
16
16
  Requires-Dist: dynesty
17
17
  Requires-Dist: emcee
@@ -0,0 +1,4 @@
1
+ import warnings
2
+
3
+ warnings.simplefilter('ignore', FutureWarning)
4
+ __version__ = '1.7.0'
@@ -1,5 +1,6 @@
1
+ import warnings
1
2
  import numpy as np
2
- from scipy.optimize import curve_fit
3
+ from scipy.optimize import curve_fit, OptimizeWarning
3
4
  from scipy.special import erf
4
5
  from scipy.interpolate import RegularGridInterpolator as RGI
5
6
 
@@ -59,6 +60,11 @@ def estimate_rms(data: np.ndarray, sigma: float | str | None = 'hist'
59
60
  if sigma is None:
60
61
  return None
61
62
 
63
+ def warning_offset(ave, noise):
64
+ if np.abs(ave) > 0.2 * noise:
65
+ s = 'The intensity offset is larger than 0.2 sigma.'
66
+ warnings.warn(s, UserWarning)
67
+
62
68
  nums = [float, int, np.float64, np.int64, np.float32, np.int32]
63
69
  if type(sigma) in nums:
64
70
  noise = sigma
@@ -68,8 +74,7 @@ def estimate_rms(data: np.ndarray, sigma: float | str | None = 'hist'
68
74
  elif sigma == 'edge':
69
75
  ave = np.nanmean(data[::len(data) - 1])
70
76
  noise = np.nanstd(data[::len(data) - 1])
71
- if np.abs(ave) > 0.2 * noise:
72
- print('Warning: The intensity offset is larger than 0.2 sigma.')
77
+ warning_offset(ave, noise)
73
78
  elif sigma == 'neg':
74
79
  noise = np.sqrt(np.nanmean(data[data < 0]**2))
75
80
  elif sigma == 'med':
@@ -82,8 +87,7 @@ def estimate_rms(data: np.ndarray, sigma: float | str | None = 'hist'
82
87
  n = n[np.abs(n) < 3.5 * sig]
83
88
  ave = np.nanmean(n)
84
89
  noise = np.nanstd(n)
85
- if np.abs(ave) > 0.2 * noise:
86
- print('Warning: The intensity offset is larger than 0.2 sigma.')
90
+ warning_offset(ave, noise)
87
91
  elif sigma == 'out':
88
92
  n, n0, n1 = data.copy(), len(data), len(data[0])
89
93
  n = np.moveaxis(n, [-2, -1], [0, 1])
@@ -95,8 +99,7 @@ def estimate_rms(data: np.ndarray, sigma: float | str | None = 'hist'
95
99
  else:
96
100
  ave = np.nanmean(n)
97
101
  noise = np.nanstd(n)
98
- if np.abs(ave) > 0.2 * noise:
99
- print('Warning: The intensity offset is larger than 0.2 sigma.')
102
+ warning_offset(ave, noise)
100
103
  elif sigma[:4] == 'hist':
101
104
  m0, s0 = np.nanmean(data), np.nanstd(data)
102
105
  hist, hbin = np.histogram(data[~np.isnan(data)],
@@ -108,13 +111,15 @@ def estimate_rms(data: np.ndarray, sigma: float | str | None = 'hist'
108
111
  xn = (x - c) / np.sqrt(2) / s
109
112
  return (erf(xn) - erf(xn * np.exp(-R**2))) / (2 * (x-c) * R**2)
110
113
  else:
111
- def g(x, s, c, R):
112
- return np.exp(-((x-c)/s)**2 / 2) / np.sqrt(2*np.pi) / s
113
- popt, _ = curve_fit(g, hbin, hist, p0=[1, 0, 1])
114
+ def g(x, s, c, _):
115
+ xn = (x - c) / np.sqrt(2) / s
116
+ return np.exp(-xn**2) / np.sqrt(2 * np.pi) / s
117
+ with warnings.catch_warnings():
118
+ warnings.simplefilter('ignore', OptimizeWarning)
119
+ popt, _ = curve_fit(g, hbin, hist, p0=[1, 0, 1])
114
120
  ave = popt[1]
115
121
  noise = popt[0]
116
- if np.abs(ave) > 0.2 * noise:
117
- print('Warning: The intensity offset is larger than 0.2 sigma.')
122
+ warning_offset(ave, noise)
118
123
  noise = noise * s0
119
124
  return noise
120
125
 
@@ -1,3 +1,4 @@
1
+ import warnings
1
2
  import numpy as np
2
3
  import matplotlib as mpl
3
4
  import matplotlib.pyplot as plt
@@ -408,7 +409,7 @@ class PlotAstroData(AstroFrame):
408
409
  figsize = (ncols * 2 / sqrt_a, max(nrows*2, 3) * sqrt_a)
409
410
  for ch in range(nchan):
410
411
  n, i, j = ch2nij(ch)
411
- if internalfig:
412
+ if internalfig and n not in plt.get_fignums():
412
413
  fig = plt.figure(n, figsize=figsize)
413
414
  sharex = ax[nij2ch(n, i - 1, j)] if i > 0 else None
414
415
  sharey = ax[nij2ch(n, i, j - 1)] if j > 0 else None
@@ -431,8 +432,11 @@ class PlotAstroData(AstroFrame):
431
432
  self.allchan = np.arange(nv)
432
433
  self.bottomleft = nij2ch(np.arange(npages), nrows - 1, 0)
433
434
  self.channelnumber = channelnumber
435
+ self.v = v
434
436
 
435
- def vskipfill(c: np.ndarray, v_in: np.ndarray = None) -> np.ndarray:
437
+ def vskipfill(c: np.ndarray,
438
+ v_in: np.ndarray | None = None
439
+ ) -> np.ndarray:
436
440
  """Skip and fill channels with nan.
437
441
 
438
442
  Args:
@@ -442,20 +446,41 @@ class PlotAstroData(AstroFrame):
442
446
  Returns:
443
447
  np.ndarray: 3D arrays skipped and filled with nan.
444
448
  """
445
- if np.ndim(c) == 3:
449
+ if np.ndim(c) == 2:
450
+ d = np.full((nv, *np.shape(c)), c)
451
+ elif np.ndim(c) == 3:
446
452
  if v_in is not None:
447
- if (k0 := np.argmin(np.abs(v - v_in[0]))) > 0:
448
- prenan = np.full((k0, *np.shape(c)[1:]), np.nan)
449
- d = np.append(prenan, c, axis=0)
450
- else:
453
+ dv_org = self.v[1] - self.v[0]
454
+ dv_in = (v_in[1] - v_in[0]) * vskip
455
+ k0 = np.argmin(np.abs(self.v - v_in[0]))
456
+ k1 = np.argmin(np.abs(self.v - v_in[-1]))
457
+ if np.abs(dv_in - dv_org) / dv_org < 0.01:
451
458
  d = c
459
+ else:
460
+ s = 'Velocity resolution mismatch (>1%).' \
461
+ + ' The cube needs to be regridded' \
462
+ + ' outside plotastrodata.'
463
+ warnings.warn(s, UserWarning)
464
+ n_valid = k1 - k0
465
+ d = [None] * n_valid
466
+ for k in range(n_valid):
467
+ k_tmp = np.argmin(np.abs(v_in - self.v[k]))
468
+ diffvel = np.abs(v_in[k_tmp] - self.v[k])
469
+ nearby = diffvel < dv_org * 0.5
470
+ d[k] = c[k_tmp] if nearby else c[0] * np.nan
471
+ d = np.array(d)
472
+ if k0 > 0:
473
+ prenan = np.full((k0, *np.shape(d)[1:]), np.nan)
474
+ d = np.append(prenan, d, axis=0)
452
475
  d = d[::vskip]
453
476
  else:
454
- d = np.full((nv, *np.shape(c)), c)
477
+ print('c must be 2D or 3D.')
478
+ return
455
479
  n = nchan if channelnumber is None else nv
456
480
  shape = (n - len(d), len(d[0]), len(d[0, 0]))
457
- dnan = np.full(shape, d[0] * np.nan)
458
- return np.concatenate((d, dnan), axis=0)
481
+ postnan = np.full(shape, d[0] * np.nan)
482
+ d = np.append(d, postnan, axis=0)
483
+ return d
459
484
  self.vskipfill = vskipfill
460
485
 
461
486
  def _map_init(self, kw: dict) -> tuple:
@@ -746,8 +771,11 @@ class PlotAstroData(AstroFrame):
746
771
  c = self.vskipfill(c, v)
747
772
  if type(self.channelnumber) is int:
748
773
  c = [c[self.channelnumber]]
749
- for axnow, cnow in zip(self.ax, c):
750
- p = axnow.pcolormesh(x, y, cnow, **_kw)
774
+ p = [None] * len(self.ax)
775
+ for ch, (axnow, cnow) in enumerate(zip(self.ax, c)):
776
+ pnow = axnow.pcolormesh(x, y, cnow, **_kw)
777
+ if ch in self.bottomleft:
778
+ p[ch] = pnow
751
779
  for ch in self.bottomleft:
752
780
  if not show_cbar:
753
781
  break
@@ -758,24 +786,28 @@ class PlotAstroData(AstroFrame):
758
786
  else:
759
787
  fig = self.fig
760
788
  if len(self.ax) == 1:
761
- ax = self.ax[0]
762
- cb = fig.colorbar(p, ax=ax, label=cblabel,
789
+ ax = self.ax[ch]
790
+ cb = fig.colorbar(p[ch], ax=ax, label=cblabel,
763
791
  format=cbformat, location=cblocation)
764
792
  else:
765
793
  cax = plt.axes([0.88, 0.105, 0.015, 0.77])
766
- cb = fig.colorbar(p, cax=cax, label=cblabel, format=cbformat)
794
+ cb = fig.colorbar(p[ch], cax=cax, label=cblabel,
795
+ format=cbformat)
767
796
  cb.ax.tick_params(labelsize=14)
768
797
  font = mpl.font_manager.FontProperties(size=16)
769
798
  cb.ax.yaxis.label.set_font_properties(font)
799
+ if cbticks is not None and ch // self.rowcol == 0:
800
+ cbticks = np.array(cbticks)
801
+ match stretch:
802
+ case 'log':
803
+ cbticks = np.log10(cbticks)
804
+ case 'asinh':
805
+ cbticks = np.arcsinh(cbticks / stretchscale)
806
+ case 'power':
807
+ p = 1 - stretchpower
808
+ cbticks = (cbticks / cmin_org)**p - 1
809
+ cbticks = cbticks / p / np.log(10)
770
810
  if cbticks is not None:
771
- if stretch == 'log':
772
- cbticks = np.log10(cbticks)
773
- elif stretch == 'asinh':
774
- cbticks = np.arcsinh(np.array(cbticks) / stretchscale)
775
- elif stretch == 'power':
776
- cbticks = np.array(cbticks)
777
- p = 1 - stretchpower
778
- cbticks = ((cbticks / cmin_org)**p - 1) / p / np.log(10)
779
811
  cb.set_ticks(cbticks)
780
812
  if cbticklabels is not None:
781
813
  cb.set_ticklabels(cbticklabels)
@@ -1112,7 +1144,7 @@ class PlotAstroData(AstroFrame):
1112
1144
  fig.savefig(fname, **_kw)
1113
1145
  if show:
1114
1146
  plt.show()
1115
- plt.close()
1147
+ plt.close('all')
1116
1148
 
1117
1149
  def get_figax(self) -> tuple[object, object]:
1118
1150
  """Output the external fig and ax after plotting.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: plotastrodata
3
- Version: 1.6.4
3
+ Version: 1.7.0
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,10 +8,10 @@ Author: yusukeaso-astron
8
8
  License: GNU General Public License Version 3
9
9
  Keywords: astronomy,FITS,plot
10
10
  Classifier: Programming Language :: Python :: 3
11
- Requires-Python: >=3.10
11
+ Requires-Python: >=3.12
12
12
  Description-Content-Type: text/markdown
13
13
  License-File: LICENSE
14
- Requires-Dist: astropy
14
+ Requires-Dist: astropy>=7.2
15
15
  Requires-Dist: corner
16
16
  Requires-Dist: dynesty
17
17
  Requires-Dist: emcee
@@ -1,4 +1,4 @@
1
- astropy
1
+ astropy>=7.2
2
2
  corner
3
3
  dynesty
4
4
  emcee
@@ -14,9 +14,9 @@ classifiers = Programming Language :: Python :: 3
14
14
  [options]
15
15
  packages = find:
16
16
  zip_safe = False
17
- python_requires = >=3.10
17
+ python_requires = >=3.12
18
18
  install_requires =
19
- astropy
19
+ astropy >= 7.2
20
20
  corner
21
21
  dynesty
22
22
  emcee
@@ -1,4 +0,0 @@
1
- import warnings
2
-
3
- warnings.simplefilter('ignore', UserWarning)
4
- __version__ = '1.6.4'
File without changes
File without changes
File without changes