def plot_candle_chart(path_to_csv: str, date_format="%Y-%m-%d") -> None:
    """
    Simple function to plot a candle chart plot.
    This assumes that the files header has 4 columns:

    - Date: The date in the specified format
    - Open: The open price
    - Close: The Close price
    - High: The highest price
    - Low: The lowest price

    :param path_to_csv: Path to the csv file
    :param date_format: The format of the Date column
    """

    # Read the dataframe and convert the index to date format
    df = pd.read_csv(path_to_csv, index_col=0)
    df.index = pd.to_datetime(df.index, format=date_format)

    # Create auxiliary columns
    df["index"] = list(range(df.shape[0]))
    df["bar_width"] = 1  # This is the width of each bar
    df["line_width"] = 0.1  # This is the width of each line
    df["diff_open_close"] = (df["Close"] - df["Open"]).abs()
    df["diff_high_low"] = (df["High"] - df["Low"]).abs()
    df["bar_x"] = df["index"] - (df["bar_width"] / 2)  # Lower left corner
    df["bar_y"] = df[["Open", "Close"]].min(axis=1)  # Lower left corner
    df["line_x"] = df["index"] - (df["line_width"] / 2)  # Lower left corner
    df["line_y"] = df[["High", "Low"]].min(axis=1)  # Lower left corner
    df["color"] = df[["Close",
                      "Open"]].apply(lambda prices: "red"
                                     if prices[1] > prices[0] else "green",
                                     axis=1)

    plt.figure()
    ax = plt.gca()
    for _, row in df.iterrows():
        ax.add_patch(
            rect((row["bar_x"], row["bar_y"]),
                 width=row["bar_width"],
                 height=row["diff_open_close"],
                 color=row["color"]))
        ax.add_patch(
            rect((row["line_x"], row["line_y"]),
                 width=row["line_width"],
                 height=row["diff_high_low"],
                 color=row["color"]))

    plt.xlim(-1, df.shape[0])
    plt.ylim(df["Low"].min(), df["High"].max())

    # Set the sticks
    plt.xticks(df["index"], df.index.date, rotation=90)

    plt.show()
Example #2
0
def pretty_plot(data, labels, clusters, lens, plot_name):
    colors = cm.rainbow(np.linspace(0, 1, len(data)))

    fig = plt.figure()
    ax = plt.axes()

    width = 2
    height = 6
    ax.set_xlim(0, len(data[0]) * width)
    ax.set_ylim(0, len(data) * height)

    label_colors = cm.gist_ncar(np.linspace(0, 1, len(set(clusters.values())) + 1))

    for r, row in enumerate(data):
        colors = cm.rainbow(np.linspace(0, 1, lens.get(labels[r], max(row)) - 2))
        colors = np.vstack((np.array([0., 0., 0., 1.]), colors, np.array([0., 0., 0., 1.])))
        for i, pos in enumerate(row):
            if pos is not None:
                ax.add_patch(rect((i * width, r * height), width, height - 2, color=colors[pos - 1]))
                if labels[r] in clusters:
                    ax.add_line(line([i * width, (i + 1) * width], [r * height, r * height], lw=1,
                                     color=label_colors[clusters[labels[r]]]))
                    ax.add_line(line([i * width, (i + 1) * width], [(r + 1) * height - 1, (r + 1) * height - 1], lw=1,
                                     color=label_colors[clusters[labels[r]]]))
    plt.yticks(map(lambda x: x * height + height / 2., range(len(labels))), labels)
    ax.tick_params(axis='y', which='major', labelsize=3)
    plt.tight_layout()
    plt.savefig(plot_name, dpi=300)
