Exemplo n.º 1
0
    def rectangle_around_axes(bottomleft_ax, topright_ax, pad, ls, label=None):
        """
        pad: tuple, (left, right, bottom, top)
        """
        left, bottom = bottomleft_ax.get_position().get_points()[0]
        right, top = topright_ax.get_position().get_points()[1]
        left -= pad[0]
        right += pad[1]
        bottom -= pad[2]
        top += pad[3]
        transf = plt.gcf().transFigure
        rec = Rectangle((left, bottom),
                        right - left,
                        top - bottom,
                        transform=transf,
                        fill=False,
                        lw=2,
                        ls=ls)
        rec = bottomleft_ax.add_patch(rec)
        rec.set_clip_on(False)

        if label:
            middle = (top + bottom) / 2.
            moreleft = left  # pad[0]
            bottomleft_ax.text(moreleft,
                               middle,
                               label,
                               transform=transf,
                               rotation='vertical',
                               fontstyle='oblique',
                               va='center',
                               ha='right')
Exemplo n.º 2
0
    def highlight_artist(self, val, artist=None):
        #        print val, artist
        figure = self.get_figpage()._artists[0]
        ax = self.get_figaxes()
        if artist is None:
            alist = self._artists
        else:
            alist = artist
        if val == True:
            container = self.get_container()
            if container is None: return

            de = self.get_data_extent()
            from ifigure.matplotlib_mod.art3d_gl import AxesImageGL
            if isinstance(alist[0], AxesImageGL):
                hl = alist[0].add_hl_mask()
                for item in hl:
                    alist[0].figobj_hl.append(item)

#               hl = alist[0].make_hl_artist(container)
#               rect_alpha = 0.0
            else:
                x = [de[0], de[1], de[1], de[0], de[0]]
                y = [de[2], de[2], de[3], de[3], de[2]]
                hl = container.plot(x,
                                    y,
                                    marker='s',
                                    color='k',
                                    linestyle='None',
                                    markerfacecolor='None',
                                    markeredgewidth=0.5,
                                    scalex=False,
                                    scaley=False)
                rect_alpha = 0.3

                hlp = Rectangle((de[0], de[2]),
                                de[1] - de[0],
                                de[3] - de[2],
                                alpha=rect_alpha,
                                facecolor='k',
                                figure=figure,
                                transform=container.transData)
                if ax is not None:
                    x0, y0 = ax._artists[0].transAxes.transform((0, 0))
                    x1, y1 = ax._artists[0].transAxes.transform((1, 1))
                    bbox = Bbox([[x0, y0], [x1, y1]])
                    hlp.set_clip_box(bbox)
                    hlp.set_clip_on(True)

                figure.patches.append(hlp)
                for item in (hl[0], hlp):
                    alist[0].figobj_hl.append(item)
        else:
            for a in alist:
                if len(a.figobj_hl) != 0:
                    a.figobj_hl[0].remove()
                    figure.patches.remove(a.figobj_hl[1])
                a.figobj_hl = []
Exemplo n.º 3
0
def plot_add_border(ax, offset=[0, 0], **rec_args):
    xmin, xmax, ymin, ymax = ax.axis()
    xmin, xmax, ymin, ymax = xmin - offset[0], xmax + offset[0], ymin - offset[
        1], ymax + offset[1]
    rec = Rectangle((xmin, ymin), (xmax - xmin), (ymax - ymin),
                    fill=False,
                    zorder=19,
                    **rec_args)
    rec = ax.add_patch(rec)
    rec.set_clip_on(False)
Exemplo n.º 4
0
 def boundary(sub1):
     autoAxis = sub1.axis()
     rec = Rectangle((autoAxis[0] - 0.6, autoAxis[2] - 0.4),
                     (autoAxis[1] - autoAxis[0]) + 1,
                     (autoAxis[3] - autoAxis[2]) + 1,
                     fill=False,
                     lw=2,
                     edgecolor='r')
     rec = sub1.add_patch(rec)
     rec.set_clip_on(False)
Exemplo n.º 5
0
    def highlight_artist(self, val, artist=None):
#        print val, artist
        figure=self.get_figpage()._artists[0]
        ax = self.get_figaxes()
        if artist is None:
           alist=self._artists
        else:
           alist=artist 
        if val == True:
           container = self.get_container()
           if container is None: return
           
           de = self.get_data_extent()
           from ifigure.matplotlib_mod.art3d_gl import AxesImageGL
           if isinstance(alist[0], AxesImageGL):
               hl = alist[0].add_hl_mask()
               for item in hl:
                   alist[0].figobj_hl.append(item)
                
#               hl = alist[0].make_hl_artist(container)
#               rect_alpha = 0.0                   
           else:
               x=[de[0],de[1],de[1],de[0],de[0]]
               y=[de[2],de[2],de[3],de[3],de[2]]               
               hl= container.plot(x, y, marker='s', 
                                 color='k', linestyle='None',
                                 markerfacecolor='None',
                                 markeredgewidth = 0.5,                                  
                                 scalex=False, scaley=False)
               rect_alpha = 0.3
           
               
               hlp = Rectangle((de[0],de[2]),
                                de[1]-de[0],
                                de[3]-de[2],
                                alpha=rect_alpha, facecolor='k',
                                figure = figure, 
                                transform= container.transData)
               if ax is not None:
                  x0, y0 = ax._artists[0].transAxes.transform((0,0))
                  x1, y1 = ax._artists[0].transAxes.transform((1,1))
                  bbox = Bbox([[x0,y0],[x1,y1]])
                  hlp.set_clip_box(bbox)
                  hlp.set_clip_on(True)

               figure.patches.append(hlp)
               for item in (hl[0], hlp):
                   alist[0].figobj_hl.append(item)
        else:
           for a in alist:
              if len(a.figobj_hl) != 0:
                 a.figobj_hl[0].remove()
                 figure.patches.remove(a.figobj_hl[1])
              a.figobj_hl=[]
Exemplo n.º 6
0
 def draw_box_around_values(start, stop, ls):
     deltaline = ty[start] - ty[start + 1]
     top = ty[start] + deltaline  # Draw the top border ABOVE the text
     bottom = ty[stop]
     rec = Rectangle((left - 0.1, bottom - 0.02),
                     right - left + 0.15,
                     top - bottom + 0.01,
                     fill=False,
                     lw=2,
                     transform=tax.transAxes,
                     ls=ls)
     rec = tax.add_patch(rec)
     rec.set_clip_on(False)
Exemplo n.º 7
0
def on_click(event):
    global prev_g_point
    global prev_b_point
    global dirty_type
    global idx_seen
    # print(idx_seen)

    if event.button == 1:
        plt.ion()
        print('Your decision has been recorded!')
        btn = event.inaxes

        spn = (int(btn.get_title()) % 80) // 4

        color_id = int(btn.get_title()) % 4

        colors_temp = ['green', 'blue', 'gray', 'orange']

        req_axis = subplot_axs_list[spn]

        autoAxis = req_axis.axis()
        rec = Rectangle((autoAxis[0] - 0.7, autoAxis[2] - 0.2),
                        (autoAxis[1] - autoAxis[0]) + 1,
                        (autoAxis[3] - autoAxis[2]) + 0.4,
                        fill=False,
                        lw=5,
                        color=colors_temp[color_id])
        rec = req_axis.add_patch(rec)
        rec.set_clip_on(False)

        plt.draw()

        print('subplot_title: {}'.format(req_axis.get_title()))

        row_no = int(req_axis.get_title())
        dirty_val = int(btn.get_title()) % 4
        idx_seen[row_no] = str(dirty_val)

        if dirty_val == 0:
            prev_b_point = row_no
        elif dirty_val == 3:
            prev_g_point = row_no

    dirty_type[row_no] = dirty_val
    rk = spn
    rv = dirty_val % 4
    d = ['{}'.format(path[int(req_axis.get_title())]), '{}'.format(rv)]

    field_names = ['path', 'dirty_value']
Exemplo n.º 8
0
    def highlight_artist(self, val, artist=None):
        figure = self.get_figpage()._artists[0]
        ax = self.get_figaxes()
        if val:
            if len(self._artists[0].figobj_hl) != 0:
                return
            box = self.get_artist_extent_all()
            self._artist_extent = box
            if box[0] is None:
                return
            x = [box[0], box[0], box[1], box[1], box[0]]
            y = [box[3], box[2], box[2], box[3], box[3]]

            hl = Line2D(x,
                        y,
                        marker='s',
                        color='k',
                        linestyle='None',
                        markerfacecolor='k',
                        markeredgewidth=0.5,
                        figure=figure,
                        alpha=0.3)
            figure.lines.append(hl)
            xy = (box[0], box[2])
            w = box[1] - box[0]
            h = box[3] - box[2]
            hlp = Rectangle(xy, w, h, alpha=0.3, facecolor='k', figure=figure)
            if ax is not None:
                x0, y0 = ax._artists[0].transAxes.transform((0, 0))
                x1, y1 = ax._artists[0].transAxes.transform((1, 1))
                bbox = Bbox([[x0, y0], [x1, y1]])
                hlp.set_clip_box(bbox)
                hlp.set_clip_on(True)
            figure.patches.append(hlp)
            #           if ax is not None and ax.get_3d():
            #               import mpl_toolkits.mplot3d.art3d as art3d
            #               art3d.patch_2d_to_3d(hl)
            #               if len(ax._artists) != 0:
            #                   a.axes = self.get_figaxes()._artists[0]
            self._artists[0].figobj_hl.extend([hl, hlp])
        else:
            if len(self._artists[0].figobj_hl) == 2:
                figure.lines.remove(self._artists[0].figobj_hl[0])
                figure.patches.remove(self._artists[0].figobj_hl[1])
            self._artists[0].figobj_hl = []
Exemplo n.º 9
0
    def highlight_artist(self, val, artist=None):
        figure=self.get_figpage()._artists[0]
        ax = self.get_figaxes()
        if val:
           if len(self._artists[0].figobj_hl) != 0: return
           box = self.get_artist_extent_all()
           self._artist_extent = box
           if box[0] is None: return
           x = [box[0], box[0], box[1], box[1], box[0]]
           y = [box[3], box[2], box[2], box[3], box[3]]

           hl= Line2D(x, y, marker='s', 
                                 color='k', linestyle='None',
                                 markerfacecolor='k',
                                 markeredgewidth =  0.5,                      
                                 figure=figure, alpha=0.3)
           figure.lines.append(hl)
           xy = (box[0], box[2])
           w = box[1] - box[0]
           h = box[3] - box[2]
           hlp = Rectangle(xy, w, h, alpha=0.3, facecolor='k',
                     figure = figure)
           if ax is not None:
              x0, y0 = ax._artists[0].transAxes.transform((0,0))
              x1, y1 = ax._artists[0].transAxes.transform((1,1))
              bbox = Bbox([[x0,y0],[x1,y1]])
              hlp.set_clip_box(bbox)
              hlp.set_clip_on(True)
           figure.patches.append(hlp)
#           if ax is not None and ax.get_3d():
#               import mpl_toolkits.mplot3d.art3d as art3d
#               art3d.patch_2d_to_3d(hl)
#               if len(ax._artists) != 0:
#                   a.axes = self.get_figaxes()._artists[0]
           self._artists[0].figobj_hl.extend([hl, hlp])
        else:
           if len(self._artists[0].figobj_hl) == 2:
              figure.lines.remove(self._artists[0].figobj_hl[0])
              figure.patches.remove(self._artists[0].figobj_hl[1])
           self._artists[0].figobj_hl = []
Exemplo n.º 10
0
from pylab import *
from matplotlib.lines import Line2D
from matplotlib.patches import Rectangle

# build a rectangle in axes coords
left, width = .25, .5
bottom, height = .25, .5
right = left + width
top = bottom + height
ax = gca()
p = Rectangle((left, bottom), width, height,
              fill=False,
              )
p.set_transform(ax.transAxes)
p.set_clip_on(False)
ax.add_patch(p)


ax.text(left, bottom, 'left top',
        horizontalalignment='left',
        verticalalignment='top',
        transform=ax.transAxes)

ax.text(left, bottom, 'left bottom',
        horizontalalignment='left',
        verticalalignment='bottom',
        transform=ax.transAxes)

