Ejemplo n.º 1
0
def makeFig1_v2(zNorm=True, whichTs=WHICH_DISHWASHER_TS):

	mpl.rcParams['axes.facecolor'] = AXES_BG_COLOR

	INSTANCE_BOUNDS_ALPHA = .3

	ts_dw = getFig1Ts(zNorm=zNorm, whichTs=whichTs)
	ts_dw.data[:, 2] /= 2 # reduce max height of spikiest dim to make it pretty
	ts_dw.endIdxs[2] += 25 # appears like it's missing stuff; fix this

	# remove the red since we'll save this to highlight the "pattern" dim
	palette = sb.color_palette()
	palette = palette[:2] + palette[3:]
	highlightColor = sb.color_palette()[2] # red
	sb.set_palette(palette)

	# ------------------------ set up axes
	FIG_SIZE = (8, 6)
	NUM_ROWS = 3
	NUM_COLS = 1
	gridSz = (NUM_ROWS, NUM_COLS)
	fig = plt.figure(figsize=FIG_SIZE)

	ax0 = plt.subplot2grid(gridSz, (0, 0))
	ax1 = plt.subplot2grid(gridSz, (1, 0), sharex=ax0)
	ax2 = plt.subplot2grid(gridSz, (2, 0), sharex=ax1)
	axes = [ax0, ax1, ax2]

	# basic axes configuration
	for ax in axes:
		ax.autoscale(tight=True)
		plt.setp(ax.get_yticklabels(), visible=False)
	plt.setp(ax0.get_xticklabels(), visible=False)
	plt.setp(ax1.get_xticklabels(), visible=False)

	# ------------------------ find patterns in ts

	lengths = [150]
	Lmin, Lmax = 100, 200
	onlyPair = False
	ts = ts_dw.clone()

	ts_ff = labelTs_ff(ts, Lmin, Lmax)

	# run mdl algo as state-of-the-art; we help it out a bit by adding
	# noise so it doesn't return flat sections, as well as by only using
	# the 3 most correct places it returns
	np.random.seed(123)
	ts.data += np.random.randn(*ts.data.shape) * .005
	# print "labels", ts.labels

	ts_sota = labelTs_sota(ts, lengths, onlyPair=onlyPair)
	ts_sota.startIdxs[2] = ts_sota.startIdxs[3]
	ts_sota.endIdxs[2] = ts_sota.endIdxs[3]
	ts_sota.startIdxs = ts_sota.startIdxs[:3]
	ts_sota.endIdxs = ts_sota.endIdxs[:3]

	ts_ff.data = np.copy(ts_dw.data)
	ts_sota.data = np.copy(ts_dw.data)

	# show ground truth, ff, and state-of-the-art
	linewidths = 1.5
	ts_dw.plot(ax=ax0, showBounds=True, showLabels=False,
		linewidths=linewidths, useWhichLabels=['Z3'],
		alpha=INSTANCE_BOUNDS_ALPHA)
	ts_ff.plot(ax=ax2, showLabels=False, alpha=INSTANCE_BOUNDS_ALPHA,
		linewidths=linewidths)
	ts_sota.plot(ax=ax1, showLabels=False, alpha=INSTANCE_BOUNDS_ALPHA,
		linewidths=linewidths)

	# plot the dim where the pattern is obvious in bright red
	tsList = [ts_ff, ts_sota, ts_dw]
	for ax, ts in zip(axes, tsList):
		ax.plot(ts.data[:, DISHWASHER_DIM_TO_HIGHLIGHT], color=highlightColor)

	# ax0.set_title("True instances of appliance running")
	ax0.set_title("True instances of appliance running", y=1.03)
	# ax1.set_title("Pattern discovered by [10] and [17]", y=1.01)
	# ax1.set_title("Pattern discovered using nearest neighbors [17]", y=1.01)
	ax1.set_title("Pattern discovered by [10]", y=1.01)
	ax2.set_title("Pattern discovered by Flock (proposed)", y=1.01)
	ax2.set_xlabel("Minutes", labelpad=1, fontsize=14)

	for ax in axes[3:]: # lower plots
		ax.set_title("")

	# annotate parts a, b, and c
	# fig.text(.01, .97, "a)", fontsize=18)
	# fig.text(.01, .64, "b)", fontsize=18)
	# fig.text(.01, .31, "c)", fontsize=18) # these 3 optimal for (8, 7)
	fig.text(.01, .96, "a)", fontsize=18)
	fig.text(.01, .65, "b)", fontsize=18)
	fig.text(.01, .33, "c)", fontsize=18)

	for ax in axes:
		viz.setXtickPadding(ax, 2.) # move x labels up; default ~=~ 4

	plt.tight_layout()
	# plt.subplots_adjust(left=.01, right=.999, top=.96, bottom=.03, hspace=.19)
	# plt.subplots_adjust(left=.01, right=.999, top=.96, bottom=.03) # optimal for (8, 7)
	plt.subplots_adjust(left=.01, right=.999, top=.945, bottom=.07, hspace=.27)

	saveFigWithName('fig1')