Example #3
0
def gcone_map(stack_path, outpath, coords_path, frame=0, size=64):

    """
    :param stack_path: path to original (not cropped) stack containing multiple growth-cones
    :param outpath: output-path where the image is saved
    :param coords_path: corresponding coordninate-file to the stack
    :param frame: desired frame which will be used, default is 0
    :param size: desired size used to build the rectangle (dimension of rectangle is 2*size x 2*size), default is 64

    Creates a map of the cropped growth-cones from a given stack by coordinates.
    """

    stack = read_stack(stack_path)
    im = stack[frame]
    coords = read_csv(coords_path)

    plt.imshow(im, cmap='gray')
    plt.axis('off')

    for i, (x, y) in enumerate(coords):
        new_xy = (x - size, y - size)
        rectangle = rect(new_xy, size*2, size*2, fill=False)
        plt.gca().add_patch(rectangle)

    name = 'gcone_map.png'
    plt.savefig(os.path.join(outpath, name))
Example #4
0
    def show(self):
        x, y = self.boundary.x - self.boundary.hl, self.boundary.y - self.boundary.hl
        pyplot.gca().add_patch(rect((x, y), self.boundary.hl * 2, self.boundary.hl * 2, facecolor='none'))

        if (self.divided):
            self.northwest.show()
            self.northeast.show()
            self.southwest.show()
            self.southeast.show()
Example #5
0
 def plotree(self, ax):
     angler = np.rad2deg(self.boundary.angle)
     ax.add_patch(
         rect((self.boundary.bleft[0], self.boundary.bleft[1]),
              self.boundary.sides[0],
              self.boundary.sides[1],
              angler,
              color=(1 - 1. / self.gen**2, 1 - 1. / (self.gen + 1)**2,
                     1. / (self.gen + 1)**2, 1. / np.log(self.gen * np.e))))
     if len(self.branch) > 0:
         for i in range(2):
             self.branch[i].plotree(ax)
Example #6
0
def plot_colors(color_list):
    list_sz = len(color_list)
    fig = plt.figure()
    ax = fig.add_subplot(111)

    for i in range(0, list_sz):
        color = tuple([x / 255 for x in color_list[i]])
        rectangle = rect((i, 0), 1, list_sz, color=color)
        ax.add_patch(rectangle)

    plt.xlim([0, list_sz])
    plt.ylim([0, list_sz])
    # plt.show()
    plt.savefig('palette.png', bbox_inches='tight')
Example #7
0
def plotblockclusternode(plt, block, xmin, ymin, width, height, maxlevel, ax):
    if block.level == maxlevel or len(block.children) == 0:

        col = 'b' if block.admissible else 'r'

        r = rect((xmin, ymin),
                 width=width,
                 height=height,
                 color=col,
                 alpha=0.8,
                 visible=True,
                 fill=True)
        r.set_edgecolor('k')

        #plt.gca().add_patch(r)
        ax.add_patch(r)
        return
    else:
        ht = height
        wd = width

        fract = float(block.tau.children[0].n) / float(block.tau.n)
        fracs = float(block.sigma.children[0].n) / float(block.sigma.n)

        fract = float(block.tau.children[0].n) / float(block.tau.n)
        fracs = float(block.sigma.children[0].n) / float(block.sigma.n)

        #[1 0; 0 0]	quadrant
        x = xmin
        y = ymin + (1. - fract) * ht
        plotblockclusternode(plt, block.children[0], x, y, fracs * wd,
                             fract * ht, maxlevel, ax)
        #[0 1; 0 0]	quadrant
        x = xmin + fracs * wd
        y = ymin + (1. - fract) * ht
        plotblockclusternode(plt, block.children[1], x, y, (1. - fracs) * wd,
                             fract * ht, maxlevel, ax)
        #[0 0; 1 0]
        x = xmin
        y = ymin
        plotblockclusternode(plt, block.children[2], x, y, fracs * wd,
                             (1. - fract) * ht, maxlevel, ax)
        #[0 0; 0 1]
        x = xmin + fracs * wd
        y = ymin
        plotblockclusternode(plt, block.children[3], x, y, (1. - fracs) * wd,
                             (1. - fract) * ht, maxlevel, ax)

    return