ax.text(right, top, 'right bottom',
        horizontalalignment='right',
Exemplo n.º 11
0
def render_profiles(num, seq, reactivity, stderr,
                    rx_rates, bg_rates, dc_rates,
                    rx_depth, bg_depth, dc_depth,
                    rx_simple_depth, bg_simple_depth, dc_simple_depth,
                    fileout, name, qc_pass):
    # FIXME: this is fairly ugly code - should at least break each panel into a separate func

    if rx_rates is None and bg_rates is None and dc_rates is None:
        no_mapped = True
    else:
        no_mapped = False

    legend_labels = []
    if rx_rates is not None:
        legend_labels.append("Modified")
        rx_err = sqrt(rx_rates) / sqrt(rx_depth)
    else:
        rx_rates = np.zeros((len(rx_depth),))
        rx_err = np.zeros((len(rx_depth),))
    if bg_rates is not None:
        legend_labels.append("Untreated")
        bg_err = sqrt(bg_rates) / sqrt(bg_depth)
    else:
        bg_rates = np.zeros((len(rx_depth),))
        bg_err = np.zeros((len(rx_depth),))
    if dc_rates is not None:
        legend_labels.append("Denatured")
        dc_err = sqrt(dc_rates) / sqrt(dc_depth)
    else:
        dc_rates = np.zeros((len(rx_depth),))
        dc_err = np.zeros((len(rx_depth),))

    # Add a zeroeth nuc so axis numbering works correctly
    # There's probably a better way to do this
    num = np.append(0, num)
    if reactivity is not None:
        reactivity = np.append(0, reactivity)
        stderr = np.append(0, stderr)
    rx_depth = np.append(0, rx_depth)
    bg_depth = np.append(0, bg_depth)
    dc_depth = np.append(0, dc_depth)
    rx_simple_depth = np.append(0, rx_simple_depth)
    bg_simple_depth = np.append(0, bg_simple_depth)
    dc_simple_depth = np.append(0, dc_simple_depth)
    rx_rates = np.append(0, rx_rates)
    bg_rates = np.append(0, bg_rates)
    dc_rates = np.append(0, dc_rates)
    rx_err = np.append(0, rx_err)
    bg_err = np.append(0, bg_err)
    dc_err = np.append(0, dc_err)

    if reactivity is not None:
        orange_thresh = 0.4
        red_thresh = 0.85

        gray_vals = []
        gray_nums = []
        gray_errs = []
        black_vals = []
        black_nums = []
        black_errs = []
        orange_vals = []
        orange_nums = []
        orange_errs = []
        red_vals = []
        red_nums = []
        red_errs = []
        for i in range(len(reactivity)):
            if isnan(reactivity[i]):
                gray_vals.append(-1)
                gray_nums.append(num[i])
                gray_errs.append(0)
            elif reactivity[i] < orange_thresh:
                black_vals.append(reactivity[i])
                black_nums.append(num[i])
                black_errs.append(stderr[i])
            elif reactivity[i] < red_thresh:
                orange_vals.append(reactivity[i])
                orange_nums.append(num[i])
                orange_errs.append(stderr[i])
            else:
                red_vals.append(reactivity[i])
                red_nums.append(num[i])
                red_errs.append(stderr[i])

    yMin, ymax = (-0.5, 4)
    left_inches = 0.9
    right_inches = 0.4
    sp_width = len(num)*0.032
    fig_width = max(7,sp_width+left_inches+right_inches)
    fig = plt.figure(figsize=(fig_width,8))

    left_percent = left_inches/fig_width
    right_percent = 1-right_inches/fig_width
    ax1 = plt.subplot(311)
    ax2 = plt.subplot(313)
    ax3 = plt.subplot(312)
    plt.subplots_adjust(hspace=0.5, left=left_percent,right=right_percent,top=0.94)

    near_black = (0,0,1/255.0)

    if reactivity is not None:
        if len(gray_nums)>0:
            ax1.bar(gray_nums,gray_vals,
                     align="center",
                     width=1.05, color="0.80", edgecolor="0.80",linewidth=0.0)
        if len(black_nums)>0:
            ax1.bar(black_nums,black_vals,
                     align="center",
                     width=1.05, color="black", edgecolor="black",linewidth=0.0,
                     yerr=black_errs,ecolor=near_black,capsize=1)
        if len(orange_nums)>0:
            ax1.bar(orange_nums,orange_vals,
                     align="center",
                     width=1.05, color="orange",edgecolor="orange",linewidth=0.0,
                     yerr=orange_errs,ecolor=near_black,capsize=1)
        if len(red_nums)>0:
            ax1.bar(red_nums,red_vals,
                     align="center",
                     width=1.05,color="red",edgecolor="red",linewidth=0.0,
                     yerr=red_errs,ecolor=near_black,capsize=1)

    #print("title: "+name)
    ax1title = ax1.set_title(name, horizontalalignment="left", fontsize=16)
    x,y = ax1title.get_position()
    ax1title.set_position((0,y))
    ax1.set_ylim(yMin,ymax)
    ax1.set_xlim(1,len(num))
    #ax1.set_yticks(fontsize=9)

    if not qc_pass:
        msg = "Note: possible data quality issue - see log file"
        return_flag = False
        if no_mapped:
            msg = "ERROR: no reads mapped to this RNA"
            return_flag = True
        txt = plt.text(30,573,
                 msg,
                 ha='left', va='top',
                 fontsize=16, color='red',
                 transform=mp.transforms.IdentityTransform())
        if return_flag:
            plt.savefig(fileout)
            return 

    #tickNums = range(num[0]+10,num[-1]+1,10)
    #tickPos = range(num[0]+9,num[-1],10)
    #ax1.set_xticks(tickPos,tickNums,fontsize=9,rotation=30)
    #ax1.set_xticks(fontsize=9)

    ax1.yaxis.grid(True)
    ax1.set_axisbelow(True)

    ax1.spines["right"].set_visible(False)
    ax1.spines["top"].set_visible(False)
    for loc, spine in ax1.spines.items():
        if loc == 'bottom':
            spine.set_position(('outward', 6))  # move outward (down) 6 pts
            spine.set_smart_bounds(True)
    for loc, spine in ax1.spines.items():
        if loc == 'left':
            spine.set_position(('outward', 6))  # move outward (left) 6 pts
            spine.set_smart_bounds(True)

    # need to add labels after moving spines, otherwise they will disappear
    ax1xlabel = ax1.set_xlabel("Nucleotide", horizontalalignment="left", fontsize=14, labelpad=0)
    x,y = ax1xlabel.get_position()
    ax1xlabel.set_position((0,y))
    ax1ylabel = ax1.set_ylabel("Shape Reactivity", horizontalalignment="left", fontsize=14)
    x,y = ax1ylabel.get_position()
    ax1ylabel.set_position((x,0))

    if reactivity is not None:
        # add a SHAPE colorbar to the vertical axis
        # uses a little transformation magic to place correctly
        inv = ax1.transData.inverted()
        for loc, spine in ax1.spines.items():
            if loc == 'left':
                trans = spine.get_transform()
        pt = trans.transform_point([0,0])
        pt2 = inv.transform_point(pt)
        rectX = pt2[0]
        ptA = (0,0)
        ptB = (6,0)
        ptA2 = inv.transform_point(ptA)
        ptB2 = inv.transform_point(ptB)
        rectW = ptB2[0]-ptA2[0]
        rect = Rectangle((rectX,-0.5), rectW, orange_thresh+0.5, facecolor="black", edgecolor="none")
        ax1.add_patch(rect)
        rect.set_clip_on(False)
        rect = Rectangle((rectX,orange_thresh), rectW, red_thresh-orange_thresh, facecolor="orange", edgecolor="none")
        ax1.add_patch(rect)
        rect.set_clip_on(False)
        rect = Rectangle((rectX,red_thresh), rectW, 4-red_thresh, facecolor="red", edgecolor="none")
        ax1.add_patch(rect)
        rect.set_clip_on(False)

    ax1.get_xaxis().tick_bottom()   # remove unneeded ticks
    ax1.get_yaxis().tick_left()

    ax1.tick_params(axis='y',which='minor',left='off')
    #ax1.tick_params(axis='x',which='minor')

    ax1.minorticks_on()

    yticks = ax1.get_yticks()
    stripped_ticks = [str(val).rstrip('0').rstrip('.') for val in yticks]
    ax1.set_yticklabels(stripped_ticks)

    for line in ax1.get_yticklines():
        line.set_markersize(6)
        line.set_markeredgewidth(1)

    for line in ax1.get_xticklines():
        line.set_markersize(7)
        line.set_markeredgewidth(2)

    for line in ax1.xaxis.get_ticklines(minor=True):
        line.set_markersize(5)
        line.set_markeredgewidth(1)


    # put nuc sequence below axis
    font_prop = mp.font_manager.FontProperties(family = "monospace", style="normal",weight="bold",size="4.5")
    for i in range(seq.shape[0]):
        nuc = seq[i]
        if nuc == "T":
            nuc = "U"
        color_dict = {"A": "#f20000",
                      "U": "#f28f00",
                      "G": "#00509d",
                      "C": "#00c200"}
        if nuc in color_dict:
            col = color_dict[nuc]
        elif nuc.upper() in color_dict:
            col = color_dict[nuc.upper()]
        else:
            col = "black"
        ax1.annotate(nuc, xy=(i+1, -0.67),fontproperties=font_prop,color=col,annotation_clip=False, horizontalalignment="center")

    handles = []
    h, = ax2.plot(num, rx_simple_depth, linewidth = 1.5, color=rx_color, alpha=1.0)
    ax2.plot(num, rx_depth, linewidth = 1.0, color=rx_color, alpha=0.3)
    handles.append(h)
    h, = ax2.plot(num, bg_simple_depth, linewidth = 1.5, color=bg_color, alpha=1.0)
    ax2.plot(num, bg_depth, linewidth = 1.0, color=bg_color, alpha=0.3)
    handles.append(h)
    h, = ax2.plot(num, dc_simple_depth, linewidth = 1.5, color=dc_color, alpha=1.0)
    ax2.plot(num, dc_depth, linewidth = 1.0, color=dc_color, alpha=0.3)
    handles.append(h)
    ax2.set_xlim(1,len(num))
    #ax2.legend(["+Reagent","Background","Denatured"], bbox_to_anchor=(1.1,1.1))
    leg = ax2.legend(handles, legend_labels, loc=2, borderpad=0.8, handletextpad=0.2, framealpha=0.75)
    xmin, xmax, ymin, ymax = ax2.axis()
    ax2.set_ylim(0,ymax)
    #ax2.set_yscale('log')
    #ax2.set_yscale('symlog')# useful, but disabled because of a matplotlib/pyparsing bug
    ax2xlabel = ax2.set_xlabel("Nucleotide\n(note: effective read depths shown in lighter colors)", horizontalalignment="left", fontsize=14, labelpad=0)
    x,y = ax2xlabel.get_position()
    ax2xlabel.set_position((0,y))

    ax2.spines["right"].set_visible(False)
    ax2.spines["top"].set_visible(False)
    ax2.get_xaxis().tick_bottom()   # remove unneeded ticks
    ax2.get_yaxis().tick_left()

    ax2.minorticks_on()
    ax2.tick_params(axis='y',which='minor',left='off')
    #ax2.tick_params(axis='x',which='minor')

    #xlabels = ["%.2f"%v for v in xticks]
    #ax3.set_xticks(xticks)
    #ax3.set_xticklabels(xlabels,rotation = -45, horizontalalignment='left')

    yticks = [int(y) for y in ax2.get_yticks()]
    formatted_ticks = []
    for val in yticks:
        formatted_ticks.append(metric_abbreviate(val))
    ax2.set_yticklabels(formatted_ticks)

    for line in ax2.get_yticklines():
        line.set_markersize(6)
        line.set_markeredgewidth(1)

    for line in ax2.get_xticklines():
        line.set_markersize(7)
        line.set_markeredgewidth(2)

    for line in ax2.xaxis.get_ticklines(minor=True):
        line.set_markersize(5)
        line.set_markeredgewidth(1)

    ax2.yaxis.grid(True)
    ax2.set_axisbelow(True)

    ax2ylabel = ax2.set_ylabel("Read depth", horizontalalignment="left", fontsize=14)
    x, y = ax2ylabel.get_position()
    ax2ylabel.set_position((x, 0))
    # tried to make an offset, smaller font note about effective depths,
    # but couldn't get positioning/transforms to work properly.
    # For now just putting in xaxis label

    # choose a decent range for axis, excluding high-background positions
    good_indices = []
    for i in range(len(bg_rates)):
        if bg_rates[i]<=0.05 or isnan(bg_rates[i]):
            good_indices.append(i)
    temp_rates = [rx_rates[i] for i in good_indices]
    near_top_rate = percentile(temp_rates,98.0)
    maxes = [0.32,0.16,0.08,0.04,0.02,0.01]
    ymax = maxes[0]
    for i in range(len(maxes)):
        if near_top_rate<maxes[i]:
            ymax = maxes[i]

    rx_upper = rx_rates + rx_err
    rx_lower = rx_rates - rx_err
    bg_upper = bg_rates + bg_err
    bg_lower = bg_rates - bg_err
    dc_upper = dc_rates + dc_err
    dc_lower = dc_rates - dc_err

    ax3xlabel = ax3.set_xlabel("Nucleotide", horizontalalignment="left", fontsize=14, labelpad=0)
    x,y = ax3xlabel.get_position()
    ax3xlabel.set_position((0,y))
    ax3ylabel = ax3.set_ylabel("Mutation rate (%)", horizontalalignment="left", fontsize=14)
    x,y = ax3ylabel.get_position()
    ax3ylabel.set_position((x,0))

    ax3.plot(num, rx_rates, zorder=3, color=rx_color, linewidth=1.5)
    ax3.plot(num, bg_rates, zorder=2, color=bg_color, linewidth=1.5)
    ax3.plot(num, dc_rates, zorder=2, color=dc_color, linewidth=1.5)
    ax3.fill_between(num, rx_lower, rx_upper, edgecolor="none", alpha=0.5, facecolor=rx_color)
    ax3.fill_between(num, bg_lower, bg_upper, edgecolor="none", alpha=0.5, facecolor=bg_color)
    ax3.fill_between(num, dc_lower, dc_upper, edgecolor="none", alpha=0.5, facecolor=dc_color)
    ax3.legend(legend_labels, loc=2, borderpad=0.8, handletextpad=0.2, framealpha=0.75)
    ax3.set_xlim((1,len(rx_rates)))
    ax3.set_ylim((0,ymax))

    ax3.spines["right"].set_visible(False)
    ax3.spines["top"].set_visible(False)
    ax3.get_xaxis().tick_bottom()   # remove unneeded ticks
    ax3.get_yaxis().tick_left()

    ax3.minorticks_on()
    ax3.tick_params(axis='y',which='minor',left='off')

    ticks = [x*100 for x in ax3.get_yticks()]
    ax3.set_yticklabels([str(val).rstrip('0').rstrip('.') for val in ticks])

    for line in ax3.get_yticklines():
        line.set_markersize(6)
        line.set_markeredgewidth(1)

    for line in ax3.get_xticklines():
        line.set_markersize(7)
        line.set_markeredgewidth(2)

    for line in ax3.xaxis.get_ticklines(minor=True):
        line.set_markersize(5)
        line.set_markeredgewidth(1)

    ax3.yaxis.grid(True)
    ax3.set_axisbelow(True)

    # TODO: add a tick for the first nuc - can't seem to add one without screwing
    # up all the other ticks

    plt.savefig(fileout)
Exemplo n.º 12
0
 def draw_border(axis):
     from matplotlib.patches import Rectangle
     rec = Rectangle((0, 0), 1, 1,
         fill=False, lw=2, transform=axis.transAxes)
     rec = axis.add_patch(rec)
     rec.set_clip_on(False)
Exemplo n.º 13
0
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.legend(loc='lower left', bbox_to_anchor=(1, 0), frameon=False)
ax.set_title('Die Spannbreite der Ticketpreise',
             size=18,
             horizontalalignment='left')
ax.yaxis.set_ticks_position('left')
ax.xaxis.set_ticks_position('bottom')
ax.tick_params(axis='y', direction='out')
#add frames
autoAxis = ax.axis()
rec = Rectangle((autoAxis[0] - 5, autoAxis[2] - 10),
                (autoAxis[1] - autoAxis[0]) + 50,
                (autoAxis[3] - autoAxis[2]) + 30,
                fill=False,
                lw=1,
                edgecolor="darkkhaki")
rec = ax.add_patch(rec)
rec.set_clip_on(False)
rec2 = Rectangle((autoAxis[0] - 5, autoAxis[2] + 142),
                 (autoAxis[1] - autoAxis[0]) + 50,
                 (autoAxis[3] - autoAxis[2]) - 120,
                 fill=True,
                 lw=1,
                 edgecolor="darkkhaki",
                 facecolor="darkkhaki")
rec2 = ax.add_patch(rec2)
rec2.set_clip_on(False)
#save the plot
fig.savefig("plot.png")
def writeFigures(num,reactivity,stdev,
                 rxRates,bgRates,dcRates,
                 rxErr,bgErr,dcErr,
                 rxDepth,bgDepth,dcDepth,
                 name,outputDir):
    errFlag = False
    try:
        import matplotlib as mp
        mp.rcParams["font.sans-serif"].insert(0,"Arial") # If matplotlib can find this font, then Illustrator
                                                         # should be able to open the correct font on PDF import
                                                         # rather than replacing it. Matplotlib generally falls
                                                         # back to Bitstream fonts, which Illustrator usually
                                                         # can't locate by default.
        mp.rcParams["font.family"] = "sans-serif"
        mp.rcParams["pdf.fonttype"] = 42 # use TrueType fonts when exporting pdfs (embeds most fonts)
        mp.rcParams['xtick.direction'] = 'out'
        mp.rcParams['ytick.direction'] = 'out'
        mp.rcParams['legend.fontsize'] = 14
        mp.rcParams['grid.color'] = ".8"
        mp.rcParams['grid.linestyle'] = '-'
        mp.rcParams['grid.linewidth'] = 1
        mp.use('Agg')

        import matplotlib.pyplot as plt
        from matplotlib.patches import Rectangle
    except ImportError:
        sys.stderr.write("Warning: matplotlib python module was not found, so no figures were rendered for %i.\n"%(name))
        errFlag = True
    version = [int(v) for v in mp.__version__.split('.')]
    # Check that we have matplotlib version 1.2 or greater
    if version[0]<1 or (version[0]==1 and version[1]<2):
        sys.stderr.write("Warning: matplotlib version 1.2 or greater is recommended, but version %s was found, so no figures were rendered for %i.\n"%(mp.__version__,name))
        errFlag = True
    if errFlag==True:
        return False

    from numpy import percentile

    # Add a zeroeth nuc so axis numbering works correctly
    # There's probably a better way to do this
    num = [0]+num
    reactivity = [0]+reactivity
    stdev = [0]+stdev
    rxDepth = [0]+rxDepth
    bgDepth = [0]+bgDepth
    dcDepth = [0]+dcDepth
    rxRates = [0]+rxRates
    bgRates = [0]+bgRates
    dcRates = [0]+dcRates
    rxErr = [0]+rxErr
    bgErr = [0]+bgErr
    dcErr = [0]+dcErr

    orangeThresh = 0.4
    redThresh = 0.85

    grayVals = []
    grayNums = []
    grayErrs = []
    blackVals = []
    blackNums = []
    blackErrs = []
    orangeVals = []
    orangeNums = []
    orangeErrs = []
    redVals = []
    redNums = []
    redErrs = []
    for i in range(len(reactivity)):
        if reactivity[i] < -900:
            grayVals.append(-1)
            grayNums.append(num[i])
            grayErrs.append(0)
        elif reactivity[i] < orangeThresh:
            blackVals.append(reactivity[i])
            blackNums.append(num[i])
            blackErrs.append(stdev[i])
        elif reactivity[i] < redThresh:
            orangeVals.append(reactivity[i])
            orangeNums.append(num[i])
            orangeErrs.append(stdev[i])
        else:
            redVals.append(reactivity[i])
            redNums.append(num[i])
            redErrs.append(stdev[i])

    yMin, yMax = (-0.5, 4)
    leftInches = 0.9
    rightInches = 0.4
    spWidth = len(num)*0.032
    figWidth = max(7,spWidth+leftInches+rightInches)
    fig = plt.figure(figsize=(figWidth,8))
    leftPercent = leftInches/figWidth
    rightPercent = 1-rightInches/figWidth
    ax1 = plt.subplot(311)
    ax2 = plt.subplot(313)
    ax3 = plt.subplot(312)
    plt.subplots_adjust(hspace=0.5, left=leftPercent,right=rightPercent,top=0.94)

    nearBlack = (0,0,1/255.0)

    if len(grayNums)>0:
        ax1.bar(grayNums,grayVals,
                 align="center",
                 width=1.05, color="0.80", edgecolor="0.80",linewidth=0.0)
    if len(blackNums)>0:
        ax1.bar(blackNums,blackVals,
                 align="center",
                 width=1.05, color="black", edgecolor="black",linewidth=0.0,
                 yerr=blackErrs,ecolor=nearBlack,capsize=1)
    if len(orangeNums)>0:
        ax1.bar(orangeNums,orangeVals,
                 align="center",
                 width=1.05, color="orange",edgecolor="orange",linewidth=0.0,
                 yerr=orangeErrs,ecolor=nearBlack,capsize=1)
    if len(redNums)>0:
        ax1.bar(redNums,redVals,
                 align="center",
                 width=1.05,color="red",edgecolor="red",linewidth=0.0,
                 yerr=redErrs,ecolor=nearBlack,capsize=1)
    
    ax1title = ax1.set_title(name, horizontalalignment="left", fontsize=16)
    x,y = ax1title.get_position()
    ax1title.set_position((0,y))
    ax1.set_ylim(yMin,yMax)
    ax1.set_xlim(1,len(num))
    #ax1.set_yticks(fontsize=9)

    #tickNums = range(num[0]+10,num[-1]+1,10)
    #tickPos = range(num[0]+9,num[-1],10)
    #ax1.set_xticks(tickPos,tickNums,fontsize=9,rotation=30)
    #ax1.set_xticks(fontsize=9)

    ax1.yaxis.grid(True)
    ax1.set_axisbelow(True)

    ax1.spines["right"].set_visible(False)
    ax1.spines["top"].set_visible(False)
    for loc, spine in ax1.spines.items():
        if loc == 'bottom':
            spine.set_position(('outward', 6))  # move outward (down) 6 pts
            spine.set_smart_bounds(True)
    for loc, spine in ax1.spines.items():
        if loc == 'left':
            spine.set_position(('outward', 6))  # move outward (left) 6 pts
            spine.set_smart_bounds(True)

    # need to add labels after moving spines, otherwise they will disappear
    ax1xlabel = ax1.set_xlabel("Nucleotide", horizontalalignment="left", fontsize=14, labelpad=0)
    x,y = ax1xlabel.get_position()
    print str((x,y))
    ax1xlabel.set_position((0,y))
    ax1ylabel = ax1.set_ylabel("Shape Reactivity", horizontalalignment="left", fontsize=14)
    x,y = ax1ylabel.get_position()
    ax1ylabel.set_position((x,0))

    # add a SHAPE colorbar to the vertical axis
    # uses a little transformation magic to place correctly
    inv = ax1.transData.inverted()
    for loc, spine in ax1.spines.items():
        if loc == 'left':
            trans = spine.get_transform()
    pt = trans.transform_point([0,0])
    pt2 = inv.transform_point(pt)
    rectX = pt2[0]
    ptA = (0,0)
    ptB = (6,0)
    ptA2 = inv.transform_point(ptA)
    ptB2 = inv.transform_point(ptB)
    rectW = ptB2[0]-ptA2[0]    
    rect = Rectangle((rectX,-0.5), rectW, orangeThresh+0.5, facecolor="black", edgecolor="none")
    ax1.add_patch(rect)
    rect.set_clip_on(False)
    rect = Rectangle((rectX,orangeThresh), rectW, redThresh-orangeThresh, facecolor="orange", edgecolor="none")
    ax1.add_patch(rect)
    rect.set_clip_on(False)
    rect = Rectangle((rectX,redThresh), rectW, 4-redThresh, facecolor="red", edgecolor="none")
    ax1.add_patch(rect)
    rect.set_clip_on(False)
    
    ax1.get_xaxis().tick_bottom()   # remove unneeded ticks
    ax1.get_yaxis().tick_left()

    ax1.tick_params(axis='y',which='minor',left='off')
    #ax1.tick_params(axis='x',which='minor')

    ax1.minorticks_on()

    yticks = ax1.get_yticks()
    #print str(yticks)
    strippedTicks = ["%d"%val if val==int(val) else "%s"%val for val in yticks]
    ax1.set_yticklabels(strippedTicks)
    
    for line in ax1.get_yticklines():
        line.set_markersize(6)
        line.set_markeredgewidth(1)

    for line in ax1.get_xticklines():
        line.set_markersize(7)
        line.set_markeredgewidth(2)

    for line in ax1.xaxis.get_ticklines(minor=True):
        line.set_markersize(5)
        line.set_markeredgewidth(1)

    
    # put nuc sequence below axis
    fontProp = mp.font_manager.FontProperties(family = "monospace", style="normal",weight="bold",size="4.5")
    for i in range(len(seq)):
        nuc = seq[i]
        if nuc == "T":
            nuc = "U"
        colorDict = {"A":"#f20000",
                     "U":"#f28f00",
                     "G":"#00509d",
                     "C":"#00c200"}
        if nuc in colorDict.keys():
            col = colorDict[nuc]
        else:
            col = "black"
        ax1.annotate(nuc, xy=(i+1, -0.67),fontproperties=fontProp,color=col,annotation_clip=False, horizontalalignment="center")

    ax2.plot(num,rxDepth, linewidth = 1.5, color=rxColor)
    ax2.plot(num,bgDepth, linewidth = 1.5, color=bgColor)
    ax2.plot(num,dcDepth, linewidth = 1.5, color=dcColor)
    ax2.set_xlim(1,len(num))
    #ax2.legend(["+Reagent","Background","Denatured"], bbox_to_anchor=(1.1,1.1))
    leg = ax2.legend(["Modified","Untreated","Denatured"], loc=2, borderpad=0.8, handletextpad=0.2, framealpha=0.75)
    xmin, xmax, ymin, ymax = ax2.axis()
    ax2.set_ylim(0,ymax)
    #ax2.set_yscale('symlog')# useful but currently disabled because of a matplotlib/pyparsing bug
    ax2xlabel = ax2.set_xlabel("Nucleotide", horizontalalignment="left", fontsize=14, labelpad=0)
    x,y = ax2xlabel.get_position()
    ax2xlabel.set_position((0,y))
    ax2ylabel = ax2.set_ylabel("Read depth", horizontalalignment="left", fontsize=14)
    x,y = ax2ylabel.get_position()
    ax2ylabel.set_position((x,0))
    #ax2title = ax2.set_title(name, horizontalalignment="left")
    #x,y = ax2title.get_position()
    #ax2title.set_position((0,y))

    ax2.spines["right"].set_visible(False)
    ax2.spines["top"].set_visible(False)
    ax2.get_xaxis().tick_bottom()   # remove unneeded ticks
    ax2.get_yaxis().tick_left()

    ax2.minorticks_on()
    ax2.tick_params(axis='y',which='minor',left='off')
    #ax2.tick_params(axis='x',which='minor')

    #xlabels = ["%.2f"%v for v in xticks]
    #ax3.set_xticks(xticks)
    #ax3.set_xticklabels(xlabels,rotation = -45, horizontalalignment='left')

    yticks = [int(y) for y in ax2.get_yticks()]
    formattedTicks = []
    for val in yticks:
        formattedTicks.append(metricAbbreviate(val))
    ax2.set_yticklabels(formattedTicks)

    for line in ax2.get_yticklines():
        line.set_markersize(6)
        line.set_markeredgewidth(1)

    for line in ax2.get_xticklines():
        line.set_markersize(7)
        line.set_markeredgewidth(2)

    for line in ax2.xaxis.get_ticklines(minor=True):
        line.set_markersize(5)
        line.set_markeredgewidth(1)

    ax2.yaxis.grid(True)
    ax2.set_axisbelow(True)

    # choose a decent range for axis, excluding high-background positions
    goodIndices = []
    for i in xrange(len(bgRates)):
        if bgRates[i]<=conf.maxBackground:
            goodIndices.append(i)
    tempRates = [rxRates[i] for i in goodIndices]
    nearTopRate = percentile(tempRates,98.0)
    maxes = [0.32,0.16,0.08,0.04,0.02,0.01]
    yMax = maxes[0]
    for i in xrange(len(maxes)):
        if nearTopRate<maxes[i]:
            yMax = maxes[i]

    rxUpper = [rxRates[i]+rxErr[i] for i in xrange(len(rxRates))]
    rxLower = [rxRates[i]-rxErr[i] for i in xrange(len(rxRates))]
    bgUpper = [bgRates[i]+bgErr[i] for i in xrange(len(bgRates))]
    bgLower = [bgRates[i]-bgErr[i] for i in xrange(len(bgRates))]
    dcUpper = [dcRates[i]+dcErr[i] for i in xrange(len(dcRates))]
    dcLower = [dcRates[i]-dcErr[i] for i in xrange(len(dcRates))]

    ax3xlabel = ax3.set_xlabel("Nucleotide", horizontalalignment="left", fontsize=14, labelpad=0)
    x,y = ax3xlabel.get_position()
    ax3xlabel.set_position((0,y))
    ax3ylabel = ax3.set_ylabel("Mutation rate (%)", horizontalalignment="left", fontsize=14)
    x,y = ax3ylabel.get_position()
    ax3ylabel.set_position((x,0))
    
    ax3.plot(rxRates, zorder=3,color=rxColor,linewidth=1.5)
    ax3.plot(bgRates, zorder=2, color=bgColor, linewidth=1.5)
    ax3.fill_between(num,rxLower,rxUpper,edgecolor="none",alpha=0.5, facecolor=rxColor)
    ax3.fill_between(num,bgLower,bgUpper,edgecolor="none",alpha=0.5, facecolor=bgColor)
    ax3.legend(["Modified","Untreated"], loc=2, borderpad=0.8, handletextpad=0.2, framealpha=0.75)
    ax3.set_xlim((1,len(rxRates)))
    ax3.set_ylim((0,yMax))

    ax3.spines["right"].set_visible(False)
    ax3.spines["top"].set_visible(False)
    ax3.get_xaxis().tick_bottom()   # remove unneeded ticks
    ax3.get_yaxis().tick_left()

    ax3.minorticks_on()
    ax3.tick_params(axis='y',which='minor',left='off')

    ticks = [x*100 for x in ax3.get_yticks()]
    ax3.set_yticklabels(["%d"%val if val==int(val) else "%s"%val for val in ticks])

    for line in ax3.get_yticklines():
        line.set_markersize(6)
        line.set_markeredgewidth(1)

    for line in ax3.get_xticklines():
        line.set_markersize(7)
        line.set_markeredgewidth(2)

    for line in ax3.xaxis.get_ticklines(minor=True):
        line.set_markersize(5)
        line.set_markeredgewidth(1)

    ax3.yaxis.grid(True)
    ax3.set_axisbelow(True)

    # TODO: add a tick for the first nuc - can't seem to add one without screwing
    # up all the other ticks

    outPath = os.path.join(outputDir,"reactivity_profiles")
    outPath = os.path.join(outPath,name+"_depth_and_reactivity.pdf")
    plt.savefig(outPath)
    return True
Exemplo n.º 15
0
from matplotlib.patches import Rectangle

# build a rectangle in axes coords
left, width = .25, .5
bottom, height = .25, .5
right = left + width
top = bottom + height
ax = gca()
p = Rectangle(
    (left, bottom),
    width,
    height,
    fill=False,
)
p.set_transform(ax.transAxes)
p.set_clip_on(False)
ax.add_patch(p)

ax.text(left,
        bottom,
        'left top',
        horizontalalignment='left',
        verticalalignment='top',
        transform=ax.transAxes)

ax.text(left,
        bottom,
        'left bottom',
        horizontalalignment='left',
        verticalalignment='bottom',
        transform=ax.transAxes)
Exemplo n.º 16
0
def plot_cnn_output(output,
                    path,
                    name,
                    title=None,
                    image=None,
                    video=False,
                    verbose=True,
                    highlight=None):
    """
    This function creates a plot of the cnn output.
    :param output: response from cnn (28,28,256)
    :param path: folder where to save plot
    :param name: name of plot
    :param title: title of plot
    :param image: if given, the image is displayed
    :param video: if true an animation is created,
        output shape should then be (#frames, 28,28,256) and image either none or (#frames)
    :param verbose:
    :param highlight: list of int, highlights the feature map at given indices by a red rectangle
    :return:
    """
    if verbose:
        print("start plot_cnn_output of", name)

    num_ft = output.shape[-1]
    n_col = math.ceil(np.sqrt(num_ft))
    n_rows = math.ceil(num_ft / n_col)
    vmin, vmax = np.min(output), np.max(output)
    fig, axs = plt.subplots(n_rows, n_col, figsize=(n_rows + 3, n_col))
    # add entry to matrix if there's not enough columns/rows so np.ndenumerate can unpack two values
    if n_col == 1 and n_rows == 1:
        axs = [[axs]]
    elif n_rows == 1:
        axs = [axs]

    plt.subplots_adjust(right=0.75, wspace=0.1, hspace=0.1)

    # add title
    if title is not None:
        fig.suptitle(title)

    ax_colorbar = fig.add_axes([0.83, 0.1, 0.02, 0.65])

    # add image input
    if image is not None:
        ax_image = fig.add_axes([0.78, 0.78, .12, .12])
        if np.max(image) > 1:
            if verbose:
                print("transform image data to RGB [0..1] from [0..255]")
            image = image / 255

    if not os.path.exists(path):
        os.mkdir(path)

    # add highlight
    if highlight is not None:
        for index_highlight in highlight:
            multi_index_highlight = np.unravel_index(index_highlight,
                                                     (n_rows, n_col))
            if video:
                size_axis = output.shape[1]
            else:
                size_axis = output.shape[0]
            rec = Rectangle((0, 0),
                            size_axis,
                            size_axis,
                            fill=False,
                            lw=size_axis * 0.15,
                            edgecolor='r')
            rec = axs[multi_index_highlight].add_patch(rec)
            rec.set_clip_on(False)

    update_list = []

    def update(n_frame):
        if verbose and n_frame >= 0:
            print("frame: {}/{}".format(n_frame, output.shape[0]), end="\r")
        if not video:
            data = output
        else:
            data = output[n_frame, ...]

        # loop over all feature maps
        for (i, j), ax in np.ndenumerate(axs):
            n = i * n_col + j
            try:
                # old way, not sure to understand what Tim tried to do here
                # ax.get_images()[0].set_data(data[..., n])
                im = ax.imshow(data[..., n], vmin=vmin, vmax=vmax)
                update_list.append(im)
            except IndexError:
                # old way, not sure to understand what Tim did here
                # im = ax.imshow(data[...,n], vmin=vmin, vmax=vmax)
                # update_list.append(im)
                pass
            ax.axis('off')
        # add input image
        if image is not None:
            if video:
                image_frame = image[n_frame]
            else:
                image_frame = image
            try:
                ax_image.get_images()[0].set_data(image_frame)
            except IndexError:
                im_image = ax_image.imshow(image_frame)
                update_list.append(im_image)
                ax_image.axis('off')

        # display color bar
        if n_frame <= 0:
            cbar = fig.colorbar(im, cax=ax_colorbar)

        return update_list

    if not video:
        update(-1)
        fig.savefig(os.path.join(path, name))
    else:

        def init_func():
            return []

        anim = FuncAnimation(fig,
                             update,
                             frames=output.shape[0],
                             init_func=init_func,
                             blit=True,
                             interval=33)
        writergif = animation.PillowWriter(fps=30)
        anim.save(os.path.join(path, name), writer=writergif)

    if verbose:
        print("finished plot_cnn_output of", name)
Exemplo n.º 17
0
    def create_design_plot(self):
        """Creates a RNAi design plot."""

        # Temp file for storing
        temp_img_file = tempfile.mkstemp()

        # Create main figure
        fig, ax1 = plt.subplots(figsize=(15, 4))

        off_target_dict, main_target_dict, efficient_dict, main_hits_histo = general_helpers.get_target_data(self.f_in, self.sirna_size)

        # If there are no hits, we show only the efficient sirnas for designing a construct
        if self.main_targets == []:
            off_target_dict = {}
            main_target_dict = {}
            main_hits_histo = []

        # Off-target position list
        off_targets_pos = set()
        for i in off_target_dict.values():
            off_targets_pos = off_targets_pos | i

        # Main-target position list
        main_targets_plot = set()
        for i in main_target_dict.values():
            main_targets_plot = main_targets_plot | i

        # Efficient position list
        eff_sirna_plot = []
        for i in efficient_dict.values():
            eff_sirna_plot.extend(i)
        eff_sirna_plot.sort()

        # Draw efficiency plot
        eff_sirna_histo = np.bincount(eff_sirna_plot, minlength=self.query_length)
        ax1.plot(eff_sirna_histo, 'r-', label='Efficient siRNA hits')

        # Draw main target histogram
        main_histo = np.bincount(main_hits_histo, minlength=self.query_length)
        ax1.plot(main_histo, 'b-', label='Main target siRNA hits')

        # Draw main targets as green rectangles inside plot figure
        for region in main_targets_plot:
            someX, someY = region, 0.
            currentAxis = fig.gca()
            tri1 = Rectangle((someX, someY), 1, self.sirna_size + 3, color='g', alpha=0.2)#, label='green')
            currentAxis.add_patch(tri1)
            tri1.set_clip_on(False)
        
        # Draw off-targets as red rectangles inside plot figure
        for off_target in off_targets_pos:
            someX, someY = off_target, 0.
            currentAxis = fig.gca()
            tri2 = Rectangle((someX, someY), 1, self.sirna_size + 3, color='r', alpha=0.2)#, label='red')
            currentAxis.add_patch(tri2)
            tri2.set_clip_on(False)

        if max(eff_sirna_histo) > self.sirna_size:
            max_y = max(eff_sirna_histo) + 3
        else:
            max_y = self.sirna_size + 3

        ax1.set_ylim([0, max_y])
        x_text = 'mRNA sequence position\n\n'
        ax1.set_xlabel(x_text, fontsize=12)
        ax1.xaxis.set_ticks(np.arange(0, self.query_length, 50))
        ax1.set_ylabel('Nr of siRNAs', color='b', fontsize=12)
        ax1.set_xlim([0, self.query_length])
        plt.title("RNAi design plot\n\n", fontsize=14)
        plt.tight_layout()
        p1 = Rectangle((0, 0), 1, 1, fc="g", alpha=0.2)
        p2 = Rectangle((0, 0), 1, 1, fc="r", alpha=0.2)
        p3 = mlines.Line2D([], [], color='r')
        p4 = mlines.Line2D([], [], color='b')
        plt.legend([p1,p2, p3, p4], ["Main target", "Off target", 'Efficient siRNAs', 'All siRNAs'],
                    bbox_to_anchor=(0., 1.02, 1., .102), loc=4, ncol=4, mode="", borderaxespad=0.5, frameon=True)
        plt.savefig(temp_img_file[1] + '.png')

        #plt.show()
        plt.close(fig)
        return temp_img_file[1] + '.png', off_target_dict, main_target_dict
Exemplo n.º 18
0
    def highlight_artist(self, val, artist=None):
        from ifigure.matplotlib_mod.art3d_gl import Poly3DCollectionGL
        from ifigure.matplotlib_mod.art3d_gl import Line3DCollectionGL
        figure = self.get_figpage()._artists[0]
        ax = self.get_figaxes()
        if artist is None:
            alist = self._artists
        else:
            alist = artist

        if val == True:
            if self._parent is None: return
            container = self.get_container()
            if container is None: return

            if isinstance(alist[0], Poly3DCollectionGL):
                hl = alist[0].add_hl_mask()
                for item in hl:
                    alist[0].figobj_hl.append(item)
            else:
                de = self.get_data_extent()
                x = (de[0], de[1], de[1], de[0], de[0])
                y = (de[2], de[2], de[3], de[3], de[2])

                facecolor = 'k'
                if isinstance(alist[0], Poly3DCollectionGL):
                    hl = alist[0].make_hl_artist(container)
                    facecolor = 'none'
                    self._hit_path = None
                elif isinstance(alist[0], Line3DCollectionGL):
                    hl = alist[0].make_hl_artist(container)
                    facecolor = 'none'
                    self._hit_path = None
                else:
                    hl = container.plot(x,
                                        y,
                                        marker='s',
                                        color='k',
                                        linestyle='None',
                                        markerfacecolor='None',
                                        markeredgewidth=0.5,
                                        scalex=False,
                                        scaley=False)
                for item in hl:
                    alist[0].figobj_hl.append(item)

                if self._hit_path is not None:
                    v = self._hit_path.vertices
                    hl = container.plot(v[:, 0],
                                        v[:, 1],
                                        marker='s',
                                        color='k',
                                        linestyle='None',
                                        markerfacecolor='None',
                                        markeredgewidth=0.5,
                                        scalex=False,
                                        scaley=False)
                    for item in hl:
                        alist[0].figobj_hl.append(item)

                hlp = Rectangle((de[0], de[2]),
                                de[1] - de[0],
                                de[3] - de[2],
                                alpha=0.3,
                                facecolor=facecolor,
                                figure=figure,
                                transform=container.transData)
                if ax is not None:
                    x0, y0 = ax._artists[0].transAxes.transform((0, 0))
                    x1, y1 = ax._artists[0].transAxes.transform((1, 1))
                    bbox = Bbox([[x0, y0], [x1, y1]])
                    hlp.set_clip_box(bbox)
                    hlp.set_clip_on(True)
                figure.patches.append(hlp)
                alist[0].figobj_hl.append(hlp)
        else:
            for a in alist:
                if len(a.figobj_hl) == 0: continue
                for hl in a.figobj_hl[:-1]:
                    hl.remove()
                if isinstance(alist[0], Poly3DCollectionGL):
                    a.figobj_hl[-1].remove()
                else:
                    figure.patches.remove(a.figobj_hl[-1])
                a.figobj_hl = []
Exemplo n.º 19
0
    def generateGraph(self,
                      data=None,
                      outputFilename=None,
                      timeDivisions=6,
                      graphWidth=1920,
                      graphHeight=300,
                      darkMode=False,
                      rainVariance=False,
                      minMaxTemperature=False,
                      fontSize=12,
                      symbolZoom=1.0,
                      symbolDivision=1,
                      showCityName=None,
                      writeMetaData=None):
        logging.debug("Initializing graph...")
        if darkMode:
            colors = self.colorsDarkMode
        else:
            colors = self.colorsLightMode

        fig = plt.figure(0)  # Main figure
        rainAxis = fig.add_subplot(111)

        # set font sizes
        plt.rcParams.update({'font.size':
                             fontSize})  # Temperature Y axis and day names
        rainAxis.tick_params(axis='y', labelsize=fontSize)  # Rain Y axis
        plt.xticks(fontsize=fontSize)  # Time axis

        if not graphWidth:
            graphWidth = 1280
        if not graphHeight:
            graphHeight = 300
        logging.debug("Graph size: %d x %d pixel" % (graphWidth, graphHeight))
        fig.set_size_inches(
            float(graphWidth) / fig.get_dpi(),
            float(graphHeight) / fig.get_dpi())

        # Plot dimension and borders
        bbox = rainAxis.get_window_extent().transformed(
            fig.dpi_scale_trans.inverted())
        width, height = bbox.width * fig.dpi, bbox.height * fig.dpi  # plot size in pixel

        plt.margins(x=0)
        rainAxis.margins(x=0)

        plt.subplots_adjust(left=40 / width,
                            right=1 - 40 / width,
                            top=1 - 35 / height,
                            bottom=40 / height)

        bbox = rainAxis.get_window_extent().transformed(
            fig.dpi_scale_trans.inverted())
        width, height = bbox.width * fig.dpi, bbox.height * fig.dpi  # plot size in pixel
        xPixelsPerDay = width / data["noOfDays"]

        # Dimensions of the axis in pixel
        firstDayX = math.ceil(bbox.x0 * fig.dpi)
        firstDayY = math.ceil(bbox.y0 * fig.dpi)
        dayWidth = math.floor((bbox.x1 - bbox.x0) * fig.dpi) / data["noOfDays"]
        dayHeight = math.floor((bbox.y1 - bbox.y0) * fig.dpi)

        # Show gray background on every 2nd day
        for day in range(0, data["noOfDays"], 2):
            plt.axvspan(data["timestamps"][0 + day * 24],
                        data["timestamps"][23 + day * 24] + 3600,
                        facecolor='gray',
                        alpha=0.2)

        # Time axis and ticks
        plt.xticks(data["timestamps"][::timeDivisions],
                   data["formatedTime"][::timeDivisions])
        rainAxis.tick_params(axis='x', colors=colors["x-axis"])

        # Rain (data gets splitted to stacked bars)
        logging.debug("Creating rain plot...")
        rainBars = [0] * len(self.rainColorSteps)

        for i in range(0, len(self.rainColorSteps)):
            rainBars[i] = []

        for rain in data["rainfall"]:
            for i in range(0, len(self.rainColorSteps)):
                if rain > self.rainColorSteps[i]:
                    rainBars[i].append(self.rainColorStepSizes[i])
                else:
                    if i > 0:
                        rainBars[i].append(
                            max(rain - self.rainColorSteps[i - 1], 0))
                    else:
                        rainBars[i].append(rain)
                    continue

        rainAxis.bar(data["timestamps"],
                     rainBars[0],
                     width=3000,
                     color=self.rainColors[0],
                     align='edge')
        bottom = [0] * len(rainBars[0])
        for i in range(1, len(self.rainColorSteps)):
            bottom = np.add(bottom, rainBars[i - 1]).tolist()
            rainAxis.bar(data["timestamps"],
                         rainBars[i],
                         bottom=bottom,
                         width=3000,
                         color=self.rainColors[i],
                         align='edge')

        rainAxis.tick_params(axis='y',
                             labelcolor=colors["rain-axis"],
                             width=0,
                             length=8)
        rainYRange = plt.ylim()
        rainScaleMax = max(
            data["rainfall"]
        ) + 1  # Add a bit to make sure we do not bang our head
        plt.ylim(0, rainScaleMax)
        rainAxis.locator_params(axis='y', nbins=7)
        # TODO find a better way than rounding
        rainAxis.yaxis.set_major_formatter(FormatStrFormatter('%0.1f'))

        # Rain color bar as y axis
        plt.xlim(
            data["timestamps"][0], data["timestamps"][-1] +
            (data["timestamps"][1] - data["timestamps"][0]))
        pixelToRainX = 1 / xPixelsPerDay * (data["timestamps"][23] -
                                            data["timestamps"][0])
        x = data["timestamps"][-1] + (
            data["timestamps"][1] - data["timestamps"][0])  # end of x
        w = 7 * pixelToRainX

        for i in range(0, len(self.rainColorSteps)):
            y = self.rainColorSteps[i] - self.rainColorStepSizes[i]
            if y > rainScaleMax:
                break
            h = self.rainColorSteps[i] + self.rainColorStepSizes[i]
            if y + h >= rainScaleMax:  # reached top
                h = rainScaleMax - y
            rainScaleBar = Rectangle((x, y),
                                     w,
                                     h,
                                     fc=self.rainColors[i],
                                     alpha=1)
            rainAxis.add_patch(rainScaleBar)
            rainScaleBar.set_clip_on(False)

        rainScaleBorder = Rectangle((x, 0),
                                    w,
                                    rainScaleMax,
                                    fc="black",
                                    fill=False,
                                    alpha=1)
        rainAxis.add_patch(rainScaleBorder)
        rainScaleBorder.set_clip_on(False)

        # Rain variance
        if rainVariance:
            rainfallVarianceAxis = rainAxis.twinx(
            )  # instantiate a second axes that shares the same x-axis
            rainfallVarianceAxis.axes.yaxis.set_visible(False)

            timestampsCentered = [i + 1500 for i in data["timestamps"]]
            rainfallVarianceMin = np.subtract(
                np.array(data["rainfall"]),
                np.array(data["rainfallVarianceMin"]))
            rainfallVarianceMax = np.subtract(
                np.array(data["rainfallVarianceMax"]),
                np.array(data["rainfall"]))
            rainfallVarianceAxis.errorbar(
                timestampsCentered,
                data["rainfall"],
                yerr=[rainfallVarianceMin, rainfallVarianceMax],
                fmt="none",
                elinewidth=1,
                alpha=0.5,
                ecolor='black',
                capsize=3)
            plt.ylim(0, rainScaleMax)

        # Show when the model was last calculated
        timestampLocal = data[
            "modelCalculationTimestamp"] + self.utcOffset * 3600
        l = mlines.Line2D([timestampLocal, timestampLocal],
                          [rainYRange[0], rainScaleMax])
        rainAxis.add_line(l)

        # Temperature
        logging.debug("Creating temerature plot...")
        temperatureAxis = rainAxis.twinx(
        )  # instantiate a second axes that shares the same x-axis
        temperatureAxis.plot(data["timestamps"],
                             data["temperature"],
                             label="temperature",
                             color=self.temperatureColor,
                             linewidth=4)
        #temperatureAxis.set_ylabel('Temperature', color=self.temperatureColor)
        temperatureAxis.tick_params(axis='y',
                                    labelcolor=colors["temperature-axis"])
        temperatureAxis.grid(True)

        # Position the Y Scales
        temperatureAxis.yaxis.tick_left()
        rainAxis.yaxis.tick_right()

        # Make sure the temperature scaling has a gap of 45 pixel, so we can fit the labels

        interimPixelToTemperature = (np.nanmax(data["temperature"]) -
                                     np.nanmin(data["temperature"])) / height
        temperatureScaleMin = np.nanmin(
            data["temperature"]) - float(45) * interimPixelToTemperature
        temperatureScaleMax = np.nanmax(
            data["temperature"]) + float(45) * interimPixelToTemperature

        plt.ylim(temperatureScaleMin, temperatureScaleMax)
        temperatureAxis.locator_params(axis='y', nbins=6)
        temperatureAxis.yaxis.set_major_formatter(FormatStrFormatter('%0.1f'))
        pixelToTemperature = (temperatureScaleMax -
                              temperatureScaleMin) / height

        # Temperature variance
        temperatureVarianceAxis = temperatureAxis.twinx(
        )  # instantiate a second axes that shares the same x-axis
        temperatureVarianceAxis.axes.yaxis.set_visible(False)

        temperatureVarianceAxis.fill_between(data["timestamps"],
                                             data["temperatureVarianceMin"],
                                             data["temperatureVarianceMax"],
                                             facecolor=self.temperatureColor,
                                             alpha=0.2)
        temperatureVarianceAxis.tick_params(axis='y',
                                            labelcolor=self.temperatureColor)
        plt.ylim(temperatureScaleMin, temperatureScaleMax)

        logging.debug("Adding various additional information to the graph...")
        # Mark min/max temperature per day
        if minMaxTemperature:
            da = DrawingArea(2, 2, 0, 0)
            da.add_artist(
                Circle((1, 1),
                       4,
                       color=self.temperatureColor,
                       fc="white",
                       lw=2))
            for day in range(0, data["noOfDays"]):
                dayXPixelMin = day * xPixelsPerDay
                dayXPixelMax = (day + 1) * xPixelsPerDay - 1
                maxTemperatureOfDay = {"data": -100, "timestamp": 0}
                minTemperatureOfDay = {"data": +100, "timestamp": 0}
                for h in range(0, 24):
                    if data["temperature"][day * 24 +
                                           h] > maxTemperatureOfDay["data"]:
                        maxTemperatureOfDay["data"] = data["temperature"][day *
                                                                          24 +
                                                                          h]
                        maxTemperatureOfDay["timestamp"] = data["timestamps"][
                            day * 24 + h]
                        maxTemperatureOfDay["xpixel"] = (
                            data["timestamps"][day * 24 + h] -
                            data["timestamps"][0]) / (24 *
                                                      3600) * xPixelsPerDay
                        maxTemperatureOfDay["ypixel"] = (
                            data["temperature"][day * 24 + h] -
                            temperatureScaleMin) / (
                                temperatureScaleMax -
                                temperatureScaleMin) * height
                    if data["temperature"][day * 24 +
                                           h] < minTemperatureOfDay["data"]:
                        minTemperatureOfDay["data"] = data["temperature"][day *
                                                                          24 +
                                                                          h]
                        minTemperatureOfDay["timestamp"] = data["timestamps"][
                            day * 24 + h]
                        minTemperatureOfDay["xpixel"] = (
                            data["timestamps"][day * 24 + h] -
                            data["timestamps"][0]) / (24 *
                                                      3600) * xPixelsPerDay
                        minTemperatureOfDay["ypixel"] = (
                            data["temperature"][day * 24 + h] -
                            temperatureScaleMin) / (
                                temperatureScaleMax -
                                temperatureScaleMin) * height

                # Circles
                temperatureVarianceAxis.add_artist(
                    AnnotationBbox(da, (maxTemperatureOfDay["timestamp"],
                                        maxTemperatureOfDay["data"]),
                                   xybox=(maxTemperatureOfDay["timestamp"],
                                          maxTemperatureOfDay["data"]),
                                   xycoords='data',
                                   boxcoords=("data", "data"),
                                   frameon=False))
                temperatureVarianceAxis.add_artist(
                    AnnotationBbox(da, (minTemperatureOfDay["timestamp"],
                                        minTemperatureOfDay["data"]),
                                   xybox=(minTemperatureOfDay["timestamp"],
                                          minTemperatureOfDay["data"]),
                                   xycoords='data',
                                   boxcoords=("data", "data"),
                                   frameon=False))

                # Max Temperature Labels
                text = str(int(round(maxTemperatureOfDay["data"], 0))) + "°C"
                f = plt.figure(
                    1
                )  # Temporary figure to get the dimensions of the text label
                t = plt.text(0, 0, text, weight='bold')
                temporaryLabel = t.get_window_extent(
                    renderer=f.canvas.get_renderer())
                plt.figure(0)  # Select Main figure again

                # Check if text is fully within the day (x axis)
                if maxTemperatureOfDay[
                        "xpixel"] - temporaryLabel.width / 2 < dayXPixelMin:  # To far left
                    maxTemperatureOfDay[
                        "xpixel"] = dayXPixelMin + temporaryLabel.width / 2 + self.textShadowWidth / 2
                if maxTemperatureOfDay[
                        "xpixel"] + temporaryLabel.width / 2 > dayXPixelMax:  # To far right
                    maxTemperatureOfDay[
                        "xpixel"] = dayXPixelMax - temporaryLabel.width / 2 - self.textShadowWidth / 2

                temperatureVarianceAxis.annotate(
                    text,
                    xycoords=('axes pixels'),
                    xy=(maxTemperatureOfDay["xpixel"],
                        maxTemperatureOfDay["ypixel"] + 8),
                    ha="center",
                    va="bottom",
                    color=colors["temperature-label"],
                    weight='bold',
                    path_effects=[
                        path_effects.withStroke(linewidth=self.textShadowWidth,
                                                foreground="w")
                    ])

                # Min Temperature Labels
                text = str(int(round(minTemperatureOfDay["data"], 0))) + "°C"
                f = plt.figure(
                    1
                )  # Temporary figure to get the dimensions of the text label
                t = plt.text(0, 0, text, weight='bold')
                temporaryLabel = t.get_window_extent(
                    renderer=f.canvas.get_renderer())
                plt.figure(0)  # Select Main figure again

                # Check if text is fully within the day (x axis)
                if minTemperatureOfDay[
                        "xpixel"] - temporaryLabel.width / 2 < dayXPixelMin:  # To far left
                    minTemperatureOfDay[
                        "xpixel"] = dayXPixelMin + temporaryLabel.width / 2 + self.textShadowWidth / 2
                if minTemperatureOfDay[
                        "xpixel"] + temporaryLabel.width / 2 > dayXPixelMax:  # To far right
                    minTemperatureOfDay[
                        "xpixel"] = dayXPixelMax - temporaryLabel.width / 2 - self.textShadowWidth / 2

                temperatureVarianceAxis.annotate(
                    text,
                    xycoords=('axes pixels'),
                    xy=(minTemperatureOfDay["xpixel"],
                        minTemperatureOfDay["ypixel"] - 12),
                    ha="center",
                    va="top",
                    color=colors["temperature-label"],
                    weight='bold',
                    path_effects=[
                        path_effects.withStroke(linewidth=self.textShadowWidth,
                                                foreground="w")
                    ])

        # Print day names
        for day in range(0, data["noOfDays"]):
            rainAxis.annotate(data['dayNames'][day],
                              xy=(day * xPixelsPerDay + xPixelsPerDay / 2,
                                  -45),
                              xycoords='axes pixels',
                              ha="center",
                              weight='bold',
                              color=colors["x-axis"])

        # Show y-axis units
        rainAxis.annotate("mm\n/h",
                          linespacing=0.8,
                          xy=(width + 25, height + 12),
                          xycoords='axes pixels',
                          ha="center",
                          color=colors["rain-axis"])
        rainAxis.annotate("°C",
                          xy=(-20, height + 10),
                          xycoords='axes pixels',
                          ha="center",
                          color=colors["temperature-axis"])

        # Show Symbols above the graph
        for i in range(0, len(data["symbols"]), symbolDivision):
            symbolFile = os.path.dirname(
                os.path.realpath(__file__)) + "/symbols/" + str(
                    data["symbols"][i]) + ".png"
            if not os.path.isfile(symbolFile):
                logging.warning(
                    "The symbol file %s seems to be missing. Please check the README.md!"
                    % symbolFile)
                continue
            symbolImage = mpimg.imread(symbolFile)
            imagebox = OffsetImage(symbolImage, zoom=symbolZoom / 1.41 * 0.15)
            xyPos = (
                (data["symbolsTimestamps"][i] - data["symbolsTimestamps"][0]) /
                (24 * 3600) + len(data["symbols"]) / 24 / 6 /
                data["noOfDays"]) * xPixelsPerDay, height + 22
            ab = AnnotationBbox(imagebox,
                                xy=xyPos,
                                xycoords='axes pixels',
                                frameon=False)
            rainAxis.add_artist(ab)

        # Show city name in graph
        # TODO find a way to show the label in the background
        if showCityName:
            logging.debug("Adding city name to plot...")
            text = fig.text(1 - 7 / width,
                            1 - 20 / height,
                            self.cityName,
                            color='gray',
                            ha='right',
                            transform=rainAxis.transAxes)
            text.set_path_effects([
                path_effects.Stroke(linewidth=self.textShadowWidth,
                                    foreground='white'),
                path_effects.Normal()
            ])

        # Save the graph in a png image file
        logging.debug("Saving graph to %s" % outputFilename)
        plt.savefig(outputFilename, facecolor=colors["background"])
        plt.close()

        # Write Meta Data
        if writeMetaData:
            logging.debug("Saving Meta Data to %s" % writeMetaData)
            metaData = {}
            metaData['city'] = self.cityName
            metaData['imageHeight'] = graphHeight
            metaData['imageWidth'] = graphWidth
            metaData['firstDayX'] = firstDayX
            metaData['firstDayY'] = firstDayY
            metaData['dayWidth'] = dayWidth
            metaData['dayHeight'] = dayHeight
            metaData['modelTimestamp'] = self.data[
                "modelCalculationTimestamp"]  # Seconds in UTC
            with open(writeMetaData, 'w') as metaFile:
                json.dump(metaData, metaFile)
Exemplo n.º 20
0
def modelMap(grids, shakefile=None, suptitle=None, inventory_shapefile=None,
             plotorder=None, maskthreshes=None, colormaps=None, boundaries=None,
             zthresh=0, scaletype='continuous', lims=None, logscale=False,
             ALPHA=0.7, maproads=True, mapcities=True, isScenario=False,
             roadfolder=None, topofile=None, cityfile=None, oceanfile=None,
             roadcolor='#6E6E6E', watercolor='#B8EEFF', countrycolor='#177F10',
             outputdir=None, savepdf=True, savepng=True, showplots=False,
             roadref='unknown', cityref='unknown', oceanref='unknown',
             printparam=False, ds=True, dstype='mean', upsample=False):
    """
    This function creates maps of mapio grid layers (e.g. liquefaction or
    landslide models with their input layers)
    All grids must use the same bounds
    TO DO change so that all input layers do not have to have the same bounds,
    test plotting multiple probability layers, and add option so that if PDF and
    PNG aren't output, opens plot on screen using plt.show()

    :param grids: Dictionary of N layers and metadata formatted like:
        maplayers['layer name']={
        'grid': mapio grid2D object,
        'label': 'label for colorbar and top line of subtitle',
        'type': 'output or input to model',
        'description': 'detailed description of layer for subtitle'}.
      Layer names must be unique.
    :type name: Dictionary or Ordered dictionary - import collections;
      grids = collections.OrderedDict()
    :param shakefile: optional ShakeMap file (url or full file path) to extract information for labels and folder names
    :type shakefile: Shakemap Event Dictionary
    :param suptitle: This will be displayed at the top of the plots and in the
      figure names
    :type suptitle: string
    :param plotorder: List of keys describing the order to plot the grids, if
      None and grids is an ordered dictionary, it will use the order of the
      dictionary, otherwise it will choose order which may be somewhat random
      but it will always put a probability grid first
    :type plotorder: list
    :param maskthreshes: N x 1 array or list of lower thresholds for masking
      corresponding to order in plotorder or order of OrderedDict if plotorder
      is None. If grids is not an ordered dict and plotorder is not specified,
      this will not work right. If None (default), nothing will be masked
    :param colormaps: List of strings of matplotlib colormaps (e.g. cm.autumn_r)
      corresponding to plotorder or order of dictionary if plotorder is None.
      The list can contain both strings and None e.g. colormaps = ['cm.autumn',
      None, None, 'cm.jet'] and None's will default to default colormap
    :param boundaries: None to show entire study area, 'zoom' to zoom in on the
      area of action (only works if there is a probability layer) using zthresh
      as a threshold, or a dictionary defining lats and lons in the form of
      boundaries.xmin = minlon, boundaries.xmax = maxlon, boundaries.ymin =
      min lat, boundaries.ymax = max lat
    :param zthresh: threshold for computing zooming bounds, only used if
      boundaries = 'zoom'
    :type zthresh: float
    :param scaletype: Type of scale for plotting, 'continuous' or 'binned' -
      will be reflected in colorbar
    :type scaletype: string
    :param lims: None or Nx1 list of tuples or numpy arrays corresponding to
      plotorder defining the limits for saturating the colorbar (vmin, vmax) if
      scaletype is continuous or the bins to use (clev) if scaletype if binned.
      The list can contain tuples, arrays, and Nones, e.g. lims = [(0., 10.),
      None, (0.1, 1.5), np.linspace(0., 1.5, 15)]. When None is specified, the
      program will estimate the limits, when an array is specified but the scale
      type is continuous, vmin will be set to min(array) and vmax will be set
      to max(array)
    :param lims: None or Nx1 list of Trues and Falses corresponding to
      plotorder defining whether to use a linear or log scale (log10) for
      plotting the layer. This will be reflected in the labels
    :param ALPHA: Transparency for mapping, if there is a hillshade that will
      plot below each layer, it is recommended to set this to at least 0.7
    :type ALPHA: float
    :param maproads: Whether to show roads or not, default True, but requires
      that roadfile is specified and valid to work
    :type maproads: boolean
    :param mapcities: Whether to show cities or not, default True, but requires
      that cityfile is specified and valid to work
    :type mapcities: boolean
    :param isScenario: Whether this is a scenario (True) or a real event (False)
      (default False)
    :type isScenario: boolean
    :param roadfolder: Full file path to folder containing road shapefiles
    :type roadfolder: string
    :param topofile: Full file path to topography grid (GDAL compatible) - this
      is only needed to make a hillshade if a premade hillshade is not specified
    :type topofile: string
    :param cityfile: Full file path to Pager file containing city & population
      information
    :type cityfile: string
    :param roadcolor: Color to use for roads, if plotted, default #6E6E6E
    :type roadcolor: Hex color or other matplotlib compatible way of defining
      color
    :param watercolor: Color to use for oceans, lakes, and rivers, default
      #B8EEFF
    :type watercolor: Hex color or other matplotlib compatible way of defining
      color
    :param countrycolor: Color for country borders, default #177F10
    :type countrycolor: Hex color or other matplotlib compatible way of defining
      color
    :param outputdir: File path for outputting figures, if edict is defined, a
      subfolder based on the event id will be created in this folder. If None,
      will use current directory
    :param savepdf: True to save pdf figure, False to not
    :param savepng: True to save png figure, False to not
    :param ds: True to allow downsampling for display (necessary when arrays
      are quite large, False to not allow)
    :param dstype: What function to use in downsampling, options are 'min',
      'max', 'median', or 'mean'
    :param upsample: True to upsample the layer to the DEM resolution for better
      looking hillshades

    :returns:
        * PDF and/or PNG of map
        * Downsampled and trimmed version of input grids. If no
        modification was needed for plotting, this will be identical to grids but
        without the metadata

    """

    if suptitle is None:
        suptitle = ' '

    plt.ioff()

    defaultcolormap = cm.jet

    if shakefile is not None:
        edict = ShakeGrid.load(shakefile, adjust='res').getEventDict()
        temp = ShakeGrid.load(shakefile, adjust='res').getShakeDict()
        edict['eventid'] = temp['shakemap_id']
        edict['version'] = temp['shakemap_version']
    else:
        edict = None

    # Get output file location
    if outputdir is None:
        print('No output location given, using current directory for outputs\n')
        outputdir = os.getcwd()
    if edict is not None:
        outfolder = os.path.join(outputdir, edict['event_id'])
    else:
        outfolder = outputdir
    if not os.path.isdir(outfolder):
        os.makedirs(outfolder)

    # Get plotting order, if not specified
    if plotorder is None:
        plotorder = list(grids.keys())

    # Get boundaries to use for all plots
    cut = True
    if boundaries is None:
        cut = False
        keytemp = list(grids.keys())
        boundaries = grids[keytemp[0]]['grid'].getGeoDict()
    elif boundaries == 'zoom':
        # Find probability layer (will just take the maximum bounds if there is
        # more than one)
        keytemp = list(grids.keys())
        key1 = [key for key in keytemp if 'model' in key.lower()]
        if len(key1) == 0:
            print('Could not find model layer to use for zoom, using default boundaries')
            keytemp = list(grids.keys())
            boundaries = grids[keytemp[0]]['grid'].getGeoDict()
        else:
            lonmax = -1.e10
            lonmin = 1.e10
            latmax = -1.e10
            latmin = 1.e10
            for key in key1:
                # get lat lons of areas affected and add, if no areas affected,
                # switch to shakemap boundaries
                temp = grids[key]['grid']
                xmin, xmax, ymin, ymax = temp.getBounds()
                lons = np.linspace(xmin, xmax, temp.getGeoDict().nx)
                lats = np.linspace(ymax, ymin, temp.getGeoDict().ny)  # backwards so it plots right
                row, col = np.where(temp.getData() > float(zthresh))
                lonmin = lons[col].min()
                lonmax = lons[col].max()
                latmin = lats[row].min()
                latmax = lats[row].max()
                # llons, llats = np.meshgrid(lons, lats)  # make meshgrid
                # llons1 = llons[temp.getData() > float(zthresh)]
                # llats1 = llats[temp.getData() > float(zthresh)]
                # if llons1.min() < lonmin:
                #     lonmin = llons1.min()
                # if llons1.max() > lonmax:
                #     lonmax = llons1.max()
                # if llats1.min() < latmin:
                #     latmin = llats1.min()
                # if llats1.max() > latmax:
                #     latmax = llats1.max()
            boundaries1 = {'dx': 100, 'dy': 100., 'nx': 100., 'ny': 100}  # dummy fillers, only really care about bounds
            if xmin < lonmin-0.15*(lonmax-lonmin):
                boundaries1['xmin'] = lonmin-0.1*(lonmax-lonmin)
            else:
                boundaries1['xmin'] = xmin
            if xmax > lonmax+0.15*(lonmax-lonmin):
                boundaries1['xmax'] = lonmax+0.1*(lonmax-lonmin)
            else:
                boundaries1['xmax'] = xmax
            if ymin < latmin-0.15*(latmax-latmin):
                boundaries1['ymin'] = latmin-0.1*(latmax-latmin)
            else:
                boundaries1['ymin'] = ymin
            if ymax > latmax+0.15*(latmax-latmin):
                boundaries1['ymax'] = latmax+0.1*(latmax-latmin)
            else:
                boundaries1['ymax'] = ymax
            boundaries = GeoDict(boundaries1, adjust='res')
    else:
        # SEE IF BOUNDARIES ARE SAME AS BOUNDARIES OF LAYERS
        keytemp = list(grids.keys())
        tempgdict = grids[keytemp[0]]['grid'].getGeoDict()
        if np.abs(tempgdict.xmin-boundaries['xmin']) < 0.05 and \
           np.abs(tempgdict.ymin-boundaries['ymin']) < 0.05 and \
           np.abs(tempgdict.xmax-boundaries['xmax']) < 0.05 and \
           np.abs(tempgdict.ymax - boundaries['ymax']) < 0.05:
            print('Input boundaries are almost the same as specified boundaries, no cutting needed')
            boundaries = tempgdict
            cut = False
        else:
            try:
                if boundaries['xmin'] > boundaries['xmax'] or \
                   boundaries['ymin'] > boundaries['ymax']:
                    print('Input boundaries are not usable, using default boundaries')
                    keytemp = list(grids.keys())
                    boundaries = grids[keytemp[0]]['grid'].getGeoDict()
                    cut = False
                else:
                    # Build dummy GeoDict
                    boundaries = GeoDict({'xmin': boundaries['xmin'],
                                          'xmax': boundaries['xmax'],
                                          'ymin': boundaries['ymin'],
                                          'ymax': boundaries['ymax'],
                                          'dx': 100.,
                                          'dy': 100.,
                                          'ny': 100.,
                                          'nx': 100.},
                                         adjust='res')
            except:
                print('Input boundaries are not usable, using default boundaries')
                keytemp = list(grids.keys())
                boundaries = grids[keytemp[0]]['grid'].getGeoDict()
                cut = False

    # Pull out bounds for various uses
    bxmin, bxmax, bymin, bymax = boundaries.xmin, boundaries.xmax, boundaries.ymin, boundaries.ymax

    # Determine if need a single panel or multi-panel plot and if multi-panel,
    # how many and how it will be arranged
    fig = plt.figure()
    numpanels = len(grids)
    if numpanels == 1:
        rowpan = 1
        colpan = 1
        # create the figure and axes instances.
        fig.set_figwidth(5)
    elif numpanels == 2 or numpanels == 4:
        rowpan = np.ceil(numpanels/2.)
        colpan = 2
        fig.set_figwidth(13)
    else:
        rowpan = np.ceil(numpanels/3.)
        colpan = 3
        fig.set_figwidth(15)
    if rowpan == 1:
        fig.set_figheight(rowpan*6.0)
    else:
        fig.set_figheight(rowpan*5.3)

    # Need to update naming to reflect the shakemap version once can get
    # getHeaderData to work, add edict['version'] back into title, maybe
    # shakemap id also?
    fontsizemain = 14.
    fontsizesub = 12.
    fontsizesmallest = 10.
    if rowpan == 1.:
        fontsizemain = 12.
        fontsizesub = 10.
        fontsizesmallest = 8.
    if edict is not None:
        if isScenario:
            title = edict['event_description']
        else:
            timestr = edict['event_timestamp'].strftime('%b %d %Y')
            title = 'M%.1f %s v%i - %s' % (edict['magnitude'], timestr, edict['version'], edict['event_description'])
        plt.suptitle(title+'\n'+suptitle, fontsize=fontsizemain)
    else:
        plt.suptitle(suptitle, fontsize=fontsizemain)

    clear_color = [0, 0, 0, 0.0]

    # Cut all of them and release extra memory

    xbuff = (bxmax-bxmin)/10.
    ybuff = (bymax-bymin)/10.
    cutxmin = bxmin-xbuff
    cutymin = bymin-ybuff
    cutxmax = bxmax+xbuff
    cutymax = bymax+ybuff
    if cut is True:
        newgrids = collections.OrderedDict()
        for k, layer in enumerate(plotorder):
            templayer = grids[layer]['grid']
            try:
                newgrids[layer] = {'grid': templayer.cut(cutxmin, cutxmax, cutymin, cutymax, align=True)}
            except Exception as e:
                print(('Cutting failed, %s, continuing with full layers' % e))
                newgrids = grids
                continue
        del templayer
        gc.collect()
    else:
        newgrids = grids
    tempgdict = newgrids[list(grids.keys())[0]]['grid'].getGeoDict()

    # Upsample layers to same as topofile if desired for better looking hillshades
    if upsample is True and topofile is not None:
        try:
            topodict = GDALGrid.getFileGeoDict(topofile)
            if topodict.dx >= tempgdict.dx or topodict.dy >= tempgdict.dy:
                print('Upsampling not possible, resolution of results already smaller than DEM')
                pass
            else:
                tempgdict1 = GeoDict({'xmin': tempgdict.xmin-xbuff,
                                      'ymin': tempgdict.ymin-ybuff,
                                      'xmax': tempgdict.xmax+xbuff,
                                      'ymax': tempgdict.ymax+ybuff,
                                      'dx': topodict.dx,
                                      'dy': topodict.dy,
                                      'nx': topodict.nx,
                                      'ny': topodict.ny},
                                     adjust='res')
                tempgdict2 = tempgdict1.getBoundsWithin(tempgdict)
                for k, layer in enumerate(plotorder):
                    newgrids[layer]['grid'] = newgrids[layer]['grid'].subdivide(tempgdict2)
        except:
            print('Upsampling failed, continuing')

    # Downsample all of them for plotting, if needed, and replace them in
    # grids (to save memory)
    tempgrid = newgrids[list(grids.keys())[0]]['grid']
    xsize = tempgrid.getGeoDict().nx
    ysize = tempgrid.getGeoDict().ny
    inchesx, inchesy = fig.get_size_inches()
    divx = int(np.round(xsize/(500.*inchesx)))
    divy = int(np.round(ysize/(500.*inchesy)))
    xmin, xmax, ymin, ymax = tempgrid.getBounds()
    gdict = tempgrid.getGeoDict()  # Will be replaced if downsampled
    del tempgrid
    gc.collect()

    if divx <= 1:
        divx = 1
    if divy <= 1:
        divy = 1
    if (divx > 1. or divy > 1.) and ds:
        if dstype == 'max':
            func = np.nanmax
        elif dstype == 'min':
            func = np.nanmin
        elif dstype == 'med':
            func = np.nanmedian
        else:
            func = np.nanmean
        for k, layer in enumerate(plotorder):
            layergrid = newgrids[layer]['grid']
            dat = block_reduce(layergrid.getData().copy(),
                               block_size=(divy, divx),
                               cval=float('nan'),
                               func=func)
            if k == 0:
                lons = block_reduce(np.linspace(xmin, xmax, layergrid.getGeoDict().nx),
                                    block_size=(divx,),
                                    func=np.mean,
                                    cval=float('nan'))
                if math.isnan(lons[-1]):
                    lons[-1] = lons[-2] + (lons[1]-lons[0])
                lats = block_reduce(np.linspace(ymax, ymin, layergrid.getGeoDict().ny),
                                    block_size=(divy,),
                                    func=np.mean,
                                    cval=float('nan'))
                if math.isnan(lats[-1]):
                    lats[-1] = lats[-2] + (lats[1]-lats[0])
                gdict = GeoDict({'xmin': lons.min(),
                                 'xmax': lons.max(),
                                 'ymin': lats.min(),
                                 'ymax': lats.max(),
                                 'dx': np.abs(lons[1]-lons[0]),
                                 'dy': np.abs(lats[1]-lats[0]),
                                 'nx': len(lons),
                                 'ny': len(lats)},
                                adjust='res')
            newgrids[layer]['grid'] = Grid2D(dat, gdict)
        del layergrid, dat
    else:
        lons = np.linspace(xmin, xmax, xsize)
        lats = np.linspace(ymax, ymin, ysize)  # backwards so it plots right side up

    #make meshgrid
    llons1, llats1 = np.meshgrid(lons, lats)

    # See if there is an oceanfile for masking
    bbox = PolygonSH(((cutxmin, cutymin), (cutxmin, cutymax), (cutxmax, cutymax), (cutxmax, cutymin)))
    if oceanfile is not None:
        try:
            f = fiona.open(oceanfile)
            oc = next(f)
            f.close
            shapes = shape(oc['geometry'])
            # make boundaries into a shape
            ocean = shapes.intersection(bbox)
        except:
            print('Not able to read specified ocean file, will use default ocean masking')
            oceanfile = None
    if inventory_shapefile is not None:
        try:
            f = fiona.open(inventory_shapefile)
            invshp = list(f.items(bbox=(bxmin, bymin, bxmax, bymax)))
            f.close()
            inventory = [shape(inv[1]['geometry']) for inv in invshp]
        except:
            print('unable to read inventory shapefile specified, will not plot inventory')
            inventory_shapefile = None

    # # Find cities that will be plotted
    if mapcities is True and cityfile is not None:
        try:
            mycity = BasemapCities.loadFromGeoNames(cityfile=cityfile)
            bcities = mycity.limitByBounds((bxmin, bxmax, bymin, bymax))
            #bcities = bcities.limitByPopulation(40000)
            bcities = bcities.limitByGrid(nx=4, ny=4, cities_per_grid=2)
        except:
            print('Could not read in cityfile, not plotting cities')
            mapcities = False
            cityfile = None

    # Load in topofile
    if topofile is not None:
        try:
            topomap = GDALGrid.load(topofile, resample=True, method='linear', samplegeodict=gdict)
        except:
            topomap = GMTGrid.load(topofile, resample=True, method='linear', samplegeodict=gdict)
        topodata = topomap.getData().copy()
        # mask oceans if don't have ocean shapefile
        if oceanfile is None:
            topodata = maskoceans(llons1, llats1, topodata, resolution='h', grid=1.25, inlands=True)
    else:
        print('no hillshade is possible\n')
        topomap = None
        topodata = None

    # Load in roads, if needed
    if maproads is True and roadfolder is not None:
        try:
            roadslist = []
            for folder in os.listdir(roadfolder):
                road1 = os.path.join(roadfolder, folder)
                shpfiles = glob.glob(os.path.join(road1, '*.shp'))
                if len(shpfiles):
                    shpfile = shpfiles[0]
                    f = fiona.open(shpfile)
                    shapes = list(f.items(bbox=(bxmin, bymin, bxmax, bymax)))
                    for shapeid, shapedict in shapes:
                        roadslist.append(shapedict)
                    f.close()
        except:
            print('Not able to plot roads')
            roadslist = None

    val = 1
    for k, layer in enumerate(plotorder):
        layergrid = newgrids[layer]['grid']
        if 'label' in list(grids[layer].keys()):
            label1 = grids[layer]['label']
        else:
            label1 = layer
        try:
            sref = grids[layer]['description']['name']
        except:
            sref = None
        ax = fig.add_subplot(rowpan, colpan, val)
        val += 1
        clat = bymin + (bymax-bymin)/2.0
        clon = bxmin + (bxmax-bxmin)/2.0
        # setup of basemap ('lcc' = lambert conformal conic).
        # use major and minor sphere radii from WGS84 ellipsoid.
        m = Basemap(llcrnrlon=bxmin, llcrnrlat=bymin, urcrnrlon=bxmax, urcrnrlat=bymax,
                    rsphere=(6378137.00, 6356752.3142),
                    resolution='l', area_thresh=1000., projection='lcc',
                    lat_1=clat, lon_0=clon, ax=ax)

        x1, y1 = m(llons1, llats1)  # get projection coordinates
        axsize = ax.get_window_extent().transformed(fig.dpi_scale_trans.inverted())
        if k == 0:
            wid, ht = axsize.width, axsize.height
        if colormaps is not None and \
           len(colormaps) == len(newgrids) and \
           colormaps[k] is not None:
            palette = colormaps[k]
        else:  # Find preferred default color map for each type of layer
            if 'prob' in layer.lower() or 'pga' in layer.lower() or \
               'pgv' in layer.lower() or 'cohesion' in layer.lower() or \
               'friction' in layer.lower() or 'fs' in layer.lower():
                palette = cm.jet
            elif 'slope' in layer.lower():
                palette = cm.gnuplot2
            elif 'precip' in layer.lower():
                palette = cm2.s3pcpn
            else:
                palette = defaultcolormap

        if topodata is not None:
            if k == 0:
                ptopo = m.transform_scalar(
                    np.flipud(topodata), lons+0.5*gdict.dx,
                    lats[::-1]-0.5*gdict.dy, np.round(300.*wid),
                    np.round(300.*ht), returnxy=False, checkbounds=False,
                    order=1, masked=False)
                #use lightsource class to make our shaded topography
                ls = LightSource(azdeg=135, altdeg=45)
                ls1 = LightSource(azdeg=120, altdeg=45)
                ls2 = LightSource(azdeg=225, altdeg=45)
                intensity1 = ls1.hillshade(ptopo, fraction=0.25, vert_exag=1.)
                intensity2 = ls2.hillshade(ptopo, fraction=0.25, vert_exag=1.)
                intensity = intensity1*0.5 + intensity2*0.5
                #hillshm_im = m.transform_scalar(np.flipud(hillshm), lons, lats[::-1], np.round(300.*wid), np.round(300.*ht), returnxy=False, checkbounds=False, order=0, masked=False)
            #m.imshow(hillshm_im, cmap='Greys', vmin=0., vmax=3., zorder=1, interpolation='none')  # vmax = 3 to soften colors to light gray
            #m.pcolormesh(x1, y1, hillshm, cmap='Greys', linewidth=0., rasterized=True, vmin=0., vmax=3., edgecolors='none', zorder=1);
            # plt.draw()

        # Get the data
        dat = layergrid.getData().copy()

        # mask out anything below any specified thresholds
        # Might need to move this up to before downsampling...might give illusion of no hazard in places where there is some that just got averaged out
        if maskthreshes is not None and len(maskthreshes) == len(newgrids):
            if maskthreshes[k] is not None:
                dat[dat <= maskthreshes[k]] = float('NaN')
                dat = np.ma.array(dat, mask=np.isnan(dat))

        if logscale is not False and len(logscale) == len(newgrids):
            if logscale[k] is True:
                dat = np.log10(dat)
                label1 = r'$log_{10}$(' + label1 + ')'

        if scaletype.lower() == 'binned':
            # Find order of range to know how to scale
            order = np.round(np.log(np.nanmax(dat) - np.nanmin(dat)))
            if order < 1.:
                scal = 10**-order
            else:
                scal = 1.
            if lims is None or len(lims) != len(newgrids):
                clev = (np.linspace(np.floor(scal*np.nanmin(dat)), np.ceil(scal*np.nanmax(dat)), 10))/scal
            else:
                if lims[k] is None:
                    clev = (np.linspace(np.floor(scal*np.nanmin(dat)), np.ceil(scal*np.nanmax(dat)), 10))/scal
                else:
                    clev = lims[k]
            # Adjust to colorbar levels
            dat[dat < clev[0]] = clev[0]
            for j, level in enumerate(clev[:-1]):
                dat[(dat >= clev[j]) & (dat < clev[j+1])] = clev[j]
            # So colorbar saturates at top
            dat[dat > clev[-1]] = clev[-1]
            #panelhandle = m.contourf(x1, y1, datm, clev, cmap=palette, linewidth=0., alpha=ALPHA, rasterized=True)
            vmin = clev[0]
            vmax = clev[-1]
        else:
            if lims is not None and len(lims) == len(newgrids):
                if lims[k] is None:
                    vmin = np.nanmin(dat)
                    vmax = np.nanmax(dat)
                else:
                    vmin = lims[k][0]
                    vmax = lims[k][-1]
            else:
                vmin = np.nanmin(dat)
                vmax = np.nanmax(dat)

        # Mask out cells overlying oceans or block with a shapefile if available
        if oceanfile is None:
            dat = maskoceans(llons1, llats1, dat, resolution='h', grid=1.25, inlands=True)
        else:
            #patches = []
            if type(ocean) is PolygonSH:
                ocean = [ocean]
            for oc in ocean:
                patch = getProjectedPatch(oc, m, edgecolor="#006280", facecolor=watercolor, lw=0.5, zorder=4.)
                #x, y = m(oc.exterior.xy[0], oc.exterior.xy[1])
                #xy = zip(x, y)
                #patch = Polygon(xy, facecolor=watercolor, edgecolor="#006280", lw=0.5, zorder=4.)
                ##patches.append(Polygon(xy, facecolor=watercolor, edgecolor=watercolor, zorder=500.))
                ax.add_patch(patch)
            ##ax.add_collection(PatchCollection(patches))

        if inventory_shapefile is not None:
            for in1 in inventory:
                if 'point' in str(type(in1)):
                    x, y = in1.xy
                    x = x[0]
                    y = y[0]
                    m.scatter(x, y, c='m', s=50, latlon=True, marker='^',
                              zorder=100001)
                else:
                    x, y = m(in1.exterior.xy[0], in1.exterior.xy[1])
                    xy = list(zip(x, y))
                    patch = Polygon(xy, facecolor='none', edgecolor='k', lw=0.5, zorder=10.)
                    #patches.append(Polygon(xy, facecolor=watercolor, edgecolor=watercolor, zorder=500.))
                    ax.add_patch(patch)
        palette.set_bad(clear_color, alpha=0.0)
        # Plot it up
        dat_im = m.transform_scalar(
            np.flipud(dat), lons+0.5*gdict.dx, lats[::-1]-0.5*gdict.dy,
            np.round(300.*wid), np.round(300.*ht), returnxy=False,
            checkbounds=False, order=0, masked=True)
        if topodata is not None:  # Drape over hillshade
            #turn data into an RGBA image
            cmap = palette
            #adjust data so scaled between vmin and vmax and between 0 and 1
            dat1 = dat_im.copy()
            dat1[dat1 < vmin] = vmin
            dat1[dat1 > vmax] = vmax
            dat1 = (dat1 - vmin)/(vmax-vmin)
            rgba_img = cmap(dat1)
            maskvals = np.dstack((dat1.mask, dat1.mask, dat1.mask))
            rgb = np.squeeze(rgba_img[:, :, 0:3])
            rgb[maskvals] = 1.
            draped_hsv = ls.blend_hsv(rgb, np.expand_dims(intensity, 2))
            m.imshow(draped_hsv, zorder=3., interpolation='none')
            # This is just a dummy layer that will be deleted to make the
            # colorbar look right
            panelhandle = m.imshow(dat_im, cmap=palette, zorder=0.,
                                   vmin=vmin, vmax=vmax)
        else:
            panelhandle = m.imshow(dat_im, cmap=palette, zorder=3.,
                                   vmin=vmin, vmax=vmax, interpolation='none')
        #panelhandle = m.pcolormesh(x1, y1, dat, linewidth=0., cmap=palette, vmin=vmin, vmax=vmax, alpha=ALPHA, rasterized=True, zorder=2.);
        #panelhandle.set_edgecolors('face')
        # add colorbar
        cbfmt = '%1.1f'
        if vmax is not None and vmin is not None:
            if (vmax - vmin) < 1.:
                cbfmt = '%1.2f'
            elif vmax > 5.:  # (vmax - vmin) > len(clev):
                cbfmt = '%1.0f'

        #norm = mpl.colors.Normalize(vmin=vmin, vmax=vmax)
        if scaletype.lower() == 'binned':
            cbar = fig.colorbar(panelhandle, spacing='proportional',
                                ticks=clev, boundaries=clev, fraction=0.036,
                                pad=0.04, format=cbfmt, extend='both')
            #cbar1 = ColorbarBase(cbar.ax, cmap=palette, norm=norm, spacing='proportional', ticks=clev, boundaries=clev, fraction=0.036, pad=0.04, format=cbfmt, extend='both', extendfrac='auto')

        else:
            cbar = fig.colorbar(panelhandle, fraction=0.036, pad=0.04,
                                extend='both', format=cbfmt)
            #cbar1 = ColorbarBase(cbar.ax, cmap=palette, norm=norm, fraction=0.036, pad=0.04, extend='both', extendfrac='auto', format=cbfmt)

        if topodata is not None:
            panelhandle.remove()

        cbar.set_label(label1, fontsize=10)
        cbar.ax.tick_params(labelsize=8)

        parallels = m.drawparallels(getMapLines(bymin, bymax, 3),
                                    labels=[1, 0, 0, 0], linewidth=0.5,
                                    labelstyle='+/-', fontsize=9, xoffset=-0.8,
                                    color='gray', zorder=100.)
        m.drawmeridians(getMapLines(bxmin, bxmax, 3), labels=[0, 0, 0, 1],
                        linewidth=0.5, labelstyle='+/-', fontsize=9,
                        color='gray', zorder=100.)
        for par in parallels:
            try:
                parallels[par][1][0].set_rotation(90)
            except:
                pass

        #draw roads on the map, if they were provided to us
        if maproads is True and roadslist is not None:
            try:
                for road in roadslist:
                    try:
                        xy = list(road['geometry']['coordinates'])
                        roadx, roady = list(zip(*xy))
                        mapx, mapy = m(roadx, roady)
                        m.plot(mapx, mapy, roadcolor, lw=0.5, zorder=9)
                    except:
                        continue
            except Exception as e:
                print(('Failed to plot roads, %s' % e))

        #add city names to map
        if mapcities is True and cityfile is not None:
            try:
                fontname = 'Arial'
                fontsize = 8
                if k == 0:  # Only need to choose cities first time and then apply to rest
                    fcities = bcities.limitByMapCollision(
                        m, fontname=fontname, fontsize=fontsize)
                    ctlats, ctlons, names = fcities.getCities()
                    cxis, cyis = m(ctlons, ctlats)
                for ctlat, ctlon, cxi, cyi, name in zip(ctlats, ctlons, cxis, cyis, names):
                    m.scatter(ctlon, ctlat, c='k', latlon=True, marker='.',
                              zorder=100000)
                    ax.text(cxi, cyi, name, fontname=fontname,
                            fontsize=fontsize, zorder=100000)
            except Exception as e:
                print('Failed to plot cities, %s' % e)

        #draw star at epicenter
        plt.sca(ax)
        if edict is not None:
            elat, elon = edict['lat'], edict['lon']
            ex, ey = m(elon, elat)
            plt.plot(ex, ey, '*', markeredgecolor='k', mfc='None', mew=1.0,
                     ms=15, zorder=10000.)

        m.drawmapboundary(fill_color=watercolor)

        m.fillcontinents(color=clear_color, lake_color=watercolor)
        m.drawrivers(color=watercolor)
        ##m.drawcoastlines()

        #draw country boundaries
        m.drawcountries(color=countrycolor, linewidth=1.0)

        #add map scale
        m.drawmapscale((bxmax+bxmin)/2., (bymin+(bymax-bymin)/9.), clon, clat, np.round((((bxmax-bxmin)*111)/5)/10.)*10, barstyle='fancy', zorder=10)

        # Add border
        autoAxis = ax.axis()
        rec = Rectangle((autoAxis[0]-0.7, autoAxis[2]-0.2), (autoAxis[1]-autoAxis[0])+1, (autoAxis[3]-autoAxis[2])+0.4, fill=False, lw=1, zorder=1e8)
        rec = ax.add_patch(rec)
        rec.set_clip_on(False)

        plt.draw()

        if sref is not None:
            label2 = '%s\nsource: %s' % (label1, sref)  # '%s\n' % label1 + r'{\fontsize{10pt}{3em}\selectfont{}%s}' % sref  #
        else:
            label2 = label1
        plt.title(label2, axes=ax, fontsize=fontsizesub)

        #draw scenario watermark, if scenario
        if isScenario:
            plt.sca(ax)
            cx, cy = m(clon, clat)
            plt.text(cx, cy, 'SCENARIO', rotation=45, alpha=0.10, size=72, ha='center', va='center', color='red')

        #if ds: # Could add this to print "downsampled" on map
        #    plt.text()

        if k == 1 and rowpan == 1:
            # adjust single level plot
            axsize = ax.get_window_extent().transformed(fig.dpi_scale_trans.inverted())
            ht2 = axsize.height
            fig.set_figheight(ht2*1.6)
        else:
            plt.tight_layout()

        # Make room for suptitle - tight layout doesn't account for it
        plt.subplots_adjust(top=0.92)

    if printparam is True:
        try:
            fig = plt.gcf()
            dictionary = grids['model']['description']['parameters']
            paramstring = 'Model parameters: '
            halfway = np.ceil(len(dictionary)/2.)
            for i, key in enumerate(dictionary):
                if i == halfway and colpan == 1:
                    paramstring += '\n'
                paramstring += ('%s = %s; ' % (key, dictionary[key]))
            print(paramstring)
            fig.text(0.01, 0.015, paramstring, fontsize=fontsizesmallest)
            plt.draw()
        except:
            print('Could not display model parameters')

    if edict is not None:
        eventid = edict['eventid']
    else:
        eventid = ''

    time1 = datetime.datetime.utcnow().strftime('%d%b%Y_%H%M')
    outfile = os.path.join(outfolder, '%s_%s_%s.pdf' % (eventid, suptitle, time1))
    pngfile = os.path.join(outfolder, '%s_%s_%s.png' % (eventid, suptitle, time1))

    if savepdf is True:
        print('Saving map output to %s' % outfile)
        plt.savefig(outfile, dpi=300)
    if savepng is True:
        print('Saving map output to %s' % pngfile)
        plt.savefig(pngfile)
    if showplots is True:
        plt.show()
    else:
        plt.close(fig)

    return newgrids
Exemplo n.º 21
0
    def highlight_artist(self, val, artist=None):
        from ifigure.matplotlib_mod.art3d_gl import Poly3DCollectionGL
        from ifigure.matplotlib_mod.art3d_gl import Line3DCollectionGL        
        figure=self.get_figpage()._artists[0]
        ax = self.get_figaxes()
        if artist is None:
           alist=self._artists
        else:
           alist=artist 

        if val == True:
           if self._parent is None: return
           container = self.get_container()
           if container is None: return

           if isinstance(alist[0], Poly3DCollectionGL):
               hl = alist[0].add_hl_mask()               
               for item in hl:
                   alist[0].figobj_hl.append(item)
           else:          
               de = self.get_data_extent()
               x=(de[0], de[1],de[1],de[0],de[0])
               y=(de[2], de[2],de[3],de[3],de[2])

               facecolor='k'
               if isinstance(alist[0], Poly3DCollectionGL):
                   hl = alist[0].make_hl_artist(container)
                   facecolor = 'none'
                   self._hit_path = None               
               elif isinstance(alist[0], Line3DCollectionGL):
                   hl = alist[0].make_hl_artist(container)
                   facecolor = 'none'
                   self._hit_path = None
               else:
                   hl= container.plot(x, y, marker='s', 
                                     color='k', linestyle='None',
                                     markerfacecolor='None',
                                     markeredgewidth =  0.5,                                  
                                     scalex=False, scaley=False)
               for item in hl:
                  alist[0].figobj_hl.append(item)


               if self._hit_path is not None:
                  v = self._hit_path.vertices
                  hl= container.plot(v[:,0], v[:,1], marker='s', 
                                     color='k', linestyle='None',
                                     markerfacecolor='None',
                                     markeredgewidth =  0.5,  
                                     scalex=False, scaley=False)
                  for item in hl:
                     alist[0].figobj_hl.append(item)

               hlp = Rectangle((de[0],de[2]),
                                de[1]-de[0],
                                de[3]-de[2],
                                alpha=0.3, facecolor=facecolor,
                                figure = figure, 
                                transform= container.transData)
               if ax is not None:
                  x0, y0 = ax._artists[0].transAxes.transform((0,0))
                  x1, y1 = ax._artists[0].transAxes.transform((1,1))
                  bbox = Bbox([[x0,y0],[x1,y1]])
                  hlp.set_clip_box(bbox)
                  hlp.set_clip_on(True)
               figure.patches.append(hlp)
               alist[0].figobj_hl.append(hlp)
        else:
           for a in alist:
              if len(a.figobj_hl) == 0: continue
              for hl in a.figobj_hl[:-1]:
                 hl.remove()
              if isinstance(alist[0], Poly3DCollectionGL):
                 a.figobj_hl[-1].remove()
              else:
                  figure.patches.remove(a.figobj_hl[-1])
              a.figobj_hl=[]
Exemplo n.º 22
0
def plot_beast_ifit(filters, waves, stats, pdf1d_hdu):

    # setup the plot grid
    gs = gridspec.GridSpec(4,
                           4,
                           height_ratios=[1.0, 1.0, 1.0, 1.0],
                           width_ratios=[1.0, 1.0, 1.0, 1.0])
    ax = []
    # plots for the 1D PDFs
    for j in range(2):
        for i in range(4):
            ax.append(plt.subplot(gs[j + 2, i]))
    # now for the big SED plot
    ax.append(plt.subplot(gs[0:2, 0:3]))

    # plot the SED
    #print(np.sort(stats.colnames))

    n_filters = len(filters)

    # get the observations
    waves *= 1e-4
    obs_flux = np.empty((n_filters), dtype=np.float)
    mod_flux = np.empty((n_filters, 3), dtype=np.float)
    mod_flux_nd = np.empty((n_filters, 3), dtype=np.float)
    mod_flux_wbias = np.empty((n_filters, 3), dtype=np.float)
    k = starnum

    c = ap_SkyCoord(ra=stats['RA'][k] * ap_units.degree,
                    dec=stats['DEC'][k] * ap_units.degree,
                    frame='icrs')
    corname = ('PHAT J' + c.ra.to_string(unit=ap_units.hourangle,
                                         sep="",
                                         precision=2,
                                         alwayssign=False,
                                         pad=True) +
               c.dec.to_string(sep="", precision=2, alwayssign=True, pad=True))

    for i, cfilter in enumerate(filters):
        obs_flux[i] = stats[cfilter][k]
        mod_flux[i, 0] = np.power(10.0, stats['log' + cfilter + '_wd_p50'][k])
        mod_flux[i, 1] = np.power(10.0, stats['log' + cfilter + '_wd_p16'][k])
        mod_flux[i, 2] = np.power(10.0, stats['log' + cfilter + '_wd_p84'][k])
        mod_flux_nd[i, 0] = np.power(10.0,
                                     stats['log' + cfilter + '_nd_p50'][k])
        mod_flux_nd[i, 1] = np.power(10.0,
                                     stats['log' + cfilter + '_nd_p16'][k])
        mod_flux_nd[i, 2] = np.power(10.0,
                                     stats['log' + cfilter + '_nd_p84'][k])
        if 'log' + cfilter + '_wd_bias_p50' in stats.colnames:
            mod_flux_wbias[i, 0] = np.power(
                10.0, stats['log' + cfilter + '_wd_bias_p50'][k])
            mod_flux_wbias[i, 1] = np.power(
                10.0, stats['log' + cfilter + '_wd_bias_p16'][k])
            mod_flux_wbias[i, 2] = np.power(
                10.0, stats['log' + cfilter + '_wd_bias_p84'][k])

    ax[8].plot(waves, obs_flux, 'ko', label='observed')

    if 'log' + filters[0] + '_wd_bias_p50' in stats.colnames:
        ax[8].plot(waves,
                   mod_flux_wbias[:, 0],
                   'b-',
                   label='stellar+dust+bias')
        ax[8].fill_between(waves,
                           mod_flux_wbias[:, 1],
                           mod_flux_wbias[:, 2],
                           color='b',
                           alpha=0.3)

    ax[8].plot(waves, mod_flux[:, 0], 'r-', label='stellar+dust')
    ax[8].fill_between(waves,
                       mod_flux[:, 1],
                       mod_flux[:, 2],
                       color='r',
                       alpha=0.2)

    ax[8].plot(waves, mod_flux_nd[:, 0], 'y-', label='stellar only')
    ax[8].fill_between(waves,
                       mod_flux_nd[:, 1],
                       mod_flux_nd[:, 2],
                       color='y',
                       alpha=0.1)

    ax[8].legend(loc='upper right', bbox_to_anchor=(1.25, 1.025))

    ax[8].set_ylabel(r'Flux [ergs s$^{-1}$ cm$^{-2}$ $\AA^{-1}$]')
    ax[8].set_yscale('log')

    ax[8].set_xscale('log')
    ax[8].text(0.5,
               -0.01,
               r'$\lambda$ [$\AA$]',
               transform=ax[8].transAxes,
               va='top')
    ax[8].set_xlim(0.2, 2.0)
    ax[8].set_xticks([0.2, 0.3, 0.4, 0.5, 0.8, 0.9, 1.0, 2.0])
    ax[8].get_xaxis().set_major_formatter(matplotlib.ticker.ScalarFormatter())

    ax[8].text(0.05,
               0.95,
               corname,
               transform=ax[8].transAxes,
               va='top',
               ha='left')

    # add the text results
    keys = ['Av', 'M_ini', 'logA', 'Rv', 'f_A', 'Z', 'logT', 'logg', 'logL']
    dispnames = [
        'A(V)', 'log(M)', 'log(t)', 'R(V)', r'f$_\mathcal{A}$', 'Z',
        r'log(T$_\mathrm{eff})$', 'log(g)', 'log(L)'
    ]
    laby = 0.72
    ty = np.linspace(laby - 0.07, 0.1, num=len(keys))
    ty[3:] -= 0.025
    ty[6:] -= 0.025
    tx = [1.12, 1.2, 1.3]
    for i in range(len(keys)):
        ax[8].text(tx[0],
                   ty[i],
                   dispnames[i],
                   ha='right',
                   transform=ax[8].transAxes)
        ax[8].text(tx[1],
                   ty[i],
                   disp_str(stats, starnum, keys[i]),
                   ha='center',
                   color='m',
                   transform=ax[8].transAxes)
        best_val = stats[keys[i] + '_Best'][k]
        if keys[i] == 'M_ini':
            best_val = np.log10(best_val)
        ax[8].text(tx[2],
                   ty[i],
                   '$' + "{0:.2f}".format(best_val) + '$',
                   ha='center',
                   color='c',
                   transform=ax[8].transAxes)
    ax[8].text(tx[0], laby, 'Param', ha='right', transform=ax[8].transAxes)
    ax[8].text(tx[1],
               laby,
               '50%$\pm$33%',
               ha='center',
               color='k',
               transform=ax[8].transAxes)
    ax[8].text(tx[2],
               laby,
               'Best',
               color='k',
               ha='center',
               transform=ax[8].transAxes)

    # now draw boxes around the different kinds of parameters
    tax = ax[8]

    # primary
    rec = Rectangle((tx[0] - 0.1, ty[2] - 0.02),
                    tx[2] - tx[0] + 0.15, (ty[0] - ty[2]) * 1.5,
                    fill=False,
                    lw=2,
                    transform=tax.transAxes,
                    ls='dashed')
    rec = tax.add_patch(rec)
    rec.set_clip_on(False)

    # secondary
    rec = Rectangle((tx[0] - 0.1, ty[5] - 0.02),
                    tx[2] - tx[0] + 0.15, (ty[3] - ty[5]) * 1.5,
                    fill=False,
                    lw=2,
                    transform=tax.transAxes,
                    ls='dotted')
    rec = tax.add_patch(rec)
    rec.set_clip_on(False)

    # derived
    rec = Rectangle((tx[0] - 0.1, ty[8] - 0.02),
                    tx[2] - tx[0] + 0.15, (ty[6] - ty[8]) * 1.5,
                    fill=False,
                    lw=2,
                    transform=tax.transAxes,
                    ls='dashdot')
    rec = tax.add_patch(rec)
    rec.set_clip_on(False)

    # padding for rectangles of 1D PDFs
    pad = 0.1

    # plot the primary parameter 1D PDFs
    plot_1dpdf(ax[0], pdf1d_hdu, 'Av', 'A(V)', starnum, stats=stats)
    plot_1dpdf(ax[1],
               pdf1d_hdu,
               'M_ini',
               'log(M)',
               starnum,
               logx=True,
               stats=stats)
    plot_1dpdf(ax[2], pdf1d_hdu, 'logA', 'log(t)', starnum, stats=stats)

    # draw a box around them and label
    tax = ax[0]
    rec = Rectangle((-1.75 * pad, -pad),
                    3 * (1.0 + pad) + 1.5 * pad,
                    1.0 + 1.5 * pad,
                    fill=False,
                    lw=2,
                    transform=tax.transAxes,
                    ls='dashed')
    rec = tax.add_patch(rec)
    rec.set_clip_on(False)

    tax.text(-2. * pad,
             0.5,
             'Primary',
             transform=tax.transAxes,
             rotation='vertical',
             fontstyle='oblique',
             va='center',
             ha='right')

    tax.text(0.0,
             0.5,
             'Probability',
             transform=tax.transAxes,
             rotation='vertical',
             va='center',
             ha='right')

    # plot the secondary parameter 1D PDFs
    plot_1dpdf(ax[4], pdf1d_hdu, 'Rv', 'R(V)', starnum, stats=stats)
    plot_1dpdf(ax[5],
               pdf1d_hdu,
               'f_A',
               r'f$_\mathcal{A}$',
               starnum,
               stats=stats)
    plot_1dpdf(ax[6], pdf1d_hdu, 'Z', 'Z', starnum, stats=stats)

    # draw a box around them
    tax = ax[4]
    rec = Rectangle((-1.75 * pad, -pad),
                    3 * (1.0 + pad) + 1.5 * pad,
                    1.0 + 1.5 * pad,
                    fill=False,
                    lw=2,
                    transform=tax.transAxes,
                    ls='dotted')
    rec = tax.add_patch(rec)
    rec.set_clip_on(False)

    tax.text(-2 * pad,
             0.5,
             'Secondary',
             transform=tax.transAxes,
             rotation='vertical',
             fontstyle='oblique',
             va='center',
             ha='right')

    tax.text(0.0,
             0.5,
             'Probability',
             transform=tax.transAxes,
             rotation='vertical',
             va='center',
             ha='right')

    # plot the derived parameter 1D PDFs
    plot_1dpdf(ax[3],
               pdf1d_hdu,
               'logT',
               r'log(T$_\mathrm{eff})$',
               starnum,
               stats=stats)
    plot_1dpdf(ax[7], pdf1d_hdu, 'logg', 'log(g)', starnum, stats=stats)

    # draw a box around them
    tax = ax[7]
    rec = Rectangle((-0.25 * pad, -pad),
                    1.0 + 0.5 * pad,
                    2 * (1.0 + 2. * pad) - 0.125 * pad,
                    fill=False,
                    lw=2,
                    transform=tax.transAxes,
                    ls='dashdot')
    rec = tax.add_patch(rec)
    rec.set_clip_on(False)

    tax.text(0.5,
             2 * (1.0 + 2 * pad) - 1.0 * pad,
             'Derived',
             transform=tax.transAxes,
             rotation='horizontal',
             fontstyle='oblique',
             va='bottom',
             ha='center')

    # optimize the figure layout
    plt.tight_layout(h_pad=2.0, w_pad=1.0)