Ejemplo n.º 2
0
def makeFig1_v2(zNorm=True, whichTs=WHICH_DISHWASHER_TS):

    mpl.rcParams['axes.facecolor'] = AXES_BG_COLOR

    INSTANCE_BOUNDS_ALPHA = .3

    ts_dw = getFig1Ts(zNorm=zNorm, whichTs=whichTs)
    ts_dw.data[:,
               2] /= 2  # reduce max height of spikiest dim to make it pretty
    ts_dw.endIdxs[2] += 25  # appears like it's missing stuff; fix this

    # remove the red since we'll save this to highlight the "pattern" dim
    palette = sb.color_palette()
    palette = palette[:2] + palette[3:]
    highlightColor = sb.color_palette()[2]  # red
    sb.set_palette(palette)

    # ------------------------ set up axes
    FIG_SIZE = (8, 6)
    NUM_ROWS = 3
    NUM_COLS = 1
    gridSz = (NUM_ROWS, NUM_COLS)
    fig = plt.figure(figsize=FIG_SIZE)

    ax0 = plt.subplot2grid(gridSz, (0, 0))
    ax1 = plt.subplot2grid(gridSz, (1, 0), sharex=ax0)
    ax2 = plt.subplot2grid(gridSz, (2, 0), sharex=ax1)
    axes = [ax0, ax1, ax2]

    # basic axes configuration
    for ax in axes:
        ax.autoscale(tight=True)
        plt.setp(ax.get_yticklabels(), visible=False)
    plt.setp(ax0.get_xticklabels(), visible=False)
    plt.setp(ax1.get_xticklabels(), visible=False)

    # ------------------------ find patterns in ts

    lengths = [150]
    Lmin, Lmax = 100, 200
    onlyPair = False
    ts = ts_dw.clone()

    ts_ff = labelTs_ff(ts, Lmin, Lmax)

    # run mdl algo as state-of-the-art; we help it out a bit by adding
    # noise so it doesn't return flat sections, as well as by only using
    # the 3 most correct places it returns
    np.random.seed(123)
    ts.data += np.random.randn(*ts.data.shape) * .005
    # print "labels", ts.labels

    ts_sota = labelTs_sota(ts, lengths, onlyPair=onlyPair)
    ts_sota.startIdxs[2] = ts_sota.startIdxs[3]
    ts_sota.endIdxs[2] = ts_sota.endIdxs[3]
    ts_sota.startIdxs = ts_sota.startIdxs[:3]
    ts_sota.endIdxs = ts_sota.endIdxs[:3]

    ts_ff.data = np.copy(ts_dw.data)
    ts_sota.data = np.copy(ts_dw.data)

    # show ground truth, ff, and state-of-the-art
    linewidths = 1.5
    ts_dw.plot(ax=ax0,
               showBounds=True,
               showLabels=False,
               linewidths=linewidths,
               useWhichLabels=['Z3'],
               alpha=INSTANCE_BOUNDS_ALPHA)
    ts_ff.plot(ax=ax2,
               showLabels=False,
               alpha=INSTANCE_BOUNDS_ALPHA,
               linewidths=linewidths)
    ts_sota.plot(ax=ax1,
                 showLabels=False,
                 alpha=INSTANCE_BOUNDS_ALPHA,
                 linewidths=linewidths)

    # plot the dim where the pattern is obvious in bright red
    tsList = [ts_ff, ts_sota, ts_dw]
    for ax, ts in zip(axes, tsList):
        ax.plot(ts.data[:, DISHWASHER_DIM_TO_HIGHLIGHT], color=highlightColor)

    # ax0.set_title("True instances of appliance running")
    ax0.set_title("True instances of appliance running", y=1.03)
    # ax1.set_title("Pattern discovered by [10] and [17]", y=1.01)
    # ax1.set_title("Pattern discovered using nearest neighbors [17]", y=1.01)
    ax1.set_title("Pattern discovered by [10]", y=1.01)
    ax2.set_title("Pattern discovered by Flock (proposed)", y=1.01)
    ax2.set_xlabel("Minutes", labelpad=1, fontsize=14)

    for ax in axes[3:]:  # lower plots
        ax.set_title("")

    # annotate parts a, b, and c
    # fig.text(.01, .97, "a)", fontsize=18)
    # fig.text(.01, .64, "b)", fontsize=18)
    # fig.text(.01, .31, "c)", fontsize=18) # these 3 optimal for (8, 7)
    fig.text(.01, .96, "a)", fontsize=18)
    fig.text(.01, .65, "b)", fontsize=18)
    fig.text(.01, .33, "c)", fontsize=18)

    for ax in axes:
        viz.setXtickPadding(ax, 2.)  # move x labels up; default ~=~ 4

    plt.tight_layout()
    # plt.subplots_adjust(left=.01, right=.999, top=.96, bottom=.03, hspace=.19)
    # plt.subplots_adjust(left=.01, right=.999, top=.96, bottom=.03) # optimal for (8, 7)
    plt.subplots_adjust(left=.01, right=.999, top=.945, bottom=.07, hspace=.27)

    saveFigWithName('fig1')