Example #8
0
def setup_image(path: str, plot: bool = False, retoffset: bool = False, retsize: bool = False, retscale: bool = False)\
        -> (np.ndarray, np.ndarray, np.ndarray):
    # Import parent image and convert to black and white
    parent_image = cv2.cvtColor(cv2.imread(path), cv2.COLOR_RGB2GRAY)
    # Store parent image dimensions as array to reduce lookup times
    parent_dims = np.array([n for n in parent_image.shape])
    # Calculate the size, offset, and scaled size of the sub-image
    offset = np.random.randint(0, [int(n) for n in parent_dims / 2])
    size = np.random.randint([int(n) for n in parent_dims / 5],
                             [int(n) for n in parent_dims / 2])
    scale = np.random.randint(size, size * 2)
    # Crop the parent image using offset and size to create the sub image
    sub_image = parent_image[offset[0]:offset[0] +
                             size[0]].transpose()[offset[1]:offset[1] +
                                                  size[1]].transpose()
    # Resize the sub-image in the x direction
    sub_image = np.array([
        np.interp(np.linspace(0, 1, scale[1]), np.linspace(0, 1, size[1]), n)
        for n in sub_image
    ])
    # Resize the sub-image in the y-direction
    sub_image = np.array([
        np.interp(np.linspace(0, 1, scale[0]), np.linspace(0, 1, size[0]), n)
        for n in sub_image.transpose()
    ]).transpose()
    # Plot the two images
    if plot:
        fig, (ax, ax1) = plt.subplots(2)
        imgplot = ax.imshow(parent_image)
        imgplot = ax1.imshow(sub_image)
        # Add a rectangle onto the parent image to show the position of the sub-image
        ax.add_patch(
            rect((offset[1], offset[0]),
                 size[1],
                 size[0],
                 edgecolor='red',
                 facecolor='none'))
        plt.show()
    out = [parent_image, parent_dims, sub_image]
    out.append(offset) if retoffset else None
    out.append(size - 1) if retsize else None
    out.append(scale - 1) if retscale else None
    return out
Example #9
0
File: vis.py Project: arvindks/kle
def plotblockclusternode(plt, block, xmin, ymin, width, height, maxlevel, ax):
	if block.level == maxlevel or len(block.children) == 0:
		
		col = 'b' if block.admissible else 'r'
		
		r = rect((xmin, ymin), width = width, height = height, color = col, alpha =0.8, visible = True, fill = True)
		r.set_edgecolor('k')
	
		#plt.gca().add_patch(r)
		ax.add_patch(r)
		return
	else:
		ht = height
		wd = width

		fract = float(block.tau.children[0].n)/float(block.tau.n)
		fracs = float(block.sigma.children[0].n)/float(block.sigma.n)

		fract = float(block.tau.children[0].n)/float(block.tau.n)
		fracs = float(block.sigma.children[0].n)/float(block.sigma.n)

		#[1 0; 0 0]	quadrant
		x = xmin
		y = ymin + (1.-fract)*ht
		plotblockclusternode(plt, block.children[0], x, y, fracs*wd, fract*ht, maxlevel, ax)
		#[0 1; 0 0]	quadrant
		x = xmin + fracs*wd
		y = ymin + (1.-fract)*ht
		plotblockclusternode(plt, block.children[1], x, y, (1.-fracs)*wd, fract*ht,maxlevel, ax)
		#[0 0; 1 0]
		x = xmin
		y = ymin
		plotblockclusternode(plt, block.children[2], x, y, fracs*wd, (1.-fract)*ht,maxlevel,ax)
		#[0 0; 0 1]
		x = xmin + fracs*wd
		y = ymin
		plotblockclusternode(plt, block.children[3], x, y, (1.-fracs)*wd, (1.-fract)*ht,maxlevel,ax)
		
	return	
Example #10
0
 def show(self, edgecolor=None):
     x, y = self.x - self.hl, self.y - self.hl
     pyplot.gca().add_patch(rect((x, y), self.hl * 2, self.hl * 2, facecolor='none', edgecolor=edgecolor))
