visualize_4.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. # -*- coding: utf-8 -*-
  2. # Author: Puyuan Du
  3. import os
  4. from datetime import datetime
  5. import numpy as np
  6. import matplotlib.pyplot as plt
  7. from matplotlib.cm import ScalarMappable
  8. from xarray import Dataset
  9. from cinrad.common import get_dtype
  10. from cinrad.visualize.utils import sec_plot, norm_plot, prodname, save, plot_kw
  11. __all__ = ["Section"]
  12. class Section(object):
  13. def __init__(
  14. self,
  15. data: Dataset,
  16. hlim: int = 15,
  17. interpolate: bool = True,
  18. figsize: tuple = (10, 5),
  19. ):
  20. # TODO: Use context manager to control style
  21. plt.style.use("dark_background")
  22. self.data = data
  23. self.dtype = get_dtype(data)
  24. self.settings = {
  25. "hlim": hlim,
  26. "interp": interpolate,
  27. "figsize": figsize,
  28. }
  29. self.rhi_flag = "azimuth" in data.attrs
  30. self._plot()
  31. def _plot(self):
  32. rhi = self.data[self.dtype]
  33. xcor = self.data["x_cor"]
  34. ycor = self.data["y_cor"]
  35. rmax = np.nanmax(rhi.values)
  36. plt.figure(figsize=self.settings["figsize"], dpi=300)
  37. plt.grid(
  38. True, linewidth=0.50, linestyle="-.", color="white"
  39. ) ## 修改于2019-01-22 By WU Fulang
  40. cmap = sec_plot[self.dtype]
  41. norm = norm_plot[self.dtype]
  42. if self.settings["interp"]:
  43. plt.contourf(
  44. xcor,
  45. ycor,
  46. rhi,
  47. 128,
  48. cmap=cmap,
  49. norm=norm,
  50. )
  51. else:
  52. plt.pcolormesh(xcor, ycor, rhi, cmap=cmap, norm=norm, shading="auto")
  53. plt.ylim(0, self.settings["hlim"])
  54. if self.rhi_flag:
  55. title = "Range-Height Indicator\n"
  56. else:
  57. title = "Vertical cross-section ({})\n".format(prodname[self.dtype])
  58. title += "Station: {} ".format(self.data.site_name)
  59. if self.rhi_flag:
  60. # RHI scan type
  61. title += "Range: {:.0f}km Azimuth: {:.0f}° ".format(
  62. self.data.range, self.data.azimuth
  63. )
  64. else:
  65. title += "Start: {}N {}E ".format(self.data.start_lat, self.data.start_lon)
  66. title += "End: {}N {}E ".format(self.data.end_lat, self.data.end_lon)
  67. title += "Time: " + datetime.strptime(
  68. self.data.scan_time, "%Y-%m-%d %H:%M:%S"
  69. ).strftime("%Y.%m.%d %H:%M ")
  70. title += "Max: {:.1f}".format(rmax)
  71. plt.title(title, **text_kw)
  72. lat_pos = np.linspace(self.data.start_lat, self.data.end_lat, 6)
  73. lon_pos = np.linspace(self.data.start_lon, self.data.end_lon, 6)
  74. tick_formatter = lambda x, y: "{:.2f}N\n{:.2f}E".format(x, y)
  75. ticks = list(map(tick_formatter, lat_pos, lon_pos))
  76. cor_max = xcor.values.max()
  77. plt.xticks(np.array([0, 0.2, 0.4, 0.6, 0.8, 1]) * cor_max, ticks)
  78. plt.ylabel("Height (km)", **text_kw) ## 修改于2019-01-22 By WU Fulang
  79. sm = ScalarMappable(norm=norm, cmap=cmap)
  80. plt.colorbar(sm)
  81. def __call__(self, fpath: str):
  82. if os.path.isdir(fpath):
  83. if self.rhi_flag:
  84. path_string = "{}{}_{}_RHI_{:.0f}_{:.0f}_{}.png".format(
  85. fpath,
  86. self.data.site_code,
  87. datetime.strptime(
  88. self.data.scan_time, "%Y-%m-%d %H:%M:%S"
  89. ).strftime("%Y%m%d%H%M%S"),
  90. self.data.azimuth,
  91. self.data.range,
  92. self.dtype,
  93. )
  94. else:
  95. path_string = "{}_{}_VCS_{}N{}E_{}N{}E.png".format(
  96. self.data.site_code,
  97. datetime.strptime(
  98. self.data.scan_time, "%Y-%m-%d %H:%M:%S"
  99. ).strftime("%Y%m%d%H%M%S"),
  100. self.data.start_lat,
  101. self.data.start_lon,
  102. self.data.end_lat,
  103. self.data.end_lon,
  104. )
  105. save_path = os.path.join(fpath, path_string)
  106. else:
  107. save_path = fpath
  108. save(save_path, bbox_inches="tight")