Ejemplo n.º 3
0
def makeCombinedFig1(short=False, zNorm=False, whichTs=-1, scaleVariance=False):
	# sb.set_style('ticks')
	# sb.set_style('white')

	mpl.rcParams['axes.facecolor'] = AXES_BG_COLOR

	ts_dw = getFig1Ts(zNorm=zNorm, whichTs=whichTs)
	ts_rect = getGoodRectsTs()
	ts_tri = getGoodTrianglesTs()
	ts_shape = getGoodShapesTs()

	if scaleVariance:
		ts_dw_pretty = getFig1Ts(scaleVariance=True)
	else:
		ts_dw_pretty = ts_dw

	# remove the red since we'll save this to highlight the "pattern" dim
	palette = sb.color_palette()
	palette = palette[:2] + palette[3:]
	highlightColor = sb.color_palette()[2] # red
	sb.set_palette(palette)

	# set up axes
	if short:
		SCALE = 3
		OFFSET = 1
		NUM_ROWS = 2 * SCALE + 1
		FIG_SIZE = (8, 5)
	else:
		SCALE = 2
		OFFSET = 1
		NUM_ROWS = 5 * SCALE + 1
		FIG_SIZE = (8, 10)
	NUM_COLS = 2 * SCALE
	gridSz = (NUM_ROWS, NUM_COLS)
	fig = plt.figure(figsize=FIG_SIZE)
	ax0 = plt.subplot2grid(gridSz, (0,0), rowspan=SCALE, colspan=2*SCALE)
	ax10 = plt.subplot2grid(gridSz, (1 * SCALE + OFFSET, 0 * SCALE),
		rowspan=SCALE, colspan=SCALE)
	ax11 = plt.subplot2grid(gridSz, (1 * SCALE + OFFSET, 1 * SCALE),
		rowspan=SCALE, colspan=SCALE)
	if short:
		axes = [ax0, ax10, ax11]
		leftAxes = [ax10]
		rightAxes = [ax11]
	else:
		ax20 = plt.subplot2grid(gridSz, (2 * SCALE + OFFSET, 0 * SCALE),
			rowspan=SCALE, colspan=SCALE)
		ax21 = plt.subplot2grid(gridSz, (2 * SCALE + OFFSET, 1 * SCALE),
			rowspan=SCALE, colspan=SCALE)
		ax30 = plt.subplot2grid(gridSz, (3 * SCALE + OFFSET, 0 * SCALE),
			rowspan=SCALE, colspan=SCALE, sharex=ax20)
		ax31 = plt.subplot2grid(gridSz, (3 * SCALE + OFFSET, 1 * SCALE),
			rowspan=SCALE, colspan=SCALE, sharex=ax21)
		ax40 = plt.subplot2grid(gridSz, (4 * SCALE + OFFSET, 0 * SCALE),
			rowspan=SCALE, colspan=SCALE, sharex=ax30)
		ax41 = plt.subplot2grid(gridSz, (4 * SCALE + OFFSET, 1 * SCALE),
			rowspan=SCALE, colspan=SCALE, sharex=ax31)
		axes = [ax0, ax10, ax11, ax20, ax21, ax30, ax31, ax40, ax41]
		leftAxes = [ax10, ax20, ax30, ax40]
		rightAxes = [ax11, ax21, ax31, ax41]

	# basic axes setup
	for ax in axes:
		ax.autoscale(tight=True)
		# sb.despine(left=True, ax=ax)
		# plt.setp(ax.get_xticklabels(), visible=False) # actually, do show x labels
	plt.setp(ax0.get_xticklabels(), visible=True)

	for ax in axes:
		plt.setp(ax.get_yticklabels(), visible=False)

	# show dishwasher data
	# ts_noNorm = getFig1Ts(zNorm=False, whichTs=whichTs)
	# variances = np.var(ts_noNorm.data, axis=0)
	# linewidths = 1. + variances / np.max(variances)
	ts_dw_pretty.data[:, 2] /= 2 # reduce max height of spikiest dim to make it pretty
	linewidths = 1.5
	ts_dw_pretty.plot(showBounds=False, showLabels=False, ax=ax0,
		linewidths=linewidths)
	ax0.plot(ts_dw_pretty.data[:, DISHWASHER_DIM_TO_HIGHLIGHT], color=highlightColor)

	# show other pairs of data
	if short:
		tsList = [ts_dw]
	else:
		tsList = [ts_dw, ts_tri, ts_rect, ts_shape]
	for i, ts in enumerate(tsList):
		axLeft, axRight = leftAxes[i], rightAxes[i]

		lengths = [50]
		Lmin, Lmax = .1, .2
		onlyPair = True
		if ts == ts_dw: # dishwasher different than other (synthetic) ones
			lengths = [150]
			Lmin, Lmax = 100, 200
			onlyPair = False

		if ts == ts_rect: # TODO remove hack after prototyping fig
			ts_ff = labelTs_ff(ts, Lmin, Lmax, extractTrueLocsAlgo='none')
		else:
			ts_ff = labelTs_ff(ts, Lmin, Lmax)

		# run mdl algo as state-of-the-art; we help it out a bit by adding
		# noise so it doesn't return flat sections, as well as by only using
		# the 3 most correct places it returns
		ts.data += np.random.randn(*ts.data.shape) * .005
		ts_sota = labelTs_sota(ts, lengths, onlyPair=onlyPair)
		ts_sota.startIdxs[2] = ts_sota.startIdxs[3]
		ts_sota.endIdxs[2] = ts_sota.endIdxs[3]
		ts_sota.startIdxs = ts_sota.startIdxs[:3]
		ts_sota.endIdxs = ts_sota.endIdxs[:3]

		print "shapes:"
		print ts_dw.data.shape
		print ts_dw_pretty.data.shape
		print ts_sota.data.shape
		print ts_ff.data.shape
		if i == 0:
			ts_sota.data = np.copy(ts_dw_pretty.data)
			ts_ff.data = np.copy(ts_dw_pretty.data)
		ts_sota.plot(showLabels=False, ax=axLeft, alpha=.4, linewidths=linewidths)
		ts_ff.plot(showLabels=False, ax=axRight, alpha=.4, linewidths=linewidths)

		# plot the dim where the pattern is obvious in bright red
		axLeft.plot(ts_sota.data[:, DISHWASHER_DIM_TO_HIGHLIGHT], color=highlightColor)
		axRight.plot(ts_ff.data[:, DISHWASHER_DIM_TO_HIGHLIGHT], color=highlightColor)


	# leftAxes[0].set_ylim([0, 120])
	# rightAxes[0].set_ylim([0, 120])

	ax0.set_title("Dishwasher Power Measures Over Time")
	ax0.set_xlabel("Minute", labelpad=0, fontsize=14)
	ax10.set_title("State-of-the-art")
	ax11.set_title("Flock (proposed)")

	for ax in axes[3:]: # lower plots
		ax.set_title("")

	# leftAxes[0].set_yticks([0, 250, 500, 750, 1000])
	# for ax in leftAxes[1:-1]:
	# 	ax.set_yticks([0, .25, .5, .75, 1.])

	# annotate part a and part b
	if short:
		# fig.text(.01, .94, "a)", fontsize=18)
		# fig.text(.01, .42, "b)", fontsize=18)
		fig.text(.01, .95, "a)", fontsize=18)
		fig.text(.01, .44, "b)", fontsize=18)
	else:
		fig.text(.01, .97, "a)", fontsize=16)
		fig.text(.01, .71, "b)", fontsize=16)

	for ax in axes:
		viz.setXtickPadding(ax, 2.) # move x labels up; default ~=~ 4

	plt.tight_layout()
	# plt.subplots_adjust(left=.01, right=.99, bottom=.01, hspace=.1) # TODO uncomment
	plt.subplots_adjust(left=.01, right=.99, top=.93, bottom=0.04, hspace=.1)
	# plt.show()

	figName = 'fig1'
	# if whichTs >= 0:
	# 	figName += '_' + str(whichTs)
	saveFigWithName(figName)