Example #11
0
def plot_bar(syn_h,cal_k,cal_h,cell_nums,obs_idxs,delx,plt_name,kmin,kmax):
    #fig = pylab.figure(figsize=(8,4))
    fig = pylab.figure(figsize=(4.72,4.72))
    axk = pylab.axes((0.1,0.77,0.7,0.21))
    ax1 = pylab.axes((0.1,0.418,0.7,0.25))
    ax2 = pylab.axes((0.1,0.1,0.7,0.25))    
    axk.text(-5.0,5.0,'a) Calibrated hydraulic conductivity distribution',fontsize=8)      
    ax1.text(-5.0,6.5,'b) Calibrated water level distribution',fontsize=8)   
    ax2.text(-5.0,6.5,'c ) Predictive water level distribution',fontsize=8)    
    arrowprops=dict(connectionstyle="angle,angleA=0,angleB=90,rad=10",arrowstyle='->')
    bbox_args = dict(fc="1.0")
    ax1.annotate('Q=0.5 $m^3/d$',fontsize=8,xy=(95,0),xytext=(70.0,1.0),
                 arrowprops=arrowprops,bbox=bbox_args)
    ax2.annotate('Q=1.0 $m^3/d$',fontsize=8,xy=(95,0),xytext=(70.0,1.0),
                 arrowprops=arrowprops,bbox=bbox_args)
    
    axk.text(0.0,-1.2,'Specified\nhead',ha='left',va='top',fontsize=8)
    axk.text(100,-1.2,'Specified\nflux',ha='right',va='top',fontsize=8)
    axk.text(50,-1.6,'Active model cells',ha='center',va='top',fontsize=8)
    arrowprops=dict(arrowstyle='<->')
    axk.annotate('',fontsize=8,xycoords='axes fraction',xy=(0.85,-0.075),xytext=(0.15,-0.075),
                arrowprops=arrowprops) 

    #cmap_name = 'gray'
    #cm = pylab.get_cmap(cmap_name)
    #cnorm = colors.Normalize(vmin=k_min,vmax=k_max)
    #smap = mplcm.ScalarMappable(norm=cnorm,cmap=cm)
    #color = []
    #for i,(k,col) in enumerate(zip(cal_k,cell_nums)):        
    #    c = smap.to_rgba(k)
    #    color.append(c)

    k_rects = axk.bar(cell_nums-(delx/2.0),cal_k,width=delx,color='#58ACFA',edgecolor='k',linewidth=0.5,alpha=0.5)
    axk.plot([0,cell_nums.max()+(0.5*delx)],[2.5,2.5],'k--',lw=1.5)
    axk.text(80,2.8,'True value',ha='left',va='bottom',fontsize=8)
    
        
    ax1.plot(cell_nums,syn_h[0,:],color='b',ls='-')
    ax1.scatter(cell_nums,syn_h[0,:],marker='.',s=25,edgecolor='b',facecolor='b',label='True')

    ax1.plot(cell_nums,cal_h[0,:],color='r',ls='-')
    ax1.scatter(cell_nums,cal_h[0,:],marker='.',s=25,edgecolor='r',facecolor='r',label='Calibrated')

    ax2.plot(cell_nums,syn_h[1,:],color='b',ls='--')
    ax2.scatter(cell_nums,syn_h[1,:],marker='.',s=25,edgecolor='b',facecolor='b',label='True')

    ax2.plot(cell_nums,cal_h[1,:],color='r',ls='--')
    ax2.scatter(cell_nums,cal_h[1,:],marker='.',s=25,edgecolor='r',facecolor='r',label='Calibrated')

    
    for iobs,obs_idx in enumerate(obs_idxs):
        if iobs == 0:
            ax1.scatter([cell_nums[obs_idx]],[syn_h[0,obs_idx]],marker='^',facecolor='k',edgecolor='k',s=50,label='Observation')
        else:
            ax1.scatter([cell_nums[obs_idx]],[syn_h[0,obs_idx]],marker='^',facecolor='k',edgecolor='k',s=50)
    
    for i,(col) in enumerate(cell_nums):
        xmn,xmx = col-(delx*0.5),col+(delx*0.5)
        ymn,ymx = -1.0,0.0   
        if i == 0:
            c = 'm'
        elif i == cell_nums.shape[0]-1:
            c = 'g'
        else:
            c = '#E5E4E2'        
        a = 0.75
        r1 = rect((xmn,ymn),xmx-xmn,ymx-ymn,color=c,ec='k',alpha=a)
        ax1.add_patch(r1)
        r2 = rect((xmn,ymn),xmx-xmn,ymx-ymn,color=c,ec='k',alpha=a)
        ax2.add_patch(r2)
        r3 = rect((xmn,ymn),xmx-xmn,ymx-ymn,color=c,ec='k',alpha=a)
        axk.add_patch(r3)
        x,y = (xmn+xmx)/2.0,(ymn+ymx)/2.0
        ax1.text(x,y,i+1,ha='center',va='center',fontsize=8)
        ax2.text(x,y,i+1,ha='center',va='center',fontsize=8)
        axk.text(x,y,i+1,ha='center',va='center',fontsize=8)
        


    axk.set_ylabel('Hydraulic conductivity\n ($m/d$)',multialignment='center')
    axk.set_xticklabels([])  
    axk.set_yticklabels(['','0','1','2','3','4'])  
    axk.set_ylim(-1,4.5)
    axk.set_xlim(0,cell_nums.max()+(0.5*delx))
    


    ax1.set_ylabel('Water level ($m$)')
    ax1.set_xticklabels([])    
    ax1.set_yticklabels(['','0','1','2','3','4','5','6'])  
    ax1.set_ylim(-1.0,6)
    ax1.set_xlim(0,cell_nums.max()+(0.5*delx))
    #ax1.grid()

    ax2.set_ylabel('Water level ($m$)')
    ax2.set_xlabel('Distance ($m$)')
    ax2.set_ylim(-1.0,6)
    ax2.set_yticklabels(['','0','1','2','3','4','5','6'])  
    ax2.set_xlim(0,cell_nums.max()+(0.5*delx))
    #ax2.grid()
    ax1.legend(scatterpoints=1,columnspacing=8,handletextpad=0.001,bbox_to_anchor=(.9,-1.35),ncol=2,frameon=False)
    ax2.xaxis.labelpad = 1.5
    pylab.savefig(plt_name,dpi=600,bbox_inches='tight')
    pylab.savefig(plt_name.replace('pdf','png'),dpi=600,bbox_inches='tight')
