Beispiel #1
0
    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()
Beispiel #2
0
    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()