Ejemplo n.º 4
0
def makeCombinedFig1(short=False,
                     zNorm=False,
                     whichTs=-1,
                     scaleVariance=False):
    # sb.set_style('ticks')
    # sb.set_style('white')

    mpl.rcParams['axes.facecolor'] = AXES_BG_COLOR

    ts_dw = getFig1Ts(zNorm=zNorm, whichTs=whichTs)
    ts_rect = getGoodRectsTs()
    ts_tri = getGoodTrianglesTs()
    ts_shape = getGoodShapesTs()

    if scaleVariance:
        ts_dw_pretty = getFig1Ts(scaleVariance=True)
    else:
        ts_dw_pretty = ts_dw

    # remove the red since we'll save this to highlight the "pattern" dim
    palette = sb.color_palette()
    palette = palette[:2] + palette[3:]
    highlightColor = sb.color_palette()[2]  # red
    sb.set_palette(palette)

    # set up axes
    if short:
        SCALE = 3
        OFFSET = 1
        NUM_ROWS = 2 * SCALE + 1
        FIG_SIZE = (8, 5)
    else:
        SCALE = 2
        OFFSET = 1
        NUM_ROWS = 5 * SCALE + 1
        FIG_SIZE = (8, 10)
    NUM_COLS = 2 * SCALE
    gridSz = (NUM_ROWS, NUM_COLS)
    fig = plt.figure(figsize=FIG_SIZE)
    ax0 = plt.subplot2grid(gridSz, (0, 0), rowspan=SCALE, colspan=2 * SCALE)
    ax10 = plt.subplot2grid(gridSz, (1 * SCALE + OFFSET, 0 * SCALE),
                            rowspan=SCALE,
                            colspan=SCALE)
    ax11 = plt.subplot2grid(gridSz, (1 * SCALE + OFFSET, 1 * SCALE),
                            rowspan=SCALE,
                            colspan=SCALE)
    if short:
        axes = [ax0, ax10, ax11]
        leftAxes = [ax10]
        rightAxes = [ax11]
    else:
        ax20 = plt.subplot2grid(gridSz, (2 * SCALE + OFFSET, 0 * SCALE),
                                rowspan=SCALE,
                                colspan=SCALE)
        ax21 = plt.subplot2grid(gridSz, (2 * SCALE + OFFSET, 1 * SCALE),
                                rowspan=SCALE,
                                colspan=SCALE)
        ax30 = plt.subplot2grid(gridSz, (3 * SCALE + OFFSET, 0 * SCALE),
                                rowspan=SCALE,
                                colspan=SCALE,
                                sharex=ax20)
        ax31 = plt.subplot2grid(gridSz, (3 * SCALE + OFFSET, 1 * SCALE),
                                rowspan=SCALE,
                                colspan=SCALE,
                                sharex=ax21)
        ax40 = plt.subplot2grid(gridSz, (4 * SCALE + OFFSET, 0 * SCALE),
                                rowspan=SCALE,
                                colspan=SCALE,
                                sharex=ax30)
        ax41 = plt.subplot2grid(gridSz, (4 * SCALE + OFFSET, 1 * SCALE),
                                rowspan=SCALE,
                                colspan=SCALE,
                                sharex=ax31)
        axes = [ax0, ax10, ax11, ax20, ax21, ax30, ax31, ax40, ax41]
        leftAxes = [ax10, ax20, ax30, ax40]
        rightAxes = [ax11, ax21, ax31, ax41]

    # basic axes setup
    for ax in axes:
        ax.autoscale(tight=True)
        # sb.despine(left=True, ax=ax)
        # plt.setp(ax.get_xticklabels(), visible=False) # actually, do show x labels
    plt.setp(ax0.get_xticklabels(), visible=True)

    for ax in axes:
        plt.setp(ax.get_yticklabels(), visible=False)

    # show dishwasher data
    # ts_noNorm = getFig1Ts(zNorm=False, whichTs=whichTs)
    # variances = np.var(ts_noNorm.data, axis=0)
    # linewidths = 1. + variances / np.max(variances)
    ts_dw_pretty.data[:,
                      2] /= 2  # reduce max height of spikiest dim to make it pretty
    linewidths = 1.5
    ts_dw_pretty.plot(showBounds=False,
                      showLabels=False,
                      ax=ax0,
                      linewidths=linewidths)
    ax0.plot(ts_dw_pretty.data[:, DISHWASHER_DIM_TO_HIGHLIGHT],
             color=highlightColor)

    # show other pairs of data
    if short:
        tsList = [ts_dw]
    else:
        tsList = [ts_dw, ts_tri, ts_rect, ts_shape]
    for i, ts in enumerate(tsList):
        axLeft, axRight = leftAxes[i], rightAxes[i]

        lengths = [50]
        Lmin, Lmax = .1, .2
        onlyPair = True
        if ts == ts_dw:  # dishwasher different than other (synthetic) ones
            lengths = [150]
            Lmin, Lmax = 100, 200
            onlyPair = False

        if ts == ts_rect:  # TODO remove hack after prototyping fig
            ts_ff = labelTs_ff(ts, Lmin, Lmax, extractTrueLocsAlgo='none')
        else:
            ts_ff = labelTs_ff(ts, Lmin, Lmax)

        # run mdl algo as state-of-the-art; we help it out a bit by adding
        # noise so it doesn't return flat sections, as well as by only using
        # the 3 most correct places it returns
        ts.data += np.random.randn(*ts.data.shape) * .005
        ts_sota = labelTs_sota(ts, lengths, onlyPair=onlyPair)
        ts_sota.startIdxs[2] = ts_sota.startIdxs[3]
        ts_sota.endIdxs[2] = ts_sota.endIdxs[3]
        ts_sota.startIdxs = ts_sota.startIdxs[:3]
        ts_sota.endIdxs = ts_sota.endIdxs[:3]

        print "shapes:"
        print ts_dw.data.shape
        print ts_dw_pretty.data.shape
        print ts_sota.data.shape
        print ts_ff.data.shape
        if i == 0:
            ts_sota.data = np.copy(ts_dw_pretty.data)
            ts_ff.data = np.copy(ts_dw_pretty.data)
        ts_sota.plot(showLabels=False,
                     ax=axLeft,
                     alpha=.4,
                     linewidths=linewidths)
        ts_ff.plot(showLabels=False,
                   ax=axRight,
                   alpha=.4,
                   linewidths=linewidths)

        # plot the dim where the pattern is obvious in bright red
        axLeft.plot(ts_sota.data[:, DISHWASHER_DIM_TO_HIGHLIGHT],
                    color=highlightColor)
        axRight.plot(ts_ff.data[:, DISHWASHER_DIM_TO_HIGHLIGHT],
                     color=highlightColor)

    # leftAxes[0].set_ylim([0, 120])
    # rightAxes[0].set_ylim([0, 120])

    ax0.set_title("Dishwasher Power Measures Over Time")
    ax0.set_xlabel("Minute", labelpad=0, fontsize=14)
    ax10.set_title("State-of-the-art")
    ax11.set_title("Flock (proposed)")

    for ax in axes[3:]:  # lower plots
        ax.set_title("")

    # leftAxes[0].set_yticks([0, 250, 500, 750, 1000])
    # for ax in leftAxes[1:-1]:
    # 	ax.set_yticks([0, .25, .5, .75, 1.])

    # annotate part a and part b
    if short:
        # fig.text(.01, .94, "a)", fontsize=18)
        # fig.text(.01, .42, "b)", fontsize=18)
        fig.text(.01, .95, "a)", fontsize=18)
        fig.text(.01, .44, "b)", fontsize=18)
    else:
        fig.text(.01, .97, "a)", fontsize=16)
        fig.text(.01, .71, "b)", fontsize=16)

    for ax in axes:
        viz.setXtickPadding(ax, 2.)  # move x labels up; default ~=~ 4

    plt.tight_layout()
    # plt.subplots_adjust(left=.01, right=.99, bottom=.01, hspace=.1) # TODO uncomment
    plt.subplots_adjust(left=.01, right=.99, top=.93, bottom=0.04, hspace=.1)
    # plt.show()

    figName = 'fig1'
    # if whichTs >= 0:
    # 	figName += '_' + str(whichTs)
    saveFigWithName(figName)