Example #12
0
def reset(event):
    plt.sca(ax_prd)
    plt.cla()
    tracked = []
    new_hds = np.loadtxt(HDS_PATH)
    ax_prd.plot(cell_nums, initial_hds[1, :], lw=1.5, color='0.5', ls="--")
    ax_prd.text(50, 7.5, "Forecast", fontsize=15, ha="center")
    prd, = ax_prd.plot(cell_nums,
                       new_hds[1, :],
                       lw=1.5,
                       color='b',
                       marker='.',
                       markersize=10)
    for i, (col) in enumerate(cell_nums):
        xmn, xmx = col - (delx * 0.5), col + (delx * 0.5)
        ymn, ymx = -1.0, 0.0
        if i == 0:
            c = 'm'
        elif i == cell_nums.shape[0] - 1:
            c = 'g'
        else:
            c = '#E5E4E2'
        a = 0.75
        r2 = rect((xmn, ymn), xmx - xmn, ymx - ymn, color=c, ec='k', alpha=a)
        ax_prd.add_patch(r2)
        x, y = (xmn + xmx) / 2.0, (ymn + ymx) / 2.0
        ax_prd.text(x, y, i + 1, ha='center', va='center', fontsize=12)
        #if i == 7:
        #	r3 = rect((xmn,0.0),xmx-xmn,6-ymn,color='y',ec='k',alpha=0.5)
        #	ax_prd.add_patch(r3)
    ax_prd.text(0.0, -1.6, 'Specified\nhead', ha='left', va='top', fontsize=12)
    ax_prd.text(100,
                -1.6,
                'Specified\nflux',
                ha='right',
                va='top',
                fontsize=12)
    ax_prd.text(50,
                -1.6,
                'Active model cells',
                ha='center',
                va='top',
                fontsize=12)
    ax_prd.text(75,
                4.5,
                '?',
                ha='center',
                va='center',
                fontsize=50,
                alpha=0.25)
    ax_prd.annotate('Q=1.0 $m^3/d$',
                    fontsize=12,
                    xy=(95, 0),
                    xytext=(82.0, 1.0),
                    arrowprops=arrowprops,
                    bbox=bbox_args)
    ax_prd.set_ylim(-1, 8.5)
    ax_prd.set_xticklabels([])
    #ax_prd.set_yticklabels(['','0','1','2','3','4','5','6'])
    #ax_prd.fill_between(cell_nums,lower_95_hds[1,:],upper_95_hds[1,:],\
    #	facecolor="0.5",edgecolor="none",alpha=0.25)
    ax_prd.plot([cell_nums[7], cell_nums[7]],
                prior_range,
                lw=10,
                color="0.5",
                alpha=0.5,
                label="prior credible range")
