def write(self, data, data_name, out_file): if self.error: return pb_io.make_sure_path_exists(os.path.dirname(self.ofile)) # 写入 HDF5 文件 with h5py.File(out_file, 'a') as h5: if data_name == "Longitude" or data_name == "Latitude": h5.create_dataset(data_name, dtype='f4', data=data, compression='gzip', compression_opts=5, shuffle=True) elif data_name == "Ocean_Flag": h5.create_dataset(data_name, dtype='i4', data=data, compression='gzip', compression_opts=5, shuffle=True) else: h5.create_dataset(data_name, dtype='i2', data=data, compression='gzip', compression_opts=5, shuffle=True) # 复制属性 attrs = self.attrs[data_name] for key, value in attrs.items(): h5[data_name].attrs[key] = value
def write(self): if self.error: return pb_io.make_sure_path_exists(os.path.dirname(self.ofile)) # 写入 HDF5 文件 with h5py.File(self.ofile, 'w') as h5: for k in self.out_data: # 创建数据集 if k == "Longitude" or k == "Latitude": h5.create_dataset(k, dtype='f4', data=self.out_data[k], compression='gzip', compression_opts=5, shuffle=True) elif k == "Ocean_Flag": continue else: h5.create_dataset(k, dtype='i2', data=self.out_data[k], compression='gzip', compression_opts=5, shuffle=True) # 复制属性 if k == "Longitude" or k == "Latitude" or k == "Ocean_Flag": continue attrs = self.attrs[k] for key, value in attrs.items(): h5[k].attrs[key] = value
def plot(self): """ 绘制快视图 :return: """ if self.error: return try: # 图片大小 self._get_picture_size(self.picture_width) fig = plt.figure(figsize=(self.wight, self.height)) ax1 = plt.subplot2grid((1, 1), (0, 0)) # 背景色 fig.set_facecolor(self.facecolor) # 增加经纬度线 if self.lat_lon_line is not None: self._get_lat_lon_line() if self.error: return ax1.scatter(self.line_lon, self.line_lat, s=0.001, alpha=1) # 添加经纬度的文字 if self.text is not None: self.add_text(ax1) # 绘主图 plt.imshow(self.data, cmap=plt.get_cmap(self.cmap), vmin=self.vmin, vmax=self.vmax) ax1.axis('off') plt.tight_layout() fig.subplots_adjust(bottom=0, top=1, left=0, right=1) colorbar_position = fig.add_axes([0.2, 0.95, 0.6, 0.03]) cb = plt.colorbar(cax=colorbar_position, orientation='horizontal') cb.ax.tick_params(labelsize=8) if self.main_view is not None and "colorbar_ticks" in self.main_view: self.colorbar_ticks = self.main_view["colorbar_ticks"] cb.set_ticks(self.colorbar_ticks) if self.main_view is not None and "colorbar_tick_label" in self.main_view: self.colorbar_tick_label = self.main_view[ "colorbar_tick_label"] cb.set_ticklabels(self.colorbar_tick_label) pb_io.make_sure_path_exists(os.path.dirname(self.out_picture)) fig.savefig(self.out_picture, dpi=200) fig.clear() plt.close() except Exception as why: print "plot: {}".format(why) self.error = True return
def plot_map(lats, lons, values, out_file, box=None): p = dv_map_oc.dv_map() p.show_bg_color = False p.colorbar_fmt = "%0.2f" title = '' # 是否绘制某个区域 if box: lat_s = float(box[0]) lat_n = float(box[1]) lon_w = float(box[2]) lon_e = float(box[3]) box = [lat_s, lat_n, lon_w, lon_e] else: box = [90, -90, -180, 180] # 绘制经纬度线 p.delat = 10 p.delon = 10 if box[0] - box[1] > 90: p.delat = 30 # 30 elif box[2] - box[3] > 180: p.delon = 30 # 30 p.show_line_of_latlon = True # 是否设置 colorbar 范围 if len(values) == 0: return vmin = np.min(values) vmax = np.max(values) # # 是否填写 colorbar title # p.colorbar_label = colorbar_label # # p.colorbar_ticks = legend["ticks"] # # p.colorbar_tick_labels = legend["tick_labels"] p.title = title with time_block("plot combine map", switch=TIME_TEST): p.easyplot(lats, lons, values, ptype=None, vmin=vmin, vmax=vmax, box=box, markersize=2, marker='o') # p.easyplot(lats, lons, value, ptype="pcolormesh", vmin=vmin, vmax=vmax, box=box) pb_io.make_sure_path_exists(os.path.dirname(out_file)) p.savefig(out_file, dpi=300) print '>>> {}'.format(out_file)
def draw_butterfly(sat1Nm, sat2Nm, ymd_s, ymd_e, fy2_lon, fy2_lat, lons, lats, days, out_fig_file): ''' 画 FY2X 匹配蝴蝶图 ''' fig = plt.figure(figsize=(8, 6), dpi=100) # china ax = subplot(111) plt.subplots_adjust(left=0.11, right=0.91, bottom=0.12, top=0.92) m = drawFig_map(fig) maxday = np.max(days) COLORS = ['#d65856', '#d4d656', '#4cd964', '#1abc9c', '#5ac8fa', '#007aff', '#5856d6'] if len(COLORS) < maxday: Log.error('defined COLORS not enough.') return for i in xrange(1, maxday + 1): idx = days == i lons_1day = lons[idx] lats_1day = lats[idx] plot_matchpoint(m, lons_1day, lats_1day, COLORS[i - 1]) x, y = m(fy2_lon, fy2_lat) m.plot(x, y, marker='o', linewidth=0, markerfacecolor=RED, markeredgecolor=EDGE_GRAY, markersize=8, mew=0.2) # ---------legend----------- circle1 = mpatches.Circle((58, 36), 6, color=RED, ec=EDGE_GRAY, lw=0.3) circle_lst = [circle1] for i in xrange(maxday): circle_lst.append(mpatches.Circle((219 + i * 7, 36), 6, color=COLORS[i], ec=EDGE_GRAY, lw=0.3)) fig.patches.extend(circle_lst) TEXT_Y = 0.05 fig.text(0.1, TEXT_Y, '%s' % sat1Nm, color=RED, fontproperties=FONT0) fig.text(0.34, TEXT_Y, '%s' % sat2Nm, color=BLUE, fontproperties=FONT0) if ymd_s != ymd_e: fig.text(0.55, TEXT_Y, '%s-%s' % (ymd_s, ymd_e), fontproperties=FONT0) else: fig.text(0.55, TEXT_Y, '%s' % ymd_s, fontproperties=FONT0) fig.text(0.83, TEXT_Y, ORG_NAME, fontproperties=FONT0) # 设定Map边框粗细 spines = ax.spines for eachspine in spines: spines[eachspine].set_linewidth(0) pb_io.make_sure_path_exists(os.path.dirname(out_fig_file)) fig.savefig(out_fig_file, dpi=100) fig.clear() plt.close()
def plot_bias_map(lat=None, lon=None, data=None, out_file=None, title=None, vmin=None, vmax=None): if title: title = title else: title = "Map" # 绘制偏差的全球分布图,保持0值永远在bar的中心 if vmin is not None and vmax is not None: vmin = vmin vmax = vmax else: datamax = np.max(data) if datamax >= 0: vmin = -1.0 * datamax vmax = datamax else: vmin = datamax vmax = -1.0 * datamax p = dv_map.dv_map() p.colorbar_fmt = '%0.3f' color_list = [ '#000081', '#0000C8', '#1414FF', '#A3A3FF', '#FFA3A3', '#FF1414', '#C70000', '#810000' ] cmap = colors.ListedColormap(color_list, 'indexed') p.easyplot(lat, lon, data, vmin=vmin, vmax=vmax, ptype=None, markersize=0.05, marker='s', colormap=cmap) p.title = title make_sure_path_exists(os.path.dirname(out_file)) p.savefig(out_file) print '>>> {}'.format(out_file)
def draw_butterfly(sat1Nm, sat2Nm, ymd_s, ymd_e, lons, lats, out_fig_file): ''' 画 FY3X 匹配蝴蝶图 ''' # COLORS = ['#4cd964', '#1abc9c', '#5ac8fa', '#007aff', '#5856d6'] COLORS = [RED] fig = plt.figure(figsize=(8, 5), dpi=100) # china # plt.subplots_adjust(left=0.11, right=0.91, bottom=0.12, top=0.92) plt.subplots_adjust(left=0.09, right=0.93, bottom=0.12, top=0.94) ax = subplot(121) m1 = drawFig_map(ax, "north") plot_matchpoint(m1, lons, lats, COLORS[0]) ax = subplot(122) m2 = drawFig_map(ax, "south") plot_matchpoint(m2, lons, lats, COLORS[0]) # ---------legend----------- circle1 = mpatches.Circle((58, 36), 6, color=RED, ec=EDGE_GRAY, lw=0.3) # circle_lst = [circle1] # for i in xrange(1): # circle_lst.append(mpatches.Circle((219 + i * 7, 36), 6, color=COLORS[i], ec=EDGE_GRAY, lw=0.3)) # fig.patches.extend(circle_lst) TEXT_Y = 0.05 fig.text(0.1, TEXT_Y, '%s' % sat1Nm, color=RED, fontproperties=FONT0) # fig.text(0.34, TEXT_Y, '%s' % sat2Nm, color=BLUE, fontproperties=FONT0) if ymd_s != ymd_e: fig.text(0.55, TEXT_Y, '%s-%s' % (ymd_s, ymd_e), fontproperties=FONT0) else: fig.text(0.55, TEXT_Y, '%s' % ymd_s, fontproperties=FONT0) fig.text(0.83, TEXT_Y, ORG_NAME, fontproperties=FONT0) # 设定Map边框粗细 spines = ax.spines for eachspine in spines: spines[eachspine].set_linewidth(0) pb_io.make_sure_path_exists(os.path.dirname(out_fig_file)) fig.savefig(out_fig_file, dpi=100) fig.clear() plt.close()
def _write(self, out_file): if self.error: return pb_io.make_sure_path_exists(os.path.dirname(out_file)) # 写入 HDF5 文件 with h5py.File(out_file, 'w') as h5: # 创建数据集 h5.create_dataset("data_ii", dtype='i2', data=self.data_ii, compression='gzip', compression_opts=1, shuffle=True) h5.create_dataset("data_jj", dtype='i2', data=self.data_jj, compression='gzip', compression_opts=1, shuffle=True) h5.create_dataset("lut_ii", dtype='i2', data=self.lut_ii, compression='gzip', compression_opts=1, shuffle=True) h5.create_dataset("lut_jj", dtype='i2', data=self.lut_jj, compression='gzip', compression_opts=1, shuffle=True)
def plot_regression( data_x=None, data_y=None, out_file=None, title=None, x_label=None, y_label=None, annotate=None, ymd_start=None, ymd_end=None, ymd=None, point_color=True, plot_slope=True, plot_zero=True, ): main_path = os.path.dirname(os.path.dirname(__file__)) style_file = os.path.join(main_path, "cfg", 'histogram.mplstyle') plt.style.use(style_file) fig = plt.figure(figsize=(6, 6)) # fig.subplots_adjust(top=0.88, bottom=0.11, left=0.12, right=0.97) ax1 = plt.subplot2grid((1, 1), (0, 0)) annotate_new = {'left_top': []} if plot_slope: # 绘制回归线 max_value = np.nanmax(data_x) min_value = np.nanmin(data_x) color_regression = '#ff0000' width_regression = 1.0 ab = np.polyfit(data_x, data_y, 1) p1 = np.poly1d(ab) p1_max = p1(max_value) p1_min = p1(min_value) ax1.plot([min_value, max_value], [p1_min, p1_max], color=color_regression, linewidth=width_regression, zorder=100) annotate_new = { 'left_top': ['Slope={:.4f}'.format(ab[0]), 'Offset={:.4f}'.format(ab[1])] } # 绘制对角线 if plot_zero: color_diagonal = '#888888' width_diagonal = 1.0 max_value = abs(np.nanmax(np.concatenate((data_x, data_y)))) min_value = -1 * max_value ax1.plot([min_value, max_value], [min_value, max_value], color=color_diagonal, linewidth=width_diagonal, zorder=80) ax = Scatter(ax1) x_min_value = np.min(data_x) x_max_value = np.max(data_x) y_min_value = np.min(data_y) y_max_value = np.max(data_y) ax.set_x_axis_range(x_min_value, x_max_value) ax.set_y_axis_range(y_min_value, y_max_value) if x_label: ax.set_x_label(x_label) if y_label: ax.set_y_label(y_label) if annotate: if plot_slope: annotate_new['left_top'].extend(annotate['left_top']) else: annotate_new = annotate ax.set_annotate(annotate=annotate_new) size = 1 alpha = 0.8 # 透明度 marker = "o" # 形状 color = "b" # 颜色 ax.set_scatter(size=size, alpha=alpha, marker=marker, color=color) # kde 是否绘制密度点颜色 if point_color: ax.plot_scatter(data_x=data_x, data_y=data_y, kde=True) plt.colorbar(ax.plot_result) else: ax.plot_scatter(data_x=data_x, data_y=data_y, kde=False) # -------------------- plt.tight_layout() fig.suptitle(title, fontsize=11, fontproperties=FONT0) fig.subplots_adjust(bottom=0.13, top=0.88) if ymd_start and ymd_end: fig.text(0.50, 0.02, '%s-%s' % (ymd_start, ymd_end), fontproperties=FONT0) elif ymd: fig.text(0.50, 0.02, '%s' % ymd, fontproperties=FONT0) fig.text(0.8, 0.02, 'OCC', fontproperties=FONT0) # --------------- make_sure_path_exists(os.path.dirname(out_file)) fig.savefig(out_file) fig.clear() plt.close() print '>>> {}'.format(out_file)
def plot_scatter( data_x=None, data_y=None, out_file=None, title=None, x_range=None, y_range=None, x_label=None, y_label=None, annotate=None, ymd_start=None, ymd_end=None, ymd=None, ): main_path = os.path.dirname(os.path.dirname(__file__)) style_file = os.path.join(main_path, "cfg", 'histogram.mplstyle') plt.style.use(style_file) fig = plt.figure(figsize=(6, 4)) # fig.subplots_adjust(top=0.88, bottom=0.11, left=0.12, right=0.97) ax1 = plt.subplot2grid((1, 1), (0, 0)) ax = Scatter(ax1) if x_range: ax.set_x_axis_range(x_range[0], x_range[1]) if y_range: ax.set_y_axis_range(y_range[0], y_range[1]) if x_label: ax.set_x_label(x_label) if y_label: ax.set_y_label(y_label) if annotate: ax.set_annotate(annotate=annotate) size = 1 alpha = 0.8 # 透明度 marker = "o" # 形状 color = "b" # 颜色 ax.set_scatter(size=size, alpha=alpha, marker=marker, color=color) ax.plot_scatter(data_x=data_x, data_y=data_y) # -------------------- plt.tight_layout() fig.suptitle(title, fontsize=11, fontproperties=FONT0) fig.subplots_adjust(bottom=0.2, top=0.88) if ymd_start and ymd_end: fig.text(0.50, 0.02, '%s-%s' % (ymd_start, ymd_end), fontproperties=FONT0) elif ymd: fig.text(0.50, 0.02, '%s' % ymd, fontproperties=FONT0) fig.text(0.8, 0.02, 'OCC', fontproperties=FONT0) # --------------- make_sure_path_exists(os.path.dirname(out_file)) fig.savefig(out_file) fig.clear() plt.close() print '>>> {}'.format(out_file)
def draw_combine(self): """ 通过日合成文件,画数据集的全球分布图 文件中需要有 Latitude 和Longitude 两个数据集 :return: """ try: with h5py.File(self.in_file, 'r') as h5: dataset = h5.get(self.dataset_name) value = dataset[:] slope = dataset.attrs["Slope"] intercept = dataset.attrs["Intercept"] value = value * slope + intercept lats = h5.get("Latitude")[:] lons = h5.get("Longitude")[:] except Exception as why: print why return # 过滤有效范围外的值 idx = np.where(value > 0) # 不计算小于 0 的无效值 if len(idx[0]) == 0: print "Don't have enough valid value: {} {}".format( self.dataset_name, len(idx[0])) return else: print "{} valid value count: {}".format(self.dataset_name, len(idx[0])) value = value[idx] lats = lats[idx] lons = lons[idx] # ############对特殊数据集的值进行处理 # 有一些数据集的数据在绘图时需要取对数,否则无法区分 if self.map is not None and "log10" in self.map: if self.map["log10"]: value = np.log10(value) # 有一些数据按照原来的 slope 不对,需要乘 10 if "Rw" in self.dataset_name: value = value * 10 # ################################# if DEBUG: print "-" * 100 print self.dataset_name d = np.histogram(value, bins=[x * 0.05 for x in xrange(-40, 80)]) for i in xrange(len(d[0])): print "{:10} :: {:10}".format(d[1][i], d[0][i]) print value.min() print value.max() print "-" * 100 p = dv_map_oc.dv_map() p.show_bg_color = True p.colorbar_fmt = "%0.2f" if self.map is not None and "title" in self.map: title = self.map["title"] else: title = self.dataset_name # 绘制经纬度线 if self.map is not None and "lat_lon_line" in self.map: lat_lon_line = self.map["lat_lon_line"] delat = lat_lon_line["delat"] delon = lat_lon_line["delon"] p.delat = delat # 30 p.delon = delon # 30 p.show_line_of_latlon = True else: p.show_line_of_latlon = False # 是否绘制某个区域 if self.map is not None and "area_range" in self.map: area_range = self.map["area_range"] lat_s = float(area_range.get("lat_s")) lat_n = float(area_range.get("lat_n")) lon_w = float(area_range.get("lon_w")) lon_e = float(area_range.get("lon_e")) box = [lat_s, lat_n, lon_w, lon_e] else: box = None # 是否设置 colorbar 范围 if self.map is not None and "legend" in self.map: legend = self.map["legend"] vmin = legend["vmin"] vmax = legend["vmax"] # 是否填写 colorbar title if "label" in legend: colorbar_label = legend["label"] p.colorbar_label = colorbar_label if "ticks" in legend: p.colorbar_ticks = legend["ticks"] if "tick_labels" in legend: p.colorbar_tick_labels = legend["tick_labels"] else: vmin = vmax = None p.title = title with time_block("plot combine map", switch=TIME_TEST): p.easyplot(lats, lons, value, ptype=None, vmin=vmin, vmax=vmax, box=box, markersize=0.1, marker='o') # p.easyplot(lats, lons, value, ptype="pcolormesh", vmin=vmin, vmax=vmax, box=box) pb_io.make_sure_path_exists(os.path.dirname(self.out_file)) p.savefig(self.out_file, dpi=300)
def write(self): """ 将处理后的数据写入 HDF5 文件 """ # 创建生成输出目录 pb_io.make_sure_path_exists(os.path.dirname(self.out_file)) # 写入数据 with h5py.File(self.out_file, 'w') as hdf5: with h5py.File(self.l1_1000m, 'r') as m1000: with h5py.File(self.obc_1000m, 'r') as obc: # 创建输出文件的数据集 for i in xrange(0, 20): channel_name = 'CH_{:02}'.format(i + 1) name = '{}/Dn'.format(channel_name) k = i if k != 4: data = self.Dn[channel_name].astype('u2') else: data = m1000.get('EV_250_Aggr.1KM_Emissive')[:] dtype = 'u2' self._create_dataset(name, data, dtype, hdf5) name = '{}/Ref'.format(channel_name) k = i if k < 4: data = self.ev_250m_ref[k] elif k == 4: data = m1000.get('EV_250_Aggr.1KM_Emissive')[:] else: k = k - 5 data = self.ev_1000m_ref[k] dtype = 'u2' self._create_dataset(name, data, dtype, hdf5) name = '{}/SV'.format(channel_name) k = i if k < 4: data = self.sv_extract_obc[k] elif k == 4: data = obc.get('SV_250m_EMIS')[:] else: k = k - 1 data = self.sv_extract_obc[k] dtype = 'u2' self._create_dataset(name, data, dtype, hdf5) name = '{}/CalCoeff'.format(channel_name) k = i if k < 4: data = self.coeff[k].reshape(-1, 1) elif k == 4: data = np.array([1., 0., 0.]).reshape(-1, 1) else: k = k - 1 data = self.coeff[k].reshape(-1, 1) dtype = 'f4' self._create_dataset(name, data, dtype, hdf5) name = '{}/BB'.format(channel_name) data = m1000.get('BB_DN_average')[i].reshape(-1, 1) dtype = 'f4' self._create_dataset(name, data, dtype, hdf5) name = 'Height' dtype = 'i2' data = m1000.get('Height')[:] self._create_dataset(name, data, dtype, hdf5) name = 'LandCover' dtype = 'u1' data = m1000.get('LandCover')[:] self._create_dataset(name, data, dtype, hdf5) name = 'LandSeaMask' dtype = 'u1' data = m1000.get('LandSeaMask')[:] self._create_dataset(name, data, dtype, hdf5) name = 'Latitude' dtype = 'f4' data = m1000.get('Latitude')[:] self._create_dataset(name, data, dtype, hdf5) name = 'Longitude' dtype = 'f4' data = m1000.get('Longitude')[:] self._create_dataset(name, data, dtype, hdf5) name = 'SolarZenith' dtype = 'i2' data = m1000.get('SolarZenith')[:] self._create_dataset(name, data, dtype, hdf5) name = 'SolarAzimuth' dtype = 'i2' data = m1000.get('SolarAzimuth')[:] self._create_dataset(name, data, dtype, hdf5) name = 'SensorZenith' dtype = 'i2' data = m1000.get('SensorZenith')[:] self._create_dataset(name, data, dtype, hdf5) name = 'SensorAzimuth' dtype = 'i2' data = m1000.get('SensorAzimuth')[:] self._create_dataset(name, data, dtype, hdf5) name = 'Times' dtype = 'i4' data = self.Time self._create_dataset(name, data, dtype, hdf5) # 复制文件属性 pb_io.copy_attrs_h5py(m1000, hdf5) # 添加文件属性 hdf5.attrs['dsl'] = self.dsl
def plot(x, y, weight, picPath, part1, part2, chan, ym, DayOrNight, reference_list, xname, xname_l, xunit, xmin, xmax): """ x: 参考卫星传感器数据 y: FY数据 """ plt.style.use(os.path.join(DV_PATH, 'dv_pub_regression.mplstyle')) if xname_l == "TBB": xname_l = "TB" # 过滤 正负 delta+8倍std 的杂点 ------------ w = 1.0 / weight if weight is not None else None RadCompare = G_reg1d(x, y, w) reg_line = x * RadCompare[0] + RadCompare[1] delta = np.abs(y - reg_line) mean_delta = np.mean(delta) std_delta = np.std(delta) max_y = reg_line + mean_delta + std_delta * 8 min_y = reg_line - mean_delta - std_delta * 8 idx = np.logical_and(y < max_y, y > min_y) x = x[idx] y = y[idx] w = w[idx] if weight is not None else None # ----------------------------------------- if xname == "tbb": step = 5 else: step = 0.1 # 计算回归信息: 斜率,截距,R RadCompare = G_reg1d(x, y, w) # 开始绘图 fig = plt.figure(figsize=(6, 5)) ax1 = plt.subplot2grid((2, 1), (0, 0)) ax2 = plt.subplot2grid((2, 1), (1, 0)) # 图片 Title title = '%s Bias Monthly Statistics\n%s Minus %s %s %s' % \ (xname_l, part1, part2, chan, DayOrNight) # plot 偏差分布图 ------------------------------------------------- # x y 轴范围 distri_xmin = xmin distri_xmax = xmax if xname == "tbb": distri_ymin = -4 distri_ymax = 4 elif xname == "ref": distri_ymin = -0.08 distri_ymax = 0.08 else: distri_ymin = None distri_ymax = None distri_limit = { "xlimit": (distri_xmin, distri_xmax), "ylimit": (distri_ymin, distri_ymax), } distri_locator = { "locator_x": (None, None), "locator_y": (8, 5) } # Distri label distri_label = {} if xunit != "": ylabel = 'D{}({})'.format(xname_l, xunit) else: ylabel = "D{}".format(xname_l) distri_label["ylabel"] = ylabel ref_temp = reference_list[0] # 获取拟合系数 # 获取 MeanBias 信息 bias_range = 0.15 boundary = xmin + (xmax - xmin) * 0.15 bias_info = bias_information(x, y, boundary, bias_range) # 绝对偏差和相对偏差信息 TBB=250K REF=0.25 ab = RadCompare a = ab[0] b = ab[1] if xname == 'tbb': bias_info_md = "TBB Bias ({} K) : {:.4f} K".format( ref_temp, ref_temp - (ref_temp * a + b)) elif xname == 'ref': bias_info_md = "Relative Bias (REF {}) : {:.4f} %".format( ref_temp, (ref_temp - (ref_temp * a + b)) / ref_temp * 100) else: bias_info_md = "" # 配置注释信息 distri_annotate = {"left": [bias_info.get("info_lower"), bias_info.get("info_greater"), bias_info_md]} # 注释线配置 if xname == "tbb": avxline = { 'line_x': ref_temp, 'line_color': '#4cd964', 'line_width': 0.7, 'word': str(ref_temp) + xunit, 'word_color': EDGE_GRAY, 'word_size': 6, 'word_location': (ref_temp, -3.5) } elif xname == "ref": avxline = { 'line_x': ref_temp, 'line_color': '#4cd964', 'line_width': 0.7, 'word': str(ref_temp) + xunit, 'word_color': EDGE_GRAY, 'word_size': 6, 'word_location': (ref_temp, -0.07) } else: avxline = None distri_annotate = None # y=0 线配置 zeroline = {"line_color": '#808080', "line_width": 1.0} # 偏差点配置 scatter_delta = { "scatter_marker": 'o', "scatter_size": 1.5, "scatter_alpha": 0.5, "scatter_linewidth": 0, "scatter_zorder": 100, "scatter_color": BLUE, } # 偏差 fill 配置 background_fill = { "fill_marker": 'o-', "fill_size": 6, "fill_alpha": 0.5, "fill_linewidth": 0.6, "fill_zorder": 50, "fill_color": RED, "fill_step": step, } dv_pub_3d.draw_distribution(ax1, x, y, label=distri_label, ax_annotate=distri_annotate, axislimit=distri_limit, locator=distri_locator, zeroline=zeroline, scatter_delta=scatter_delta, avxline=avxline, background_fill=background_fill, ) # 绘制 Bar 图 ------------------------------------------------- bar_xmin = distri_xmin bar_xmax = distri_xmax bar_ymin = 0 bar_ymax = 7 bar_limit = { "xlimit": (bar_xmin, bar_xmax), "ylimit": (bar_ymin, bar_ymax), } if xname == "tbb": bar_locator = { "locator_x": (None, None), "locator_y": (7, 5) } elif xname == "ref": bar_locator = { "locator_x": (None, None), "locator_y": (7, 5) } else: bar_locator = None # bar 的宽度 if xname == "tbb": width = 3 elif xname == "ref": width = 0.07 else: width = 1 # bar 配置 bar = { "bar_width": width, "bar_color": BLUE, "bar_linewidth": 0, "text_size": 6, "text_font": FONT_MONO, "bar_step": step, } bar_annotate = { "left": ['Total Number: %7d' % len(x)] } bar_label = { "xlabel": '%s %s' % (part2, xname_l) + ( '($%s$)' % xunit if xunit != "" else ""), "ylabel": 'Number of sample points\nlog (base = 10)' } dv_pub_3d.draw_bar(ax2, x, y, label=bar_label, ax_annotate=bar_annotate, axislimit=bar_limit, locator=bar_locator, bar=bar, ) # --------------- plt.tight_layout() # 将 ax1 的 xticklabels 设置为不可见 plt.setp(ax1.get_xticklabels(), visible=False) # 子图的底间距 fig.subplots_adjust(bottom=0.16, top=0.90) FONT1.set_size(11) fig.suptitle(title, fontsize=11, fontproperties=FONT1) fig.text(0.6, 0.02, '%s' % ym, fontsize=11, fontproperties=FONT0) fig.text(0.8, 0.02, ORG_NAME, fontsize=11, fontproperties=FONT0) # --------------- pb_io.make_sure_path_exists(os.path.dirname(picPath)) fig.savefig(picPath) print picPath + '.png' plt.close() fig.clear()
def plot_abc(date_D, a_D, b_D, c_D, date_M, a_M, b_M, c_M, picPath, title, date_s, date_e, var): fig = plt.figure(figsize=(6, 6)) ax1 = plt.subplot(311) ax2 = plt.subplot(312, sharex=ax1) ax3 = plt.subplot(313, sharex=ax1) # format the Xticks xlim_min = pb_time.ymd2date('%04d%02d01' % (date_s.year, date_s.month)) xlim_max = date_e ax1.set_xlim(xlim_min, xlim_max) # format the Yticks\ if var == "tbb-tbb" or var == "ref-ref": ax1.set_ylim(0, 2) ax1.yaxis.set_major_locator(MultipleLocator(0.5)) ax1.yaxis.set_minor_locator(MultipleLocator(0.1)) elif var == "dn-ref": ax1.set_ylim(0.0002, 0.0007) ax1.yaxis.set_major_locator(MultipleLocator(0.0001)) ax1.yaxis.set_minor_locator(MultipleLocator(0.00005)) if var == "tbb-tbb": ax2.set_ylim(-30, 30) ax2.yaxis.set_major_locator(MultipleLocator(10)) ax2.yaxis.set_minor_locator(MultipleLocator(2)) elif var == "ref-ref": ax2.set_ylim(-0.1, 0.1) ax2.yaxis.set_major_locator(MultipleLocator(0.02)) ax2.yaxis.set_minor_locator(MultipleLocator(0.01)) elif var == "dn-ref": ax2.set_ylim(-0.08, 0.08) ax2.yaxis.set_major_locator(MultipleLocator(0.02)) ax2.yaxis.set_minor_locator(MultipleLocator(0.01)) ax3.set_ylim(0, 7) ax3.yaxis.set_major_locator(MultipleLocator(1)) ax3.yaxis.set_minor_locator(MultipleLocator(0.2)) # plot ax1 ------------------------------------------------- plt.sca(ax1) plt.plot(date_D, a_D, 'x', ms=5, markerfacecolor=None, markeredgecolor=BLUE, alpha=0.8, mew=0.3, label='Daily') plt.plot(date_M, a_M, 'o-', ms=4, lw=0.6, c=RED, mew=0, label='Monthly') plt.ylabel('Slope', fontsize=11, fontproperties=FONT0) plt.grid(True) plt.title(title, fontsize=12, fontproperties=FONT0) set_tick_font(ax1) plt.setp(ax1.get_xticklabels(), visible=False) # plot ax2 ------------------------------------------------- plt.sca(ax2) plt.plot(date_D, b_D, 'x', ms=5, markerfacecolor=None, markeredgecolor=BLUE, alpha=0.8, mew=0.3, label='Daily') plt.plot(date_M, b_M, 'o-', ms=4, lw=0.6, c=RED, mew=0, label='Monthly') plt.ylabel('Intercept', fontsize=11, fontproperties=FONT0) plt.grid(True) set_tick_font(ax2) plt.setp(ax2.get_xticklabels(), visible=False) # point number ------------------------------------------------- plt.sca(ax3) plt.fill_between(date_D, 0, c_D, edgecolor=BLUE, facecolor=BLUE, alpha=0.6) # plt.fill_between(date_M, 0, c_M, # edgecolor=RED, facecolor=RED, alpha=0.5) # plt.bar(date_M, c_M, width=1, align='edge', # "center", # color=RED, linewidth=0) plt.plot(date_M, c_M, 'o-', ms=4, lw=0.6, c=RED, mew=0, label='Monthly') plt.ylabel('Number of sample points\nlog (base = 10)', fontsize=11, fontproperties=FONT0) plt.grid(True) set_tick_font(ax3) setXLocator(ax3, xlim_min, xlim_max) # circle1 = mpatches.Circle((430, 563), 5, color=BLUE, ec=EDGE_GRAY, lw=0) # circle2 = mpatches.Circle((508, 563), 5, color=RED, ec=EDGE_GRAY, lw=0) # fig.patches.extend([circle1, circle2]) # # fig.text(0.74, 0.93, 'Daily', color=BLUE, fontproperties=FONT0) # fig.text(0.86, 0.93, 'Monthly', color=RED, fontproperties=FONT0) #--------------- plt.tight_layout() fig.subplots_adjust(bottom=0.14) circle1 = mpatches.Circle((74, 18), 6, color=BLUE, ec=EDGE_GRAY, lw=0) circle2 = mpatches.Circle((164, 18), 6, color=RED, ec=EDGE_GRAY, lw=0) fig.patches.extend([circle1, circle2]) fig.text(0.15, 0.02, 'Daily', color=BLUE, fontproperties=FONT0) fig.text(0.3, 0.02, 'Monthly', color=RED, fontproperties=FONT0) ymd_s, ymd_e = date_s.strftime('%Y%m%d'), date_e.strftime('%Y%m%d') if ymd_s != ymd_e: fig.text(0.50, 0.02, '%s-%s' % (ymd_s, ymd_e), fontproperties=FONT0) else: fig.text(0.50, 0.02, '%s' % ymd_s, fontproperties=FONT0) fig.text(0.8, 0.02, ORG_NAME, fontproperties=FONT0) #--------------- pb_io.make_sure_path_exists(os.path.dirname(picPath)) fig.savefig(picPath) plt.close() fig.clear
def plot(x, y, weight, o_file, num_file, part1, part2, chan, ymd, xname, xname_l, xunit, xmin, xmax, yname, yname_l, yunit, ymin, ymax, is_diagonal, is_monthly): plt.style.use(os.path.join(dvPath, "dv_pub_regression_dev.mplstyle")) # 过滤 正负 delta+8 倍 std 的杂点 ------------------------ w = 1.0 / weight if weight is not None else None RadCompare = G_reg1d(x, y, w) reg_line = x * RadCompare[0] + RadCompare[1] delta = np.abs(y - reg_line) mean_delta = np.mean(delta) std_delta = np.std(delta) max_y = reg_line + mean_delta + std_delta * 8 min_y = reg_line - mean_delta - std_delta * 8 idx = np.logical_and(y < max_y, y > min_y) x = x[idx] y = y[idx] w = w[idx] if weight is not None else None # ----------------------------------------- RadCompare = G_reg1d(x, y, w) length_rad = len(x) bias_and_md = [] # 当 bias 没有被计算的时候,不输出 bias if not is_monthly and is_diagonal: # return [len(x), RadCompare[0], RadCompare[1], RadCompare[4]] fig = plt.figure(figsize=(14, 4.5)) # fig.subplots_adjust(top=0.90) ax1 = plt.subplot2grid((1, 3), (0, 0)) ax2 = plt.subplot2grid((1, 3), (0, 1)) ax3 = plt.subplot2grid((1, 3), (0, 2)) # 图片 Title titleName = "%s-%s" % (xname.upper(), yname.upper()) title = "{} Regression {} Days {}_{} {} {}".format( titleName, num_file, part1, part2, chan, ymd) # 画回归图 ----------------------------------------------- print "draw regression" regress_xmin = xmin regress_xmax = xmax regress_ymin = ymin regress_ymax = ymax regress_axislimit = { "xlimit": (regress_xmin, regress_xmax), "ylimit": (regress_ymin, regress_ymax), } if xunit != "": xlabel = "{} {} (${}$)".format(part1, xname_l, xunit) else: xlabel = "{} {}".format(part1, xname_l) if yunit != "": ylabel = "{} {} (${}$)".format(part2, yname_l, yunit) else: ylabel = "{} {}".format(part2, yname_l) regress_label = { "xlabel": xlabel, "ylabel": ylabel, "fontsize": 14, } if xname == "tbb": regress_locator = {"locator_x": (None, None), "locator_y": (None, 5)} elif xname == "ref": regress_locator = {"locator_x": (None, None), "locator_y": (None, 5)} else: regress_locator = None regress_annotate = { "left": ["{:10}: {:7.4f}".format("Slope", RadCompare[0]), "{:10}: {:7.4f}".format("Intercept", RadCompare[1]), "{:10}: {:7.4f}".format("Cor-Coef", RadCompare[4]), "{:10}: {:7d}".format("Number", length_rad)], "fontsize": 14, } regress_tick = {"fontsize": 14, } regress_diagonal = {"line_color": "#808080", "line_width": 1.2} regress_regressline = {"line_color": "r", "line_width": 1.2} scatter_point = {"scatter_alpha": 0.8} dv_pub_3d_dev.draw_regression( ax1, x, y, label=regress_label, ax_annotate=regress_annotate, tick=regress_tick, axislimit=regress_axislimit, locator=regress_locator, diagonal=regress_diagonal, regressline=regress_regressline, scatter_point=scatter_point, ) # 画偏差分布图 --------------------------------------------- print "draw distribution" distri_xmin = xmin distri_xmax = xmax if xname == "tbb": distri_ymin = -4 distri_ymax = 4 elif xname == "ref": distri_ymin = -0.08 distri_ymax = 0.08 else: distri_ymin = None distri_ymax = None distri_limit = { "xlimit": (distri_xmin, distri_xmax), "ylimit": (distri_ymin, distri_ymax), } # x y 轴标签 xlabel = "{}".format(xname_l) if xname == "tbb": ylabel = "{} bias {}_{} ".format(xname.upper(), part1, part2, ) elif xname == "ref": ylabel = "{} bias {}_{} ".format(xname.capitalize(), part1, part2, ) else: ylabel = "{} bias {}_{} ".format(xname, part1, part2, ) distri_label = { "xlabel": xlabel, "ylabel": ylabel, "fontsize": 14, } # 获取 MeanBias 信息 bias_range = 0.15 boundary = xmin + (xmax - xmin) * 0.15 bias_info = bias_information(x, y, boundary, bias_range) # 格式化 MeanBias 信息 info_lower = "MeanBias(<={:d}%Range)=\n {:.4f}±{:.4f}@{:.4f}".format( int(bias_range * 100), bias_info.get("md_lower"), bias_info.get("std_lower"), bias_info.get("mt_lower")) info_greater = "MeanBias(>{:d}%Range)=\n {:.4f}±{:.4f}@{:.4f}".format( int(bias_range * 100), bias_info.get("md_greater"), bias_info.get("std_greater"), bias_info.get("mt_greater")) # 绝对偏差和相对偏差信息 TBB=250K REF=0.25 ab = RadCompare a = ab[0] b = ab[1] if xname == "tbb": bias = 250 - (250 * a + b) bias_info_md = "TBB Bias(250K):{:.4f}K".format(bias) elif xname == "ref": bias = (0.25 - (0.25 * a + b)) / 0.25 * 100 bias_info_md = "Relative Bias(REF0.25):{:.4f}%".format(bias) else: bias = np.NaN # RMD or TBB bias bias_info_md = "" bias_and_md.append(bias) # Range Mean : 偏差图的 MD 信息 if xname == "tbb": md_greater = bias_info.get("md_greater", np.NaN) md = md_greater elif xname == "ref": md_greater = bias_info.get("md_greater") mt_greater = bias_info.get("mt_greater") if md_greater is not None and mt_greater is not None: md = (md_greater / mt_greater) * 100 else: md = np.NaN else: md = np.NaN bias_and_md.append(md) # 添加注释信息 distri_annotate = {"left": [], "leftbottom": [], "right": [], "fontsize": 14, } distri_annotate.get("left").append(bias_info_md) distri_annotate.get("leftbottom").append(info_lower) distri_annotate.get("leftbottom").append(info_greater) # 添加 tick 信息 distri_tick = {"fontsize": 14, } # 添加间隔数量 if xname == "tbb": distri_locator = {"locator_x": (None, None), "locator_y": (8, 5)} elif xname == "ref": distri_locator = {"locator_x": (None, None), "locator_y": (8, 5)} else: distri_locator = None # y=0 线配置 zeroline = {"line_color": "#808080", "line_width": 1.0} # 偏差点配置 scatter_delta = { "scatter_marker": "o", "scatter_size": 5, "scatter_alpha": 0.8, "scatter_linewidth": 0, "scatter_zorder": 100, "scatter_color": BLUE, } # 偏差回归线配置 regressline = {"line_color": "r", "line_width": 1.2} dv_pub_3d_dev.draw_distribution(ax2, x, y, label=distri_label, ax_annotate=distri_annotate, tick=distri_tick, axislimit=distri_limit, locator=distri_locator, zeroline=zeroline, scatter_delta=scatter_delta, regressline=regressline, ) # 画直方图 -------------------------------------------------- print "draw histogram" histogram_xmin = xmin histogram_xmax = xmax histogram_axislimit = { "xlimit": (histogram_xmin, histogram_xmax), } histogram_xlabel = "{}".format(xname_l) histogram_ylabel = "match point numbers" histogram_label = { "xlabel": histogram_xlabel, "ylabel": histogram_ylabel, "fontsize": 14, } # 添加间隔数量 if xname == "tbb": histogram_locator = {"locator_x": (None, None), "locator_y": (None, 5)} elif xname == "ref": histogram_locator = {"locator_x": (None, None), "locator_y": (None, 5)} else: histogram_locator = None histogram_x = { "label": part1, "color": "red", "alpha": 0.4, "bins": 100, "fontsize": 14, } histogram_y = { "label": part2, "color": "blue", "alpha": 0.4, "bins": 100,"fontsize": 14, } histogram_tick = {"fontsize": 14, } dv_pub_3d_dev.draw_histogram( ax3, x, label=histogram_label, locator=histogram_locator, tick=histogram_tick, axislimit=histogram_axislimit, histogram=histogram_x, ) dv_pub_3d_dev.draw_histogram( ax3, y, label=histogram_label, locator=histogram_locator, tick=histogram_tick, axislimit=histogram_axislimit, histogram=histogram_y, ) elif not is_monthly and not is_diagonal: fig = plt.figure(figsize=(4.5, 4.5)) # fig.subplots_adjust(bottom=0.12, top=0.86) ax1 = plt.subplot2grid((1, 1), (0, 0)) # 图片 Title titleName = "%s-%s" % (xname.upper(), yname.upper()) title = "{} Regression {} Days\n{}_{} {} {}".format( titleName, num_file, part1, part2, chan, ymd) # 画回归图 ---------------------------------------------------- print "draw regression" regress_xmin = xmin regress_xmax = xmax regress_ymin = ymin regress_ymax = ymax regress_axislimit = { "xlimit": (regress_xmin, regress_xmax), "ylimit": (regress_ymin, regress_ymax), } if xunit != "": xlabel = "{} {} (${}$)".format(part1, xname_l, xunit) else: xlabel = "{} {}".format(part1, xname_l) if yunit != "": ylabel = "{} {} (${}$)".format(part2, yname_l, yunit) else: ylabel = "{} {}".format(part2, yname_l) regress_label = { "xlabel": xlabel, "ylabel": ylabel, "fontsize": 14, } if xname == "tbb": regress_locator = {"locator_x": (5, None), "locator_y": (5, 5)} elif xname == "ref": regress_locator = {"locator_x": (None, None), "locator_y": (None, 5)} elif xname == "dn": regress_locator = {"locator_x": (5, None), "locator_y": (None, 5)} else: regress_locator = None regress_annotate = { "left": ["{:10}: {:7.4f}".format("Slope", RadCompare[0]), "{:10}: {:7.4f}".format("Intercept", RadCompare[1]), "{:10}: {:7.4f}".format("Cor-Coef", RadCompare[4]), "{:10}: {:7d}".format("Number", length_rad)], "fontsize": 14, } regress_tick = {"fontsize": 14, } regress_diagonal = {"line_color": "#808080", "line_width": 1.2} regress_regressline = {"line_color": "r", "line_width": 1.2} scatter_point = {"scatter_alpha": 0.8} dv_pub_3d_dev.draw_regression( ax1, x, y, label=regress_label, ax_annotate=regress_annotate, tick=regress_tick, axislimit=regress_axislimit, locator=regress_locator, diagonal=regress_diagonal, regressline=regress_regressline, scatter_point=scatter_point, ) elif is_monthly: o_file = o_file + "_density" fig = plt.figure(figsize=(4.5, 4.5)) # fig.subplots_adjust(bottom=0.12, top=0.86) ax1 = plt.subplot2grid((1, 1), (0, 0)) # 图片 Title Label titleName = "%s-%s" % (xname.upper(), yname.upper()) title = "{} Regression {} Days\n{}_{} {} {}".format( titleName, num_file, part1, part2, chan, ymd) # 画密度图 ----------------------------------------------------- print "draw density" density_xmin = xmin density_xmax = xmax density_ymin = ymin density_ymax = ymax density_axislimit = { "xlimit": (density_xmin, density_xmax), "ylimit": (density_ymin, density_ymax), } if xunit != "": xlabel = "{} {} (${}$)".format(part1, xname_l, xunit) else: xlabel = "{} {}".format(part1, xname_l) if yunit != "": ylabel = "{} {} (${}$)".format(part2, yname_l, yunit) else: ylabel = "{} {}".format(part2, yname_l) density_label = { "xlabel": xlabel, "ylabel": ylabel, "fontsize": 14, } if xname == "tbb": density_locator = {"locator_x": (5, None), "locator_y": (5, 5)} elif xname == "ref": density_locator = {"locator_x": (None, None), "locator_y": (None, 5)} elif xname == "dn": density_locator = {"locator_x": (5, None), "locator_y": (None, 5)} else: density_locator = None density_annotate = { "left": ["{:10}: {:7.4f}".format("Slope", RadCompare[0]), "{:10}: {:7.4f}".format("Intercept", RadCompare[1]), "{:10}: {:7.4f}".format("Cor-Coef", RadCompare[4]), "{:10}: {:7d}".format("Number", length_rad)], "fontsize": 14, } density_tick = {"fontsize": 14, } density_diagonal = {"line_color": "#808080", "line_width": 1.2} density_regressline = {"line_color": "r", "line_width": 1.2} density = { "size": 5, "marker": "o", "alpha": 1 } dv_pub_3d_dev.draw_regression( ax1, x, y, label=density_label, ax_annotate=density_annotate, tick=density_tick, axislimit=density_axislimit, locator=density_locator, diagonal=density_diagonal, regressline=density_regressline, density=density, ) else: print "::::::No output Pic {} : ".format(ymd) return # 自动调整子图间距 plt.tight_layout() if not is_monthly and is_diagonal: fig.subplots_adjust(top=0.90) elif not is_monthly and not is_diagonal: fig.subplots_adjust(bottom=0.12, top=0.86) elif is_monthly: fig.subplots_adjust(bottom=0.12, top=0.86) FONT1.set_size(14) fig.suptitle(title, fontsize=14, fontproperties=FONT1) pb_io.make_sure_path_exists(os.path.dirname(o_file)) fig.savefig(o_file, dpi=100) print o_file + ".png" print "-" * 100 fig.clear() plt.close() return [len(x), RadCompare[0], RadCompare[1], RadCompare[4]], bias_and_md # num, a, b, r, bias and md
def writeTxt(plt_cfg, part1, part2, o_name, ymd, dict_cabr, DayOrNight, isMonthly): ''' 生成abr文件 ymd: YYYYMMDD or YYYYMM ''' if len(ymd) == 6: ymd = ymd + '01' if isMonthly: FileName = os.path.join(ABR_DIR, '%s_%s' % (part1, part2), '%s_%s_%s_%s_Monthly.txt' % (part1, part2, o_name, DayOrNight)) else: FileName = os.path.join(ABR_DIR, '%s_%s' % (part1, part2), '%s_%s_%s_%s_%s.txt' % (part1, part2, o_name, DayOrNight, ymd[:4])) title_line = 'YMD ' newline = '' for chan in plt_cfg['chan']: title_line = title_line + ' Count(%s) Slope(%s) Intercept(%s) RSquared(%s)' % (chan, chan, chan, chan) newline = newline + ' %10d %-10.6f %-10.6f %-10.6f' % (tuple(dict_cabr[o_name][chan])) newline = newline + '\n' # don't forget to end with \n allLines = [] titleLines = [] DICT_TXT = {} pb_io.make_sure_path_exists(os.path.dirname(FileName)) # 写十行头信息 titleLines.append('Sat1: %s\n' % part1) titleLines.append('Sat2: %s\n' % part2) if isMonthly: titleLines.append('TimeRange: since launch\n') titleLines.append(' Monthly\n') else: titleLines.append('TimeRange: %s\n' % ymd[:4]) titleLines.append(' Daily\n') titleLines.append('Day or Night: %s\n' % DayOrNight) titleLines.append('Calc time : %s\n' % get_local_time().strftime('%Y.%m.%d %H:%M:%S')) titleLines.append('\n') titleLines.append('\n') titleLines.append(title_line + '\n') titleLines.append('-' * len(title_line) + '\n') # if os.path.isfile(FileName) and os.path.getsize(FileName) != 0: fp = open(FileName, 'r') for i in xrange(10): fp.readline() # 跳过头十行 Lines = fp.readlines() fp.close() # 使用字典特性,保证时间唯一,读取数据 for Line in Lines: DICT_TXT[Line[:8]] = Line[8:] # 添加或更改数据 DICT_TXT[ymd] = newline # 按照时间排序 newLines = sorted(DICT_TXT.iteritems(), key=lambda d:d[0], reverse=False) for i in xrange(len(newLines)): allLines.append(str(newLines[i][0]) + str(newLines[i][1])) else: allLines.append(ymd + newline) fp = open(FileName, 'w') fp.writelines(titleLines) fp.writelines(allLines) fp.close()
def plot_rmd(date_d, data_d, date_m, data_m, std_m, pic_path, date_s, date_e, sat_name, pair, chan, day_or_night, ref_temp, xname, xname_l, xunit, yname, yname_l, yunit, ): if (np.isnan(data_d)).all(): Log.error('Everything is NaN: %s' % pic_path) return plt.style.use(os.path.join(DV_PATH, 'dv_pub_timeseries.mplstyle')) fig = plt.figure(figsize=(6, 4)) # fig.subplots_adjust(top=0.88, bottom=0.11, left=0.12, right=0.97) ax1 = plt.subplot2grid((1, 1), (0, 0)) # 设置 title 参数 part1, part2 = pair.split('_') title = 'Time Series of REF Relative Bias \n{} Minus {} {} {} REF={}'.format( part1, part2, chan, day_or_night, ref_temp) # plot timeseries -------------------------------------------------------- timeseries_xmin = pb_time.ymd2date( '%04d%02d01' % (date_s.year, date_s.month)) timeseries_xmax = date_e if "FY2" in sat_name: timeseries_ymin = -20 timeseries_ymax = 20 elif "FY3" in sat_name: timeseries_ymin = -20 timeseries_ymax = 20 elif "FY4" in sat_name: timeseries_ymin = -20 timeseries_ymax = 20 else: timeseries_ymin = None timeseries_ymax = None timeseries_axislimit = { "xlimit": (timeseries_xmin, timeseries_xmax), "ylimit": (timeseries_ymin, timeseries_ymax), } # x y 轴标签 timeseries_label = {} if xunit != "": ylabel = 'Relative Bias {}'.format(xunit) else: ylabel = "Relative Bias %" timeseries_label["ylabel"] = ylabel # x, y 轴大刻度的数量,和小刻度的数量 timeseries_locator = {"locator_x": (None, None), "locator_y": (8, 2)} # y=0 线配置 timeseries_zeroline = {"line_color": '#808080', "line_width": 1.0} timeseries_daily = { "marker": 'x', "color": BLUE, "linewidth": None, "markersize": 6, "markerfacecolor": None, "markeredgecolor": BLUE, "alpha": 0.8, "markeredgewidth": 0.3, "label": "Daily", } dv_pub_3d.draw_timeseries( ax1, date_d, data_d, label=timeseries_label, axislimit=timeseries_axislimit, locator=timeseries_locator, zeroline=timeseries_zeroline, timeseries=timeseries_daily, ) timeseries_monthly = { "marker": 'o-', "color": RED, "linewidth": 0.6, "markersize": 5, "markerfacecolor": None, "markeredgecolor": RED, "alpha": 0.8, "markeredgewidth": 0, "label": "Monthly", } background_fill_timeseries = { 'x': date_m, 'y': data_m - std_m, 'y1': data_m + std_m, "color": RED, } dv_pub_3d.draw_timeseries( ax1, date_m, data_m, label=timeseries_label, axislimit=timeseries_axislimit, locator=timeseries_locator, zeroline=timeseries_zeroline, timeseries=timeseries_monthly, background_fill=background_fill_timeseries, ) # -------------------- plt.tight_layout() fig.suptitle(title, fontsize=11, fontproperties=FONT0) fig.subplots_adjust(bottom=0.2, top=0.88) circle1 = mpatches.Circle((74, 15), 6, color=BLUE, ec=EDGE_GRAY, lw=0) circle2 = mpatches.Circle((164, 15), 6, color=RED, ec=EDGE_GRAY, lw=0) fig.patches.extend([circle1, circle2]) fig.text(0.15, 0.02, 'Daily', color=BLUE, fontproperties=FONT0) fig.text(0.3, 0.02, 'Monthly', color=RED, fontproperties=FONT0) ymd_s, ymd_e = date_s.strftime('%Y%m%d'), date_e.strftime('%Y%m%d') if ymd_s != ymd_e: fig.text(0.50, 0.02, '%s-%s' % (ymd_s, ymd_e), fontproperties=FONT0) else: fig.text(0.50, 0.02, '%s' % ymd_s, fontproperties=FONT0) fig.text(0.8, 0.02, ORG_NAME, fontproperties=FONT0) # --------------- pb_io.make_sure_path_exists(os.path.dirname(pic_path)) plt.savefig(pic_path) print pic_path fig.clear() plt.close()
def main(sat_sensor, in_file): """ 对L3数据进行合成 :param sat_sensor: 卫星+传感器 :param in_file: yaml 文件 :return: """ # ######################## 初始化 ########################### # 获取程序所在位置,拼接配置文件 app = InitApp(sat_sensor) if app.error: print "Load config file error." return gc = app.global_config sc = app.sat_config yc = Config(in_file) log = LogServer(gc.path_out_log) # 加载全局配置信息 sat_sensor1 = sat_sensor.split('_')[1] sat_sensor2 = sat_sensor.split('_')[0] sat1, sensor1 = sat_sensor1.split('+') sat2, sensor2 = sat_sensor2.split('+') # 加载卫星配置信息 s_channel1 = sc.name s_channel2 = sc.name timseries_channels_config = sc.timeseries_l2_channels # 加载业务配置信息 # ######################## 开始处理 ########################### print "-" * 100 print "Start plot verify result." if not os.path.isfile(in_file): log.error("File is not exist: {}".format(in_file)) return print "<<< {}".format(in_file) all_files = yc.path_ipath # 加载数据 data_absolute = dict() data_relative = dict() date = dict() ref_s1_all = dict() ref_s2_all = dict() amount_all = dict() date_start = ymd2date(yc.info_ymd_s) date_end = ymd2date(yc.info_ymd_e) point_count_min = 2 result = dict() while date_start <= date_end: ymd_now = date_start.strftime('%Y%m%d') in_files = get_one_day_files(all_files=all_files, ymd=ymd_now, ext='.h5', pattern_ymd=r'.*_(\d{8})') cross_data = ReadCrossDataL2() cross_data.read_cross_data(in_files=in_files) # 循环通道数据 for channel in cross_data.data: if channel not in data_absolute: data_absolute[channel] = list() if channel not in data_relative: data_relative[channel] = list() if channel not in date: date[channel] = list() if channel not in ref_s1_all: ref_s1_all[channel] = list() if channel not in ref_s2_all: ref_s2_all[channel] = list() if channel not in amount_all: amount_all[channel] = list() if channel not in result: result[channel] = dict() if not isinstance(cross_data.data[channel], dict): continue ref_s2 = cross_data.data[channel]['MERSI_FovMean'] fine_count = len(ref_s2) print '---INFO--- {} Points: {}'.format(channel, fine_count) if fine_count < point_count_min: print '***WARNING***Dont have enough point to plot: < {}'.format(point_count_min) continue ref_s1 = cross_data.data[channel]['MODIS_FovMean'] # 过滤 3 倍std之外的点 mean_ref_s2 = np.nanmean(ref_s2) std_ref_s2 = np.nanstd(ref_s2) min_ref_s2 = mean_ref_s2 - 3 * std_ref_s2 max_ref_s2 = mean_ref_s2 + 3 * std_ref_s2 idx = np.logical_and(ref_s2 >= min_ref_s2, ref_s2 <= max_ref_s2) ref_s2 = ref_s2[idx] ref_s1 = ref_s1[idx] # 计算相对偏差和绝对偏差 bias = Bias() absolute_bias = bias.absolute_deviation(ref_s1, ref_s2) relative_bias = bias.relative_deviation(ref_s1, ref_s2) data_absolute[channel].append(np.mean(absolute_bias)) data_relative[channel].append(np.mean(relative_bias)) date[channel].append(date_start) mean_absolute = np.nanmean(absolute_bias) std_absolute = np.nanstd(absolute_bias) amount_absolute = len(absolute_bias) median_absolute = np.nanmedian(absolute_bias) rms_absolute = rms(absolute_bias) mean_relative = np.nanmean(relative_bias) std_relative = np.nanstd(relative_bias) amount_relative = len(relative_bias) median_relative = np.nanmedian(relative_bias) rms_relative = rms(relative_bias) mean_ref_s1 = np.nanmean(ref_s1) std_ref_s1 = np.nanstd(ref_s1) amount_ref_s1 = len(ref_s1) median_ref_s1 = np.nanmedian(ref_s1) rms_ref_s1 = rms(ref_s1) ref_s1_all[channel].append(mean_ref_s1) mean_ref_s2 = np.nanmean(ref_s2) std_ref_s2 = np.nanstd(ref_s2) amount_ref_s2 = len(ref_s2) median_ref_s2 = np.nanmedian(ref_s2) rms_ref_s2 = rms(ref_s2) ref_s2_all[channel].append(mean_ref_s2) amount_all[channel].append(amount_ref_s1) fix_point = sc.plot_scatter_fix_ref f025_absolute, f025_relative = get_dif_pdif(ref_s1, ref_s2, fix_point) result_names = ['Dif_mean', 'Dif_std', 'Dif_median', 'Dif_count', 'Dif_rms', 'Dif_025', 'PDif_mean', 'PDif_std', 'PDif_median', 'PDif_count', 'PDif_rms', 'PDif_025', '{}_MODIS_mean'.format(channel), '{}_MODIS_std'.format(channel), '{}_MODIS_median'.format(channel), '{}_MODIS_count'.format(channel), '{}_MODIS_rms'.format(channel), '{}_MERSI_mean'.format(channel), '{}_MERSI_std'.format(channel), '{}_MERSI_median'.format(channel), '{}_MERSI_count'.format(channel), '{}_MERSI_rms'.format(channel), 'Date'] datas = [mean_absolute, std_absolute, median_absolute, amount_absolute, rms_absolute, f025_absolute, mean_relative, std_relative, median_relative, amount_relative, rms_relative, f025_relative, mean_ref_s1, std_ref_s1, median_ref_s1, amount_ref_s1, rms_ref_s1, mean_ref_s2, std_ref_s2, median_ref_s2, amount_ref_s2, rms_ref_s2, ymd_now] for result_name, data in zip(result_names, datas): if result_name not in result[channel]: result[channel][result_name] = list() else: result[channel][result_name].append(data) date_start = date_start + relativedelta(days=1) for channel in data_absolute: plot_config = timseries_channels_config[channel] dif_y_range = plot_config.get('dif_y_range') pdif_y_range = plot_config.get('pdif_y_range') ref_s1_y_range = plot_config.get('ref_s1_y_range') ref_s2_y_range = plot_config.get('ref_s2_y_range') count_y_range = plot_config.get('count_y_range') absolute_bias = data_absolute[channel] if len(absolute_bias) == 0: print 'Dont have enough point to plot, is 0: {}'.format(channel) continue relative_bias = data_relative[channel] date_channel = date[channel] ref_s1_channel = ref_s1_all[channel] ref_s2_channel = ref_s2_all[channel] amount_channel = amount_all[channel] # 绘制时间序列图 channel1 = channel index_channel1 = s_channel1.index(channel1) channel2 = s_channel2[index_channel1] title_series = '{}_{} {}_{} Time Series'.format(sat_sensor1, channel1, sat_sensor2, channel2) title_ref_s1 = '{}_{} {} Time Series'.format(channel1, sat_sensor1, channel1) title_ref_s2 = '{}_{} {} Time Series'.format(channel2, sat_sensor2, channel2) title_amount = '{}_{} {}_{} Matched Points Count Time Series'.format( sat_sensor1, channel1, sat_sensor2, channel2) y_label_series_absolute = 'Dif {}-{}'.format(sensor1, sensor2) y_label_series_relative = 'PDif ({}/{})-1'.format(sensor1, sensor2) y_label_ref_s1 = '{}'.format(channel1) y_label_ref_s2 = '{}'.format(channel2) y_label_amount = 'Count' picture_path = yc.path_opath # 孙凌添加,出两张图,限制Y轴坐标的图和不限制Y轴坐标的图,这里是限制Y轴坐标的图 picture_name_absolute = 'Time_Series_Dif_{}_{}_{}_{}.png'.format( sat_sensor1, channel1, sat_sensor2, channel2) picture_name_relative = 'Time_Series_PDif_{}_{}_{}_{}.png'.format( sat_sensor1, channel1, sat_sensor2, channel2) picture_name_ref_s1 = 'Time_Series_{}_{}.png'.format(sat_sensor1, channel1) picture_name_ref_s2 = 'Time_Series_{}_{}.png'.format(sat_sensor2, channel2) picture_name_amount = 'Time_Series_Count_{}_{}_{}_{}.png'.format( sat_sensor1, channel1, sat_sensor2, channel2) picture_file_absolute = os.path.join(picture_path, picture_name_absolute) picture_file_relative = os.path.join(picture_path, picture_name_relative) picture_file_ref_s1 = os.path.join(picture_path, picture_name_ref_s1) picture_file_ref_s2 = os.path.join(picture_path, picture_name_ref_s2) picture_file_amount = os.path.join(picture_path, picture_name_amount) plot_time_series(day_data_x=date_channel, day_data_y=absolute_bias, y_range=dif_y_range, out_file=picture_file_absolute, title=title_series, y_label=y_label_series_absolute, ymd_start=yc.info_ymd_s, ymd_end=yc.info_ymd_e, ) plot_time_series(day_data_x=date_channel, day_data_y=relative_bias, y_range=pdif_y_range, out_file=picture_file_relative, title=title_series, y_label=y_label_series_relative, ymd_start=yc.info_ymd_s, ymd_end=yc.info_ymd_e, ) plot_time_series(day_data_x=date_channel, day_data_y=ref_s1_channel, y_range=ref_s1_y_range, out_file=picture_file_ref_s1, title=title_ref_s1, y_label=y_label_ref_s1, ymd_start=yc.info_ymd_s, ymd_end=yc.info_ymd_e, zero_line=False) plot_time_series(day_data_x=date_channel, day_data_y=ref_s2_channel, y_range=ref_s2_y_range, out_file=picture_file_ref_s2, title=title_ref_s2, y_label=y_label_ref_s2, ymd_start=yc.info_ymd_s, ymd_end=yc.info_ymd_e, zero_line=False) plot_time_series(day_data_x=date_channel, day_data_y=amount_channel, y_range=count_y_range, out_file=picture_file_amount, title=title_amount, y_label=y_label_amount, ymd_start=yc.info_ymd_s, ymd_end=yc.info_ymd_e, plot_background=False) # 孙凌添加,出两张图,限制Y轴坐标的图和不限制Y轴坐标的图,这里是不限制Y轴坐标的图 picture_name_absolute = 'Time_Series_Dif_{}_{}_{}_{}_NL.png'.format( sat_sensor1, channel1, sat_sensor2, channel2) picture_name_relative = 'Time_Series_PDif_{}_{}_{}_{}_NL.png'.format( sat_sensor1, channel1, sat_sensor2, channel2) picture_name_ref_s1 = 'Time_Series_{}_{}_NL.png'.format(sat_sensor1, channel1) picture_name_ref_s2 = 'Time_Series_{}_{}_NL.png'.format(sat_sensor2, channel2) picture_name_amount = 'Time_Series_Count_{}_{}_{}_{}_NL.png'.format( sat_sensor1, channel1, sat_sensor2, channel2) picture_file_absolute = os.path.join(picture_path, picture_name_absolute) picture_file_relative = os.path.join(picture_path, picture_name_relative) picture_file_ref_s1 = os.path.join(picture_path, picture_name_ref_s1) picture_file_ref_s2 = os.path.join(picture_path, picture_name_ref_s2) picture_file_amount = os.path.join(picture_path, picture_name_amount) plot_time_series(day_data_x=date_channel, day_data_y=absolute_bias, out_file=picture_file_absolute, title=title_series, y_label=y_label_series_absolute, ymd_start=yc.info_ymd_s, ymd_end=yc.info_ymd_e, ) plot_time_series(day_data_x=date_channel, day_data_y=relative_bias, out_file=picture_file_relative, title=title_series, y_label=y_label_series_relative, ymd_start=yc.info_ymd_s, ymd_end=yc.info_ymd_e, ) plot_time_series(day_data_x=date_channel, day_data_y=ref_s1_channel, out_file=picture_file_ref_s1, title=title_ref_s1, y_label=y_label_ref_s1, ymd_start=yc.info_ymd_s, ymd_end=yc.info_ymd_e, ) plot_time_series(day_data_x=date_channel, day_data_y=ref_s2_channel, out_file=picture_file_ref_s2, title=title_ref_s2, y_label=y_label_ref_s2, ymd_start=yc.info_ymd_s, ymd_end=yc.info_ymd_e, ) plot_time_series(day_data_x=date_channel, day_data_y=amount_channel, out_file=picture_file_amount, title=title_amount, y_label=y_label_amount, ymd_start=yc.info_ymd_s, ymd_end=yc.info_ymd_e, plot_background=False) # 输出HDF5 hdf5_name = '{}_{}_Dif_PDif_Daily.HDF'.format(sat_sensor1, sat_sensor2) out_path = yc.path_opath out_file_hdf5 = os.path.join(out_path, hdf5_name) make_sure_path_exists(out_path) write_hdf5(out_file_hdf5, result) keys = amount_all.keys() keys.sort() for channel in keys: print 'CHANNEL: {} POINT: {}'.format(channel, np.sum(amount_all[channel])) print '-' * 100 # 输出月的HDF5 # 加载数据 data_absolute = dict() data_relative = dict() date = dict() ref_s1_all = dict() ref_s2_all = dict() amount_all = dict() date_start = ymd2date(yc.info_ymd_s) date_end = ymd2date(yc.info_ymd_e) result = dict() while date_start <= date_end: ymd_now = date_start.strftime('%Y%m') in_files = get_one_day_files(all_files=all_files, ymd=ymd_now, ext='.h5', pattern_ymd=r'.*_(\d{6})') cross_data = ReadCrossDataL2() cross_data.read_cross_data(in_files=in_files) # 循环通道数据 for channel in cross_data.data: if channel not in data_absolute: data_absolute[channel] = list() if channel not in data_relative: data_relative[channel] = list() if channel not in date: date[channel] = list() if channel not in ref_s1_all: ref_s1_all[channel] = list() if channel not in ref_s2_all: ref_s2_all[channel] = list() if channel not in amount_all: amount_all[channel] = list() if channel not in result: result[channel] = dict() ref_s1 = cross_data.data[channel]['MERSI_FovMean'] if len(ref_s1) == 0: print '{} {} : Dont have enough point, is 0'.format(ymd_now, channel) continue ref_s2 = cross_data.data[channel]['MODIS_FovMean'] # 过滤 3 倍std之外的点 mean_ref_s1 = np.nanmean(ref_s1) std_ref_s1 = np.nanstd(ref_s1) min_ref_s1 = mean_ref_s1 - 3 * std_ref_s1 max_ref_s1 = mean_ref_s1 + 3 * std_ref_s1 idx = np.logical_and(ref_s1 >= min_ref_s1, ref_s1 <= max_ref_s1) ref_s1 = ref_s1[idx] ref_s2 = ref_s2[idx] # 计算相对偏差和绝对偏差 bias = Bias() absolute_bias = bias.absolute_deviation(ref_s1, ref_s2) relative_bias = bias.relative_deviation(ref_s1, ref_s2) data_absolute[channel].append(np.mean(absolute_bias)) data_relative[channel].append(np.mean(relative_bias)) date[channel].append(date_start) mean_absolute = np.nanmean(absolute_bias) std_absolute = np.nanstd(absolute_bias) amount_absolute = len(absolute_bias) median_absolute = np.nanmedian(absolute_bias) rms_absolute = rms(absolute_bias) mean_relative = np.nanmean(relative_bias) std_relative = np.nanstd(relative_bias) amount_relative = len(relative_bias) median_relative = np.nanmedian(relative_bias) rms_relative = rms(relative_bias) mean_ref_s1 = np.nanmean(ref_s1) std_ref_s1 = np.nanstd(ref_s1) amount_ref_s1 = len(ref_s1) median_ref_s1 = np.nanmedian(ref_s1) rms_ref_s1 = rms(ref_s1) ref_s1_all[channel].append(mean_ref_s1) mean_ref_s2 = np.nanmean(ref_s2) std_ref_s2 = np.nanstd(ref_s2) amount_ref_s2 = len(ref_s2) median_ref_s2 = np.nanmedian(ref_s2) rms_ref_s2 = rms(ref_s2) ref_s2_all[channel].append(mean_ref_s2) amount_all[channel].append(amount_ref_s1) fix_point = sc.plot_scatter_fix_ref f025_absolute, f025_relative = get_dif_pdif(ref_s1, ref_s2, fix_point) result_names = ['Dif_mean', 'Dif_std', 'Dif_median', 'Dif_count', 'Dif_rms', 'Dif_025', 'PDif_mean', 'PDif_std', 'PDif_median', 'PDif_count', 'PDif_rms', 'PDif_025', '{}_MODIS_mean'.format(channel), '{}_MODIS_std'.format(channel), '{}_MODIS_median'.format(channel), '{}_MODIS_count'.format(channel), '{}_MODIS_rms'.format(channel), '{}_MERSI_mean'.format(channel), '{}_MERSI_std'.format(channel), '{}_MERSI_median'.format(channel), '{}_MERSI_count'.format(channel), '{}_MERSI_rms'.format(channel), 'Date'] datas = [mean_absolute, std_absolute, median_absolute, amount_absolute, rms_absolute, f025_absolute, mean_relative, std_relative, median_relative, amount_relative, rms_relative, f025_relative, mean_ref_s1, std_ref_s1, median_ref_s1, amount_ref_s1, rms_ref_s1, mean_ref_s2, std_ref_s2, median_ref_s2, amount_ref_s2, rms_ref_s2, ymd_now] for result_name, data in zip(result_names, datas): if result_name not in result[channel]: result[channel][result_name] = list() else: result[channel][result_name].append(data) date_start = date_start + relativedelta(months=1) # 输出HDF5 hdf5_name = '{}_{}_Dif_PDif_Monthly.HDF'.format(sat_sensor1, sat_sensor2) out_path = yc.path_opath out_file_hdf5 = os.path.join(out_path, hdf5_name) make_sure_path_exists(out_path) write_hdf5(out_file_hdf5, result) print '-' * 100
def draw_butterfly(sat1Nm, sat2Nm, ymd_s, ymd_e, lons, lats, out_fig_file, map_range): """ 画 FY3X 匹配蝴蝶图 """ if len(lons) == 0: return plt.style.use(os.path.join(dvPath, 'dv_pub_map.mplstyle')) # COLORS = ['#4cd964', '#1abc9c', '#5ac8fa', '#007aff', '#5856d6'] COLORS = [RED] if map_range[0] and map_range[1]: fig = plt.figure(figsize=(8, 10), dpi=100) # china plt.subplots_adjust(left=0.09, right=0.93, bottom=0.12, top=0.94) ax1 = plt.subplot2grid((2, 2), (0, 0)) ax2 = plt.subplot2grid((2, 2), (0, 1)) ax3 = plt.subplot2grid((2, 2), (1, 0), colspan=2) # 画两极 polar_range = map_range[0] # 两极范围 m = drawFig_map(ax1, "north", polar_range) plot_matchpoint(m, lons, lats, COLORS[0]) m = drawFig_map(ax2, "south", polar_range) plot_matchpoint(m, lons, lats, COLORS[0]) # 画区域 area_range = map_range[1] # 区域范围 m = drawFig_map(ax3, "area", area_range) plot_matchpoint(m, lons, lats, COLORS[0]) elif map_range[0]: fig = plt.figure(figsize=(8, 5), dpi=100) # china plt.subplots_adjust(left=0.09, right=0.93, bottom=0.12, top=0.94) ax1 = plt.subplot2grid((1, 2), (0, 0)) ax2 = plt.subplot2grid((1, 2), (0, 1)) # 画两极 polar_range = map_range[0] # 两极范围 m = drawFig_map(ax1, "north", polar_range) plot_matchpoint(m, lons, lats, COLORS[0]) m = drawFig_map(ax2, "south", polar_range) plot_matchpoint(m, lons, lats, COLORS[0]) elif map_range[1]: fig = plt.figure(figsize=(8, 5), dpi=100) # china plt.subplots_adjust(left=0.09, right=0.93, bottom=0.12, top=0.94) ax3 = plt.subplot2grid((1, 2), (0, 0), colspan=2) # 画区域 area_range = map_range[1] # 区域范围 m = drawFig_map(ax3, "area", area_range) plot_matchpoint(m, lons, lats, COLORS[0]) # ---------legend----------- # 对整张图片添加文字 TEXT_Y = 0.05 fig.text(0.1, TEXT_Y, '%s' % sat1Nm, color=RED, fontproperties=FONT0) if ymd_s != ymd_e: fig.text(0.55, TEXT_Y, '%s-%s' % (ymd_s, ymd_e), fontproperties=FONT0) else: fig.text(0.55, TEXT_Y, '%s' % ymd_s, fontproperties=FONT0) fig.text(0.83, TEXT_Y, ORG_NAME, fontproperties=FONT0) pb_io.make_sure_path_exists(os.path.dirname(out_fig_file)) fig.savefig(out_fig_file, dpi=100) print out_fig_file print '-' * 50 plt.close() fig.clear()
def plot_histogram(data=None, out_file=None, title=None, x_label=None, y_label=None, bins_count=200, x_range=None, hist_label=None, annotate=None, ymd_start=None, ymd_end=None, ymd=None): """ :param ymd_end: :param ymd_start: :param out_file: str :param data: np.ndarray :param title: str :param x_label: str :param y_label: str :param bins_count: int :param x_range: (int or float, int or float) :param hist_label: str :param annotate: :return: """ main_path = os.path.dirname(os.path.dirname(__file__)) style_file = os.path.join(main_path, "cfg", 'histogram.mplstyle') plt.style.use(style_file) fig = plt.figure(figsize=(6, 4)) # fig.subplots_adjust(top=0.88, bottom=0.11, left=0.12, right=0.97) ax1 = plt.subplot2grid((1, 1), (0, 0)) ax = Histogram(ax1) if x_range: ax.set_x_axis_range(x_range[0], x_range[1]) if x_label: ax.set_x_label(x_label) if y_label: ax.set_y_label(y_label) if annotate: ax.set_annotate(annotate=annotate) ax.set_histogram(bins_count=bins_count) ax.set_histogram(label=hist_label) ax.plot_histogram(data) # -------------------- plt.tight_layout() fig.suptitle(title, fontsize=11, fontproperties=FONT0) fig.subplots_adjust(bottom=0.2, top=0.88) if ymd_start and ymd_end: fig.text(0.50, 0.02, '%s-%s' % (ymd_start, ymd_end), fontproperties=FONT0) elif ymd: fig.text(0.50, 0.02, '%s' % ymd, fontproperties=FONT0) fig.text(0.8, 0.02, 'OCC', fontproperties=FONT0) # --------------- make_sure_path_exists(os.path.dirname(out_file)) plt.savefig(out_file) fig.clear() plt.close() print '>>> {}'.format(out_file)
def draw(self, in_file, proj_file, dataset_name, vmin=None, vmax=None): if self.error: return # 加载 Proj 数据 if os.path.isfile(proj_file): try: with h5py.File(proj_file, 'r') as h5: lut_ii = h5.get("lut_ii")[:] lut_jj = h5.get("lut_jj")[:] data_ii = h5.get("data_ii")[:] data_jj = h5.get("data_jj")[:] except Exception as why: print why print "Can't open file: {}".format(proj_file) return else: print "File does not exist: {}".format(proj_file) return with time_block("Draw load", switch=TIME_TEST): # 加载产品数据 if os.path.isfile(in_file): try: with h5py.File(in_file, 'r') as h5: proj_value = h5.get(dataset_name)[:][data_ii, data_jj] except Exception as why: print why print "Can't open file: {}".format(in_file) return else: print "File does not exist: {}".format(in_file) return if vmin is not None: vmin = vmin if vmax is not None: vmax = vmax p = dv_map.dv_map() p.title = "{} {}".format(dataset_name, self.ymd) # 增加省边界 # p1.show_china_province = True p.delat = 30 p.delon = 30 p.show_line_of_latlon = False # p.colormap = 'gist_rainbow' # p.colormap = 'viridis' # p.colormap = 'brg' # 创建查找表 lookup_table = prj_core( self.cmd, self.res, unit="deg", row=self.row, col=self.col) lookup_table.grid_lonslats() lons = lookup_table.lons lats = lookup_table.lats # 创建完整的数据投影 value = np.full((self.row, self.col), self.fill_value, dtype='f4') value[lut_ii, lut_jj] = proj_value value = np.ma.masked_less_equal(value, 0) # 掩掉 <=0 的数据 # 乘数据的系数,水色产品为 0.001 slope = 0.001 value = value * slope p.easyplot(lats, lons, value, ptype=None, vmin=vmin, vmax=vmax, markersize=0.1, marker='o') out_png_path = os.path.dirname(in_file) out_png = os.path.join(out_png_path, '{}.png'.format(dataset_name)) pb_io.make_sure_path_exists(os.path.dirname(out_png)) p.savefig(out_png, dpi=300)
def plot_time_series(day_data_x=None, day_data_y=None, out_file=None, title=None, x_range=None, y_range=None, y_label=None, y_major_count=None, y_minor_count=None, ymd_start=None, ymd_end=None, ymd=None, zero_line=True, plot_background=True): main_path = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) style_file = os.path.join(main_path, "cfg", 'time_series.mplstyle') plt.style.use(style_file) fig = plt.figure(figsize=(6, 4)) ax1 = plt.subplot2grid((1, 1), (0, 0)) ax = TimeSeries(ax1) # 配置属性 if x_range is None: x_range = [np.min(day_data_x), np.max(day_data_x)] ax.set_x_axis_range(axis_min=x_range[0], axis_max=x_range[1]) if y_range is not None: ax.set_y_axis_range(axis_min=y_range[0], axis_max=y_range[1]) if y_label is not None: ax.set_y_label(y_label) if y_major_count is not None: ax.set_y_major_count(y_major_count) if y_minor_count is not None: ax.set_y_minor_count(y_minor_count) # 绘制日数据长时间序列 ax.set_time_series(maker='o', color=BLUE, line_width=None, marker_size=3, marker_facecolor=None, marker_edgecolor=BLUE, marker_edgewidth=0.3, alpha=0.8, label="Daily") ax.plot_time_series(day_data_x, day_data_y) # 绘制背景填充 if plot_background: month_data_x, month_data_y, month_data_std = get_month_avg_std( day_data_x, day_data_y) ax1.errorbar(month_data_x, month_data_y, yerr=month_data_std, fmt='-o', color=RED, alpha=0.3) # ax.set_time_series(maker='o-', color=RED, line_width=0.6, marker_size=3, # marker_facecolor=None, # marker_edgecolor=RED, marker_edgewidth=0, alpha=0.8, # label="Monthly") # ax.plot_time_series(month_data_x, month_data_y) # ax.set_background_fill(x=month_data_x, # y1=month_data_y - month_data_std, # y2=month_data_y + month_data_std, # color=RED, # alpha=0.1, # ) # ax.plot_background_fill() # 绘制 y=0 线配置,在绘制之间设置x轴范围 if zero_line: ax.plot_zero_line() # 格式化 ax ax.set_ax() # -------------------- plt.tight_layout() fig.suptitle(title, fontsize=11, fontproperties=FONT0) fig.subplots_adjust(bottom=0.2, top=0.88) if ymd_start and ymd_end: fig.text(0.50, 0.02, '%s-%s' % (ymd_start, ymd_end), fontproperties=FONT0) elif ymd: fig.text(0.50, 0.02, '%s' % ymd, fontproperties=FONT0) fig.text(0.8, 0.02, 'OCC', fontproperties=FONT0) # --------------- make_sure_path_exists(os.path.dirname(out_file)) fig.savefig(out_file) fig.clear() plt.close() print '>>> {}'.format(out_file)
def plot(x, y, picPath, part1, part2, chan, ym, DayOrNight, reference_list, xname, xname_l, xunit, xmin, xmax): ''' x: 参考卫星传感器数据 y: FY数据 ''' if xname_l == "TBB": xname_l = "TB" xlim_min = xmin xlim_max = xmax delta = y - x if xname == "tbb": step = 5 else: step = 0.1 T_seg, mean_seg, std_seg, sampleNums = get_bar_data( x, delta, xlim_min, xlim_max, step) RadCompare = G_reg1d(x, y) a, b = RadCompare[0], RadCompare[1] fig = plt.figure(figsize=(6, 5)) ax1 = plt.subplot(211) ax2 = plt.subplot(212, sharex=ax1) # format the Xticks ax1.set_xlim(xlim_min, xlim_max) # format the Yticks if xname == "tbb": ax1.set_ylim(-10, 10) ax1.yaxis.set_major_locator(MultipleLocator(5)) ax1.yaxis.set_minor_locator(MultipleLocator(1)) elif xname == "ref": ax1.set_ylim(-0.3, 0.3) ax1.yaxis.set_major_locator(MultipleLocator(0.1)) ax1.yaxis.set_minor_locator(MultipleLocator(0.02)) ax2.set_ylim(0, 7) ax2.yaxis.set_major_locator(MultipleLocator(1)) ax2.yaxis.set_minor_locator(MultipleLocator(0.2)) title = '%s Bias Monthly Statistics\n%s Minus %s %s %s' % \ (xname_l, part2, part1, chan, DayOrNight) # plot ax1 ------------------------------------------------- plt.sca(ax1) strlist = [[]] for ref_temp in reference_list: plt.axvline(x=ref_temp, color='#4cd964', lw=0.7) ax1.annotate(str(ref_temp) + xunit, (ref_temp, -7.5), va="top", ha="center", color=EDGE_GRAY, size=6, fontproperties=FONT_MONO) strlist[0].append( "%s Bias %s: %6.3f" % (xname_l, str(ref_temp) + xunit, ref_temp * a + b - ref_temp)) strlist[0].append('Total Number: %7d' % len(x)) plt.plot(x, delta, 'o', ms=1.5, markerfacecolor=BLUE, alpha=0.5, mew=0, zorder=10) plt.plot(T_seg, mean_seg, 'o-', ms=6, lw=0.6, c=RED, mew=0, zorder=50) plt.fill_between(T_seg, mean_seg - std_seg, mean_seg + std_seg, facecolor=RED, edgecolor=RED, interpolate=True, alpha=0.4, zorder=100) ylabel = 'D%s' % (xname_l) + ('($%s$)' % xunit if xunit != "" else "") plt.ylabel(ylabel, fontsize=11, fontproperties=FONT0) plt.grid(True) plt.title(title, fontsize=12, fontproperties=FONT0) set_tick_font(ax1) plt.setp(ax1.get_xticklabels(), visible=False) # point number ------------------------------------------------- plt.sca(ax2) if xname == "tbb": width = 3 elif xname == "ref": width = 0.07 plt.bar(T_seg, np.log10(sampleNums), width=width, align="center", color=BLUE, linewidth=0) for i, T in enumerate(T_seg): if sampleNums[i] > 0: plt.text(T, np.log10(sampleNums[i]) + 0.2, '%d' % int(sampleNums[i]), ha="center", fontsize=6, fontproperties=FONT_MONO) add_annotate(ax2, strlist, 'left', EDGE_GRAY, 9) plt.ylabel('Number of sample points\nlog (base = 10)', fontsize=11, fontproperties=FONT0) xlabel = '%s %s' % (part2, xname_l) + ('($%s$)' % xunit if xunit != "" else "") plt.xlabel(xlabel, fontsize=11, fontproperties=FONT0) plt.grid(True) set_tick_font(ax2) #--------------- plt.tight_layout() fig.subplots_adjust(bottom=0.16) # circle1 = mpatches.Circle((74, 18), 5, color=BLUE, ec=EDGE_GRAY, lw=0) # circle2 = mpatches.Circle((164, 18), 5, color=RED, ec=EDGE_GRAY, lw=0) # fig.patches.extend([circle1, circle2]) # # fig.text(0.15, 0.02, 'Daily', color=BLUE, fontproperties=FONT0) # fig.text(0.3, 0.02, 'Monthly', color=RED, fontproperties=FONT0) fig.text(0.6, 0.02, '%s' % ym, fontproperties=FONT0) fig.text(0.8, 0.02, ORG_NAME, fontproperties=FONT0) #--------------- pb_io.make_sure_path_exists(os.path.dirname(picPath)) fig.savefig(picPath) plt.close() fig.clear
def plot(x, y, weight, o_file, num_file, part1, part2, chan, ymd, xname, xname_l, xunit, xmin, xmax, yname, yname_l, yunit, ymin, ymax, diagonal): plt.style.use(os.path.join(dvPath, 'dv_pub_legacy.mplstyle')) titleName = '%s-%s' % (xname.upper(), yname.upper()) if xunit != "": xlabel = '{} {} (${}$)'.format(part1, xname_l, xunit) else: xlabel = '{} {}'.format(part1, xname_l) if yunit != "": ylabel = '{} {} (${}$)'.format(part2, yname_l, yunit) else: ylabel = '{} {}'.format(part2, yname_l) DictTitle_rad = { 'xlabel': xlabel, 'ylabel': ylabel, 'title': '{} Regression {} Days {}_{} {} {}'.format( titleName, num_file, part1, part2, chan, ymd)} w = 1.0 / weight if weight is not None else None RadCompare = G_reg1d(x, y, w) # 过滤 正负 delta+4倍std 的杂点 ------------------------ reg_line = x * RadCompare[0] + RadCompare[1] delta = np.abs(y - reg_line) mean_delta = np.mean(delta) std_delta = np.std(delta) max_y = reg_line + mean_delta + std_delta * 4 min_y = reg_line - mean_delta - std_delta * 4 idx = np.logical_and(y < max_y, y > min_y) x = x[idx] y = y[idx] w = w[idx] if weight is not None else None # ----------------------------------------- RadCompare = G_reg1d(x, y, w) length_rad = len(x) pb_io.make_sure_path_exists(os.path.dirname(o_file)) if diagonal: dv_pub_legacy.draw_Scatter_Bar(x, y, o_file, DictTitle_rad, [['{:15}: {:7.4f}'.format('Slope', RadCompare[0]), '{:15}: {:7.4f}'.format('Intercept', RadCompare[1]), '{:15}: {:7.4f}'.format('Cor-Coef', RadCompare[4]), '{:15}: {:7d}'.format('Number', length_rad)]], '', part1, part2, xname, xname_l, xmin, xmax, ymin, ymax) else: dv_pub_legacy.draw_Scatter(x, y, o_file, DictTitle_rad, [['{:15}: {:7.4f}'.format('Slope', RadCompare[0]), '{:15}: {:7.4f}'.format('Intercept', RadCompare[1]), '{:15}: {:7.4f}'.format('Cor-Coef', RadCompare[4]), '{:15}: {:7d}'.format('Number', length_rad)]], '', xmin, xmax, ymin, ymax, diagonal) return [len(x), RadCompare[0], RadCompare[1], RadCompare[4]] # num, a, b, r
def write(self, out_file): """ :return: """ # 创建生成输出目录 pb_io.make_sure_path_exists(os.path.dirname(out_file)) # 将现在的第5通道数据复制一份到20通道 2018/07/27 self.Dn['CH_20'] = self.Dn['CH_05'] self.Ref['CH_20'] = self.Ref['CH_05'] self.SV['CH_20'] = self.SV['CH_05'] self.cal_coeff1['CH_20'] = self.cal_coeff1['CH_05'] self.BB['CH_20'] = self.BB['CH_05'] # 写入数据 with h5py.File(out_file, 'w') as hdf5: for i in xrange(0, 20): channel_name = 'CH_{:02}'.format(i + 1) name = '{}/Dn'.format(channel_name) data = self.Dn[channel_name].astype('u2') dtype = 'u2' self._create_dataset(name, data, dtype, hdf5) name = '{}/Ref'.format(channel_name) data = self.Ref[channel_name].astype('u2') dtype = 'u2' self._create_dataset(name, data, dtype, hdf5) name = '{}/SV'.format(channel_name) data = self.SV[channel_name].astype('u2') dtype = 'u2' self._create_dataset(name, data, dtype, hdf5) name = '{}/CalCoeff'.format(channel_name) data = self.cal_coeff1[channel_name] dtype = 'f4' self._create_dataset(name, data, dtype, hdf5) name = '{}/BB'.format(channel_name) data = self.BB[channel_name] dtype = 'f4' self._create_dataset(name, data, dtype, hdf5) name = 'Height' dtype = 'i2' data = self.ary_height self._create_dataset(name, data, dtype, hdf5) name = 'LandCover' dtype = 'u1' data = self.ary_land_cover self._create_dataset(name, data, dtype, hdf5) name = 'LandSeaMask' dtype = 'u1' data = self.ary_land_sea_mask self._create_dataset(name, data, dtype, hdf5) name = 'Latitude' dtype = 'f4' data = self.ary_lat self._create_dataset(name, data, dtype, hdf5) name = 'Longitude' dtype = 'f4' data = self.ary_lon self._create_dataset(name, data, dtype, hdf5) name = 'SolarZenith' dtype = 'i2' data = self.ary_sunz self._create_dataset(name, data, dtype, hdf5) name = 'SolarAzimuth' dtype = 'i2' data = self.ary_suna self._create_dataset(name, data, dtype, hdf5) name = 'SensorZenith' dtype = 'i2' data = self.ary_satz self._create_dataset(name, data, dtype, hdf5) name = 'SensorAzimuth' dtype = 'i2' data = self.ary_satz self._create_dataset(name, data, dtype, hdf5) name = 'Times' dtype = 'i4' data = self.Time self._create_dataset(name, data, dtype, hdf5) # 复制文件属性 with h5py.File(self.in_file, 'r') as hdf5_in_file: pb_io.copy_attrs_h5py(hdf5_in_file, hdf5)
def plot_tbbias(date_D, bias_D, date_M, bias_M, picPath, title, date_s, date_e, satName): ''' 画偏差时序折线图 ''' fig = plt.figure(figsize=(6, 4)) # plt.subplots_adjust(left=0.13, right=0.95, bottom=0.11, top=0.97) if (np.isnan(bias_D)).all(): Log.error('Everything is NaN: %s' % picPath) return plt.plot(date_D, bias_D, 'x', ms=6, markerfacecolor=None, markeredgecolor=BLUE, alpha=0.8, mew=0.3, label='Daily') plt.plot(date_M, bias_M, 'o-', ms=5, lw=0.6, c=RED, mew=0, label='Monthly') plt.grid(True) plt.ylabel('DTB($K$)', fontsize=11, fontproperties=FONT0) xlim_min = pb_time.ymd2date('%04d%02d01' % (date_s.year, date_s.month)) xlim_max = date_e plt.xlim(xlim_min, xlim_max) if "FY2" in satName: plt.ylim(-8, 8) elif "FY3" in satName: plt.ylim(-8, 8) elif "FY4" in satName: plt.ylim(-2, 2) ax = plt.gca() # format the ticks setXLocator(ax, xlim_min, xlim_max) set_tick_font(ax) # title plt.title(title, fontsize=12, fontproperties=FONT0) plt.tight_layout() #-------------------- fig.subplots_adjust(bottom=0.2) circle1 = mpatches.Circle((74, 15), 6, color=BLUE, ec=EDGE_GRAY, lw=0) circle2 = mpatches.Circle((164, 15), 6, color=RED, ec=EDGE_GRAY, lw=0) fig.patches.extend([circle1, circle2]) fig.text(0.15, 0.02, 'Daily', color=BLUE, fontproperties=FONT0) fig.text(0.3, 0.02, 'Monthly', color=RED, fontproperties=FONT0) ymd_s, ymd_e = date_s.strftime('%Y%m%d'), date_e.strftime('%Y%m%d') if ymd_s != ymd_e: fig.text(0.50, 0.02, '%s-%s' % (ymd_s, ymd_e), fontproperties=FONT0) else: fig.text(0.50, 0.02, '%s' % ymd_s, fontproperties=FONT0) fig.text(0.8, 0.02, ORG_NAME, fontproperties=FONT0) #--------------- pb_io.make_sure_path_exists(os.path.dirname(picPath)) plt.savefig(picPath) fig.clear() plt.close()
def plot_tbbias(date_D, bias_D, date_M, bias_M, picPath, title, date_s, date_e): """ 画偏差时序折线图 """ plt.style.use(os.path.join(DV_PATH, 'dv_pub_timeseries.mplstyle')) fig = plt.figure(figsize=(6, 4)) # plt.subplots_adjust(left=0.13, right=0.95, bottom=0.11, top=0.97) if (np.isnan(bias_D)).all(): Log.error('Everything is NaN: %s' % picPath) return plt.plot(date_D, bias_D, 'x', ms=6, markerfacecolor=None, markeredgecolor=BLUE, alpha=0.8, mew=0.3, label='Daily') plt.plot(date_M, bias_M, 'o-', ms=5, lw=0.6, c=RED, mew=0, label='Monthly') plt.grid(True) plt.ylabel('DTB($K$)', fontsize=11, fontproperties=FONT0) xlim_min = date_s xlim_max = date_e plt.xlim(xlim_min, xlim_max) plt.ylim(-1, 1) # 画 y=0 线 plt.plot([xlim_min, xlim_max], [0, 0], color='#808080', linewidth=1.0) ax = plt.gca() # format the ticks setXLocator(ax, xlim_min, xlim_max) set_tick_font(ax) ax.yaxis.set_major_locator(MultipleLocator(0.25)) ax.yaxis.set_minor_locator(MultipleLocator(0.125)) # title plt.title(title, fontsize=12, fontproperties=FONT0) plt.tight_layout() #-------------------- fig.subplots_adjust(bottom=0.2) circle1 = mpatches.Circle((74, 15), 6, color=BLUE, ec=EDGE_GRAY, lw=0) circle2 = mpatches.Circle((164, 15), 6, color=RED, ec=EDGE_GRAY, lw=0) fig.patches.extend([circle1, circle2]) fig.text(0.15, 0.02, 'Daily', color=BLUE, fontproperties=FONT0) fig.text(0.3, 0.02, 'Monthly', color=RED, fontproperties=FONT0) ymd_s, ymd_e = date_s.strftime('%Y%m%d'), date_e.strftime('%Y%m%d') if ymd_s != ymd_e: fig.text(0.50, 0.02, '%s-%s' % (ymd_s, ymd_e), fontproperties=FONT0) else: fig.text(0.50, 0.02, '%s' % ymd_s, fontproperties=FONT0) fig.text(0.8, 0.02, ORG_NAME, fontproperties=FONT0) #--------------- pb_io.make_sure_path_exists(os.path.dirname(picPath)) plt.savefig(picPath) fig.clear() plt.close()
def plot_omb(date_D, a_D, b_D, picPath, title, date_s, date_e): ''' 画偏差时序彩色图 ''' if (np.isnan(a_D)).all(): Log.error('Everything is NaN: %s' % picPath) return ylim_min, ylim_max = 210, 330 y_res = 0.2 x_size = (date_e - date_s).days yy = np.arange(ylim_min, ylim_max, y_res) + y_res / 2. # 一列的y值 grid = np.ones(len(date_D)) * yy.reshape(-1, 1) aa = a_D * np.ones((len(grid), 1)) bb = b_D * np.ones((len(grid), 1)) grid = grid - np.divide((grid - bb), aa) zz = np.zeros((len(yy), x_size)) # 2D, 要画的值 j = 0 xx = [] # 一行的x值 for i in xrange(x_size): # 补充缺失数据的天 date_i = date_s + relativedelta(days=i) xx.append(date_i) if j < len(date_D) and date_D[j] == date_i: zz[:, i] = grid[:, j] j = j + 1 fig = plt.figure(figsize=(6, 4)) ax = fig.add_subplot(111) norm = mpl.colors.Normalize(vmin=-10.0, vmax=10.0) xx = np.array(xx) plt.pcolormesh(xx, yy, zz, cmap='jet', norm=norm, shading='gouraud', zorder=0) plt.grid(True, zorder=10) xlim_min = date_s xlim_max = date_e plt.xlim(xlim_min, xlim_max) plt.ylim(ylim_min, ylim_max) plt.ylabel('TB($K$)', fontsize=11, fontproperties=FONT0) # format the ticks setXLocator(ax, xlim_min, xlim_max) set_tick_font(ax) # title plt.title(title, fontsize=12, fontproperties=FONT0) plt.tight_layout() #-------------------- fig.subplots_adjust(bottom=0.25) # -------add colorbar --------- fig.canvas.draw() point_bl = ax.get_position().get_points()[0] # 左下 point_tr = ax.get_position().get_points()[1] # 右上 cbar_height = 0.05 colorbar_ax = fig.add_axes([ point_bl[0] - 0.05, 0.05, (point_tr[0] - point_bl[0]) / 2.2, cbar_height ]) mpl.colorbar.ColorbarBase(colorbar_ax, cmap='jet', norm=norm, orientation='horizontal') # ---font of colorbar----------- for l in colorbar_ax.xaxis.get_ticklabels(): l.set_fontproperties(FONT0) l.set_fontsize(9) # ------Time and ORG_NAME---------------- ymd_s, ymd_e = date_s.strftime('%Y%m%d'), date_e.strftime('%Y%m%d') if ymd_s != ymd_e: fig.text(0.52, 0.05, '%s-%s' % (ymd_s, ymd_e), fontproperties=FONT0) else: fig.text(0.52, 0.05, '%s' % ymd_s, fontproperties=FONT0) fig.text(0.82, 0.05, ORG_NAME, fontproperties=FONT0) #--------------- pb_io.make_sure_path_exists(os.path.dirname(picPath)) plt.savefig(picPath) fig.clear() plt.close()
def plot_bias(date_D, bias_D, date_M, bias_M, picPath, title, date_s, date_e, each, date_type, ylim_min, ylim_max): """ 画偏差时序折线图 """ plt.style.use(os.path.join(dvPath, 'dv_pub_timeseries.mplstyle')) fig = plt.figure(figsize=(6, 4)) # plt.subplots_adjust(left=0.13, right=0.95, bottom=0.11, top=0.97) plt.plot(date_D, bias_D, 'x', ms=6, markerfacecolor=None, markeredgecolor=BLUE, alpha=0.8, mew=0.3, label='Daily') plt.plot(date_M, bias_M, 'o-', ms=5, lw=0.6, c=RED, mew=0, label='Monthly') plt.grid(True) plt.ylabel('%s %s' % (each, date_type), fontsize=11, fontproperties=FONT0) xlim_min = pb_time.ymd2date('%04d%02d01' % (date_s.year, date_s.month)) xlim_max = date_e plt.plot([xlim_min, xlim_max], [0, 0], '#808080') # 在 y=0 绘制一条深灰色直线 plt.xlim(xlim_min, xlim_max) plt.ylim(ylim_min, ylim_max) ax = plt.gca() # format the ticks interval = (ylim_max - ylim_min) / 8 # 8 个间隔 minibar = interval / 2. setXLocator(ax, xlim_min, xlim_max) set_tick_font(ax) # 如果范围为浮点数,需要进行一次格式化,否则图像不会显示最后一个刻度 if isinstance(interval, float): interval = float('%.5f' % interval) minibar = float('%.5f' % minibar) ax.yaxis.set_major_locator(MultipleLocator(interval)) ax.yaxis.set_minor_locator(MultipleLocator(minibar)) # title plt.title(title, fontsize=12, fontproperties=FONT0) plt.tight_layout() # -------------------- fig.subplots_adjust(bottom=0.2) circle1 = mpatches.Circle((74, 15), 6, color=BLUE, ec=EDGE_GRAY, lw=0) circle2 = mpatches.Circle((164, 15), 6, color=RED, ec=EDGE_GRAY, lw=0) fig.patches.extend([circle1, circle2]) fig.text(0.15, 0.02, 'Daily', color=BLUE, fontproperties=FONT0) fig.text(0.3, 0.02, 'Monthly', color=RED, fontproperties=FONT0) ymd_s, ymd_e = date_s.strftime('%Y%m%d'), date_e.strftime('%Y%m%d') if ymd_s != ymd_e: fig.text(0.50, 0.02, '%s-%s' % (ymd_s, ymd_e), fontproperties=FONT0) else: fig.text(0.50, 0.02, '%s' % ymd_s, fontproperties=FONT0) fig.text(0.8, 0.02, ORG_NAME, fontproperties=FONT0) # --------------- pb_io.make_sure_path_exists(os.path.dirname(picPath)) plt.savefig(picPath) fig.clear() plt.close()