def UpdateData(self, products, micapsfile): self.UpdateExtents(products) # micapsfile = products.micapsfiles[0] self.min = self.Z.min() self.max = self.Z.max() self.distance = micapsfile.contour.step self.min = math.floor(self.min / self.distance) * self.distance self.max = math.ceil(self.max / self.distance) * self.distance # 如果自定义了legend的最小、最大和步长值 则用自定义的值更新 self.UpdatePinLegendValue(micapsfile) from Main import equal if micapsfile.uv.onspeed and not equal(self.Z.max(), 0): self.linewidth = 5 * self.Z / self.Z.max() else: self.linewidth = micapsfile.uv.linewidth self.density = micapsfile.uv.density self.barbsgrid = micapsfile.uv.barbsgrid if micapsfile.uv.oncolor: self.color = self.Z self.cmap = nclcmaps.cmaps(micapsfile.legend.micapslegendcolor) else: self.color = micapsfile.uv.color self.barbs = micapsfile.uv.barbs self.stream = micapsfile.uv.stream self.length = micapsfile.uv.length self.scale = micapsfile.uv.scale self.wholeclip = micapsfile.uv.wholecilp self.colorlist = micapsfile.legend.legendcolor
def Draw(self, products, micapsfile, debug=True): """ 根据产品参数绘制图像 :param micapsfile: 指定绘制产品中包含的一个micapsfile :param debug: 调试状态 :param products: 产品参数 :return: """ self.UpdateData(products, micapsfile) extents = products.picture.extents xmax = extents.xmax xmin = extents.xmin ymax = extents.ymax ymin = extents.ymin # 设置绘图画板的宽和高 单位:英寸 h = products.picture.height if products.map.projection.name == 'sall': # 等经纬度投影时不用配置本身的宽度,直接根据宽高比得到 w = h * np.math.fabs( (xmax - xmin) / (ymax - ymin)) * products.picture.widthshrink else: w = products.picture.width # 创建画布 fig = plt.figure(figsize=(w, h), dpi=products.picture.dpi, facecolor="white") # 必须在前面 ax = fig.add_subplot(111) ax.spines['bottom'].set_linewidth(products.map.projection.axisthick) ax.spines['left'].set_linewidth(products.map.projection.axisthick) ax.spines['right'].set_linewidth(products.map.projection.axisthick) ax.spines['top'].set_linewidth(products.map.projection.axisthick) # 设置绘图区域 plt.xlim(xmin, xmax) plt.ylim(ymin, ymax) # 背景透明 fig.patch.set_alpha(products.picture.opacity) # 坐标系统尽可能靠近绘图区边界 fig.tight_layout(pad=products.picture.pad) clipborder = products.map.clipborders[0] # 获得产品投影 from Projection import Projection m = Projection.GetProjection(products) if m is not plt: # 用投影更新经纬度数据 self.X, self.Y = Micaps.UpdateXY(m, self.X, self.Y) # 用投影更新产品参数中涉及经纬度的数据 Micaps.Update(products, m) # 画世界底图 Map.DrawWorld(products, m) # 绘制裁切区域边界 patch = Map.DrawClipBorders(products.map.clipborders) # draw parallels and meridians. Map.DrawGridLine(products, m) cmap = nclcmaps.cmaps( micapsfile.legend.micapslegendcolor) # cm.jet temp_diff_18lev vmax = math.ceil(self.max) vmin = math.floor(self.min) levels = arange(vmin - self.distance, vmax + self.distance + 0.1, self.distance) if micapsfile.legend.micapslegendvalue: level = levels else: level = micapsfile.legend.legendvalue # 绘制等值线 ------ 等值线和标注是一体的 c = micapsfile.contour Map.DrawContourAndMark(contour=c, x=self.X, y=self.Y, z=self.Z, level=level, clipborder=clipborder, patch=patch, m=m) cf = micapsfile.contour cbar = micapsfile.legend extend = micapsfile.legend.extend # 绘制色斑图 ------ 色版图、图例、裁切是一体的 Map.DrawContourfAndLegend(contourf=cf, legend=cbar, clipborder=clipborder, patch=patch, cmap=cmap, levels=levels, extend=extend, extents=extents, x=self.X, y=self.Y, z=self.Z, m=m) # 绘制描述文本 MicapsFile.MicapsFile.DrawTitle(m, micapsfile.title, self.title) self.DrawUV(m, micapsfile, clipborder, patch) # 绘制地图 Map.DrawBorders(m, products) # 绘制散点 if micapsfile.contour.scatter: if hasattr(self, 'x1'): m.scatter(self.x1, self.y1, s=micapsfile.contour.radius, c=self.z1, alpha=micapsfile.contour.alpha, edgecolors='b') else: m.scatter(self.X, self.Y, s=micapsfile.contour.radius, c=self.Z, alpha=micapsfile.contour.alpha, edgecolors='b') # 绘制站点 stations = products.map.stations if stations.visible: # 'code': code, 'lon': lon, 'lat': lat, 'height': height, # 'iclass': iclass, 'infosum': infosum, 'name': info[0] # stations_tuple = tuple(stations.micapsdata.stations) # (code, lat, lon, height, iclass, infosum, info[0]) # stations_array = np.array(stations.micapsdata.stations, dtype=[ # ('code', 'U'), # ('lat', np.float32), # ('lon', np.float32), # ('height', np.float32), # ('iclass', 'i'), # ('infosum', 'i'), # ('info', 'U') # ]) # stations_array = [list(ele) for ele in zip(*stations.micapsdata.stations)] stations_array = zip(*stations.micapsdata.stations) # 画站点mark if m is not plt: stations_array[2], stations_array[1] = \ Micaps.UpdateXY(m, stations_array[2], stations_array[1]) marker = MarkerStyle(stations.markstyle[0], stations.markstyle[1]) m.scatter(stations_array[2], stations_array[1], marker=marker, s=stations.radius, c=stations.color, alpha=stations.alpha, edgecolors=stations.edgecolors) # 画站点文本 fontfile = r"C:\WINDOWS\Fonts\{0}".format(stations.font[1]) if not os.path.exists(fontfile): font = FontProperties(size=stations.font[0], weight=stations.font[2]) else: font = FontProperties(fname=fontfile, size=stations.font[0], weight=stations.font[2]) for sta in stations.micapsdata.stations: if m is not plt: lon, lat = Micaps.UpdateXY(m, sta[2], sta[1]) lon1, lat1 = Micaps.UpdateXY(m, sta[2] + stations.detax, sta[1]) deta = lon1 - lon else: lon, lat = sta[2], sta[1] deta = stations.detax plt.text(lon + deta, lat, sta[6], fontproperties=font, rotation=0, color=stations.font[3], ha='left', va='center') # 接近收尾 # self.Clip(clipborder, fig, patch) # 存图 Picture.savePicture(fig, products.picture.picfile) print(products.picture.picfile + u'存图成功!') if debug: plt.show()
def Draw(self, products, debug=True): """ 根据产品参数绘制图像 :param debug: :param products: :return: 产品参数 """ # 图例的延展类型 origin = 'lower' if self.title.find(u'降水') >= 0 or self.title.find(u'雨'): extend = 'max' else: extend = 'neither' # 更新绘图矩形区域 # self.UpdateExtents(products) self.UpdateData(products) xmax = products.extents.xmax xmin = products.extents.xmin ymax = products.extents.ymax ymin = products.extents.ymin # 设置绘图画板的宽和高 单位:英寸 h = products.height if products.projection.name == 'sall': # 等经纬度投影时不用配置本身的宽度,直接根据宽高比得到 w = h * np.math.fabs((xmax - xmin) / (ymax - ymin)) * products.widthshrink else: w = products.width # 创建画布 fig = plt.figure(figsize=(w, h), dpi=products.dpi, facecolor="white") # 必须在前面 # ax = fig.add_subplot(111) # 设置绘图区域 plt.xlim(xmin, xmax) plt.ylim(ymin, ymax) # 背景透明 fig.patch.set_alpha(products.opacity) # 坐标系统尽可能靠近绘图区边界 fig.tight_layout(pad=products.pad) # 获得产品投影 from Projection import Projection m = Projection.GetProjection(products) if m is not plt: # 用投影更新经纬度数据 self.X, self.Y = Micaps.UpdateXY(m, self.X, self.Y) # 用投影更新产品参数中涉及经纬度的数据 Micaps.Update(products, m) if products.projection.coastlines: m.drawcoastlines(linewidth=0.25) if products.projection.countries: m.drawcountries(linewidth=0.25) # draw parallels and meridians. if products.projection.axis == 'on': m.drawparallels(np.arange(-80., 81., 10.), labels=products.projection.latlabels, family='DejaVu Sans', fontsize=10) m.drawmeridians(np.arange(-180., 181., 10.), labels=products.projection.lonlabels, family='DejaVu Sans', fontsize=10) if products.projection.lsmask['visible']: m.drawlsmask(land_color=products.projection.lsmask['land_color'], ocean_color=products.projection.lsmask['ocean_color'], resolution='l') else: # 坐标轴 plt.axis(products.projection.axis) # 设置坐标轴刻度值显示格式 if products.projection.axis == 'on': x_majorFormatter = FormatStrFormatter('%d°E') y_majorFormatter = FormatStrFormatter('%d°N') plt.gca().xaxis.set_major_formatter(x_majorFormatter) plt.gca().yaxis.set_major_formatter(y_majorFormatter) xaxis = plt.gca().xaxis for label in xaxis.get_ticklabels(): label.set_fontproperties('DejaVu Sans') label.set_fontsize(10) yaxis = plt.gca().yaxis for label in yaxis.get_ticklabels(): label.set_fontproperties('DejaVu Sans') label.set_fontsize(10) # 绘制裁切区域边界 if products.cutborders[0]['path'] is not None: patch = patches.PathPatch(products.cutborders[0]['path'], linewidth=products.cutborders[0]['linewidth'], facecolor='none', edgecolor=products.cutborders[0]['linecolor']) plt.gca().add_patch(patch) else: patch = None # 绘制地图 Micaps.DrawBorders(m, products) cmap = nclcmaps.cmaps(products.micapslegendcolor) # cm.jet temp_diff_18lev vmax = math.ceil(self.max) vmin = math.floor(self.min) levels = arange(vmin - self.distance, vmax + self.distance + 0.1, self.distance) if products.micapslegendvalue: level = levels else: level = products.legendvalue # 是否绘制等值线 ------ 等值线和标注是一体的 if products.contour['visible']: matplotlib.rcParams['contour.negative_linestyle'] = 'dashed' if products.contour['colorline']: CS1 = m.contour(self.X, self.Y, self.Z, levels=level, linewidths=products.contour['linewidth']) else: CS1 = m.contour(self.X, self.Y, self.Z, levels=level, linewidths=products.contour['linewidth'], colors=products.contour['linecolor']) # 用区域边界裁切等值线图 if not products.cutborders[0]['path'] is None and products.cutborders[0]['using']: for collection in CS1.collections: collection.set_clip_on(True) collection.set_clip_path(patch) # 是否绘制等值线标注 if products.contourlabel['visible']: plt.clabel(CS1, inline=1, fmt=products.contourlabel['fmt'], fontsize=products.contourlabel['fontsize'], colors=products.contourlabel['fontcolor']) # 是否绘制色斑图 ------ 色版图、图例、裁切是一体的 if products.contourfvisible: # 绘制色斑图 if products.micapslegendvalue: CS = m.contourf(self.X, self.Y, self.Z, cmap=cmap, levels=levels, extend=extend, orientation='vertical', origin=origin) else: CS = m.contourf(self.X, self.Y, self.Z, # cax=axins, levels=products.legendvalue, colors=products.legendcolor, extend=extend, orientation='vertical', origin=origin) # 用区域边界裁切色斑图 if products.cutborders[0]['path'] is not None and products.cutborders[0]['using']: for collection in CS.collections: collection.set_clip_on(True) collection.set_clip_path(patch) if m is plt: # 插入一个新坐标系 以使图例在绘图区内部显示 ax2 = plt.gca() axins = inset_axes(ax2, width="100%", height="100%", loc=1, borderpad=0) axins.axis('off') axins.margins(0, 0) axins.xaxis.set_ticks_position('bottom') axins.yaxis.set_ticks_position('left') axins.set_xlim(xmin, xmax) axins.set_ylim(ymin, ymax) # 画图例 if products.islegendpic: # 插入图片 arr_lena = read_png(products.legendpic) image_box = OffsetImage(arr_lena, zoom=products.legendopacity) ab = AnnotationBbox(image_box, products.legendpos, frameon=False) plt.gca().add_artist(ab) else: ticks = fmt = None CB = plt.colorbar(CS, cmap='RdBu', anchor=products.anchor, shrink=products.shrink, ticks=ticks, # fraction=0.15, # products.fraction, drawedges=True, # not products.micapslegendvalue, filled=False, spacing='uniform', use_gridspec=False, orientation=products.orientation, # extendfrac='auto', format=fmt ) else: cb = m.colorbar(CS, location=products.projection.location, size=products.projection.size, pad=products.projection.pad) # 绘制描述文本 Micaps.DrawTitle(m, products, self.title) # 存图 fig.savefig(products.picfile, format='png', transparent=False) print(products.picfile + u'存图成功!') if debug: plt.show()