Example #13
0
                      (initial_hk.shape[1] * delx) + delx, delx) - (0.5 * delx)
fig = plt.figure(figsize=(8, 8))
ax_cal = plt.axes((0.1, 0.575, 0.8, 0.4))
ax_prd = plt.axes((0.1, 0.15, 0.8, 0.4))

for i, (col) in enumerate(cell_nums):
    xmn, xmx = col - (delx * 0.5), col + (delx * 0.5)
    ymn, ymx = -1.0, 0.0
    if i == 0:
        c = 'm'
    elif i == cell_nums.shape[0] - 1:
        c = 'g'
    else:
        c = '#E5E4E2'
    a = 0.75
    r1 = rect((xmn, ymn), xmx - xmn, ymx - ymn, color=c, ec='k', alpha=a)
    ax_cal.add_patch(r1)
    r2 = rect((xmn, ymn), xmx - xmn, ymx - ymn, color=c, ec='k', alpha=a)
    ax_prd.add_patch(r2)
    x, y = (xmn + xmx) / 2.0, (ymn + ymx) / 2.0
    ax_cal.text(x, y, i + 1, ha='center', va='center', fontsize=12)
    ax_prd.text(x, y, i + 1, ha='center', va='center', fontsize=12)

x = np.arange(0, 100, delx)
ax_cal.scatter([cell_nums[3], cell_nums[5]], [2.1, 2.5],
               marker='^',
               s=50,
               edgecolor="none",
               facecolor="r",
               label="observed")
cal, = ax_cal.plot(cell_nums,
def plot_domain():
    pyemu.os_utils.run("mfnwt {0}".format(nam_file), cwd=t_d)
    m = flopy.modflow.Modflow.load(nam_file, model_ws=t_d, check=False)
    x = np.arange(m.ncol) + 1
    harr = np.loadtxt(os.path.join(t_d, nam_file.replace(".nam", ".hds")))
    fig, axes = plt.subplots(2, 1, figsize=(8, 4))
    axes[0].plot(x, harr[0, :], marker='.', color='b')
    axes[1].plot(x, harr[1, :], marker='.', color='b')

    axes[0].set_xticks(x)
    axes[1].set_xticks(x)
    axes[0].set_ylim(0, harr.max() * 1.2)
    axes[1].set_ylim(0, harr.max() * 1.2)

    for i in range(m.ncol):
        t = m.dis.top.array[0, i]
        b = m.dis.botm.array[0, 0, i]
        c = "0.5"
        if i == 0:
            c = "g"
        if i == m.ncol - 1:
            c = "m"
        x = i + 0.5
        r1 = rect((x, b), 1.0, t - b, facecolor=c, edgecolor="k", alpha=0.5)
        r2 = rect((x, b), 1.0, t - b, facecolor=c, edgecolor="k", alpha=0.5)
        axes[0].add_patch(r1)
        axes[1].add_patch(r2)
        axes[0].text(i + 1, (t - b) / 2.0,
                     str(i + 1),
                     ha="center",
                     va="center")
        axes[1].text(i + 1, (t - b) / 2.0,
                     str(i + 1),
                     ha="center",
                     va="center")

    ox = [4, 6]
    oy = harr[0, [3, 5]]
    axes[0].scatter(ox, oy, marker="^", color="b", s=55)

    axes[0].annotate("water level obs",
                     xy=(ox[0], oy[0]),
                     xycoords='data',
                     xytext=(5, 3),
                     textcoords='data',
                     size=8,
                     va="center",
                     ha="center",
                     bbox=dict(boxstyle="round4", fc="w"),
                     arrowprops=dict(arrowstyle="-|>",
                                     connectionstyle="arc3,rad=0.5",
                                     fc="w"))
    axes[0].annotate("water level obs",
                     xy=(ox[1], oy[1]),
                     xycoords='data',
                     xytext=(5, 3),
                     textcoords='data',
                     size=8,
                     va="center",
                     ha="center",
                     bbox=dict(boxstyle="round4", fc="w"),
                     arrowprops=dict(arrowstyle="-|>",
                                     connectionstyle="arc3,rad=-0.5",
                                     fc="w"))

    ox = 8
    oy = harr[0, 7]
    axes[0].scatter(ox, oy, marker="^", color="r", s=55, zorder=10)
    axes[0].annotate("water level\nforecast",
                     xy=(ox, oy),
                     xycoords='data',
                     xytext=(7, 4),
                     textcoords='data',
                     size=8,
                     va="center",
                     ha="center",
                     bbox=dict(boxstyle="round4", fc="w"),
                     arrowprops=dict(arrowstyle="-|>",
                                     connectionstyle="arc3,rad=-0.5",
                                     fc="w"))

    ox = 8
    oy = harr[1, 7]
    axes[1].scatter(ox, oy, marker="^", color="r", s=55, zorder=10)
    axes[1].annotate("water level\nforecast",
                     xy=(ox, oy),
                     xycoords='data',
                     xytext=(7, 4.7),
                     textcoords='data',
                     size=8,
                     va="center",
                     ha="center",
                     bbox=dict(boxstyle="round4", fc="w"),
                     arrowprops=dict(arrowstyle="-|>",
                                     connectionstyle="arc3,rad=-0.5",
                                     fc="w"))

    axes[0].text(0.5, -0.5, "specified\nwater level", ha="left", va="center")
    axes[0].text(10.5, -0.5, "specified\ninflow", ha="right", va="center")
    axes[1].text(0.5, -0.5, "specified\nwater level", ha="left", va="center")
    axes[1].text(10.5, -0.5, "specified\ninflow", ha="right", va="center")

    axes[0].set_ylabel("water level")
    axes[1].set_ylabel("water level")
    axes[0].set_xticks([])
    axes[1].set_xticks([])
    axes[0].set_xlabel("active model cell")
    axes[1].set_xlabel("active model cell")

    axes[0].set_title("A) stress period 1: history", loc="left")
    axes[1].set_title("B) stress period 2: future", loc="left")

    axes[0].annotate("0.5 $\\frac{L^3}{T}$",
                     xy=(10.0, 1.0),
                     xycoords='data',
                     xytext=(8.75, 1.95),
                     textcoords='data',
                     size=8,
                     va="center",
                     ha="center",
                     bbox=dict(boxstyle="round4", fc="w"),
                     arrowprops=dict(arrowstyle="-|>",
                                     connectionstyle="arc3,rad=-0.5",
                                     fc="w"))
    axes[1].annotate("1.0 $\\frac{L^3}{T}$",
                     xy=(10.0, 1.0),
                     xycoords='data',
                     xytext=(8.75, 1.95),
                     textcoords='data',
                     size=8,
                     va="center",
                     ha="center",
                     bbox=dict(boxstyle="round4", fc="w"),
                     arrowprops=dict(arrowstyle="-|>",
                                     connectionstyle="arc3,rad=-0.5",
                                     fc="w"))
    axes[0].set_xlim(0.5, (m.ncol) + 0.5)
    axes[1].set_xlim(0.5, (m.ncol) + 0.5)
    plt.tight_layout()
    plt.show()