Exemplo n.º 1
0
def draw(fig, old, new, leglabels, legpointers):
    ax = fig.gca()
    assert old.nsensors == new.nsensors

    for i in range(0, old.nsensors):
        old.sensors[i].drawNominalPosition(
            "nominal position" if i == 0 else "", ax, leglabels, legpointers)
        #no name skips label for i>1
        #draw fitted old position
        old.sensors[i].drawSensor("fitted w/o B-field" if i == 0 else "", "r",
                                  old.x, old.y, ax, leglabels, legpointers)
        #draw fitted new position
        new.sensors[i].drawSensor("fitted w/ B-field" if i == 0 else "", "g",
                                  new.x, new.y, ax, leglabels, legpointers)
        #arrows and text
        """
        ax.annotate("",
                xy=(posnew[0]+shiftnew[0],posnew[1]+shiftnew[1]), xycoords='data',
                xytext=(pos[0]+shift[0],pos[1]+shift[1]), textcoords='data',
                arrowprops=dict(arrowstyle="fancy", #linestyle="dashed",
                                color="0.1",
                                shrinkA=0, shrinkB=0,
                                patchA=None,
                                patchB=None,
                                connectionstyle="arc3,rad=0.2",
                                ),
                ) #arrow for shift due to magnetic field
        """

        text = (
            "Far" if new.isFarHalf else "Near"
        ) + " (without B field)\nx={0:.2f}+-{1:.2f}\ny={2:.3f}+-{3:.2f}".format(
            old.x, (old.xeu - old.xel) / 2, old.y, (old.yeu - old.yel) / 2)
        an1 = ax.annotate(text,
                          xy=(0.02 if new.isFarHalf else 0.59, 0.97),
                          xycoords="axes fraction",
                          va="top",
                          ha="left" if new.isFarHalf else "right",
                          bbox=dict(boxstyle="round",
                                    fc="w"))  #box with values 1

        from matplotlib.text import OffsetFrom
        offset_from = OffsetFrom(an1, (0.5, 0))
        text = (
            "Far" if new.isFarHalf else "Near"
        ) + " (with B field)\nx={0:.2f}+-{1:.2f}\ny={2:.3f}+-{3:.2f}".format(
            new.x, (new.xeu - new.xel) / 2, new.y, (new.yeu - new.yel) / 2)
        an2 = ax.annotate(
            text,
            xy=(0.1, 0.1),
            xycoords="data",
            xytext=(0, -10),
            textcoords=offset_from,
            # xytext is offset points from "xy=(0.5, 0), xycoords=at"
            va="top",
            ha="center",
            bbox=dict(boxstyle="round", fc="w"))  #box with values 2
Exemplo n.º 2
0
def init_plots(model_names, all_model_state):
    """Return the figure and annotations for the animation.

    """
    fig, axs = plt.subplots(1,
                            len(MODEL_NAMES),
                            figsize=(5 * len(MODEL_NAMES), 5))
    min_value, max_value = -2, 2
    images, model_data, annotes = [], [], []

    for i, ax in enumerate(fig.axes):

        image, info = ALL_MODEL_STATES[i][0]
        images.append(
            ax.imshow(image,
                      vmin=min_value,
                      vmax=max_value,
                      cmap="RdYlGn",
                      interpolation=None))
        ax.axis("off")
        ax.set_title(MODEL_NAMES[i])
        model_data.append(info)
        helper = ax.annotate("",
                             xy=(0.5, 0),
                             xycoords="axes fraction",
                             va="bottom",
                             ha="center")
        offset_from = OffsetFrom(helper, (0.5, 0))
        a = ax.annotate("seat",
                        xy=(0, 0),
                        xycoords="data",
                        xytext=(0, -10),
                        textcoords=offset_from,
                        va="top",
                        ha="center",
                        bbox=dict(boxstyle="round", fc="w"),
                        arrowprops=dict(arrowstyle="->"),
                        alpha=1)
        a.set_visible(False)
        annotes.append(a)

    return fig, images, annotes, model_data
Exemplo n.º 3
0
                    xycoords=("data", 'axes fraction'),
                    xytext=(0, -20),
                    textcoords='offset points',
                    ha="center",
                    va="top",
                    bbox=bbox_args,
                    arrowprops=arrow_args)

ax2.annotate('xy=(0.5, 0)\nxycoords=artist',
             xy=(0.5, 0.),
             xycoords=text,
             xytext=(0, -20),
             textcoords='offset points',
             ha="center",
             va="top",
             bbox=bbox_args,
             arrowprops=arrow_args)

ax2.annotate('xy=(0.8, 0.5)\nxycoords=ax1.transData',
             xy=(0.8, 0.5),
             xycoords=ax1.transData,
             xytext=(10, 10),
             textcoords=OffsetFrom(ax2.bbox, (0, 0), "points"),
             ha="left",
             va="bottom",
             bbox=bbox_args,
             arrowprops=arrow_args)

ax2.set(xlim=[-2, 2], ylim=[-2, 2])
plt.show()
plt.savefig("Annotate_Simple_Coord_b.png")

plt.show()

# source 2 : https://matplotlib.org/devdocs/gallery/userdemo/annotate_simple_coord02.html#sphx-glr-gallery-userdemo-annotate-simple-coord02-py

## =====================================

import matplotlib.pyplot as plt
from matplotlib.text import OffsetFrom


fig, ax = plt.subplots(figsize = (3, 2))
an1 = ax.annotate("Test 1", xy = (0.5, 0.5), xycoords = "data",
                  va = "center", ha = "center",
                  bbox = dict(boxstyle = "round", fc = "w"))

offset_from = OffsetFrom(an1, (0.5, 0))
an2 = ax.annotate("Test 2", xy = (0.1, 0.1), xycoords = "data",
                  xytext = (0, -10), textcoords = offset_from,
                  # xytext is offset points from "xy = (0.5, 0), xycoords = an1"
                  va = "top", ha = "center",
                  bbox = dict(boxstyle = "round", fc = "w"),
                  arrowprops = dict(arrowstyle = "->"))

plt.savefig("Annotate_Simple_Coord_c.png")

plt.show()

# source 3 : https://matplotlib.org/devdocs/gallery/userdemo/annotate_simple_coord03.html#sphx-glr-gallery-userdemo-annotate-simple-coord03-py
Exemplo n.º 5
0
                            shrinkA=5,shrinkB=5,
                            relpos=(1, 1)),
            horizontalalignment='right', verticalalignment='top', multialignment='left',
            fontfamily='Futura LT', fontsize=28, fontweight='bold', color=next_color)

if args.logyscale:
    helpusY=cosur_estimate_arrow_text_y / 2
else:
    helpusY=cosur_estimate_arrow_text_y - (ax.get_ylim()[1]-ax.get_ylim()[0])/10
#ax.annotate(_('help us get more data'),
#            xy=(cosur_estimate_arrow_text_x, helpusY ), xycoords='data',
#            horizontalalignment='left', verticalalignment='top', multialignment='left',
#            fontfamily='Futura LT', fontsize=20, fontweight='normal', color=next_color)


offset_from = OffsetFrom(ancosur, (0, 0))
yoff= args.helpusoff
#print ("yoff=",yoff)
ax.annotate(_('help us get more data'),
            xy=(0, yoff), xycoords=offset_from,
            horizontalalignment='left', verticalalignment='top', multialignment='left',
            fontfamily='Futura LT', fontsize=20, fontweight='normal', color=next_color)




#sns.lineplot(data=df, x='date', y='prop_cases', ax=ax, color=next(new_palette)) #, err_style="bars")

#sns.lineplot(data=df, x='date', y='dunbar_cases', ax=ax) #, err_style="bars")

## Date Limits
Exemplo n.º 6
0
                 ha="center", va="top",
                 bbox=bbox_args,
                 arrowprops=arrow_args
                 )

from matplotlib.text import OffsetFrom

ax2.annotate('xy=(0.5, 0)\nxycoords=artist',
             xy=(0.5, 0.),  xycoords=t,
             xytext=(0, -20), textcoords='offset points',
             ha="center", va="top",
             bbox=bbox_args,
             arrowprops=arrow_args
             )

ax2.annotate('xy=(0.8, 0.5)\nxycoords=ax1.transData',
             xy=(0.8, 0.5),  xycoords=ax1.transData,
             xytext=(10, 10), textcoords=OffsetFrom(ax2.bbox, (0, 0), "points"),
             ha="left", va="bottom",
             bbox=bbox_args,
             arrowprops=arrow_args
             )

ax2.set_xlim(-2, 2)
ax2.set_ylim(-2, 2)

an1.draggable()
an2.draggable()

plt.show()
Exemplo n.º 7
0
def plotmBB(df, df_cut):

    bins = np.linspace(0, 500, 51)

    # Initialise plot stuff
    plt.ion()
    plt.clf()
    plot_range = (0, 500)
    plot_data = []
    plot_weights = []
    plot_colors = []
    plt.rc('font', weight='bold')
    plt.rc('xtick.major', size=5, pad=7)
    plt.rc('xtick', labelsize=10)

    plt.rcParams["font.weight"] = "bold"
    plt.rcParams["axes.labelweight"] = "bold"
    plt.rcParams["mathtext.default"] = "regular"

    df_signal = df.loc[df['Class'] == 1.0]
    df_background = df.loc[df['Class'] == 0.0]

    df_signal_cut = df_cut.loc[df_cut['Class'] == 1.0]
    df_background_cut = df_cut.loc[df_cut['Class'] == 0.0]

    plot_weights_signal = df_signal['post_fit_weight']
    plot_weights_signal = (1 / sum(plot_weights_signal)) * plot_weights_signal
    plot_weights_signal_cut = df_signal_cut['post_fit_weight']
    plot_weights_signal_cut = (
        1 / sum(plot_weights_signal_cut)) * plot_weights_signal_cut

    plot_weights_background = df_background['post_fit_weight']
    plot_weights_background = (
        1 / sum(plot_weights_background)) * plot_weights_background
    plot_weights_background_cut = df_background_cut['post_fit_weight']
    plot_weights_background_cut = (
        1 / sum(plot_weights_background_cut)) * plot_weights_background_cut

    mbb_vals = df['mBB'].tolist()
    for i in range(len(df)):
        if mbb_vals[i] >= 500000:
            mbb_vals[i] = 499500

    df['mBB'] = mbb_vals

    mbb_vals_cut = df_cut['mBB'].tolist()
    for i in range(len(df_cut)):
        if mbb_vals_cut[i] >= 500000:
            mbb_vals_cut[i] = 499500

    df_cut['mBB'] = mbb_vals_cut

    variable_values_signal = df_signal['mBB'] / 1000
    variable_values_background = df_background['mBB'] / 1000
    variable_values_signal_cut = df_signal_cut['mBB'] / 1000
    variable_values_background_cut = df_background_cut['mBB'] / 1000

    if True == False:
        count_sig_cut = plt.hist(
            variable_values_signal_cut,
            bins=bins,
            weights=plot_weights_signal_cut,
            range=plot_range,
            rwidth=1,
            color='#b32400',  #dark red
            label='Signal after cut',
            stacked=False,
            alpha=1,
            #hatch=4*'\\'
        )
    if True != False:
        count_back_cut = plt.hist(
            variable_values_background_cut,
            bins=bins,
            weights=plot_weights_background_cut,
            range=plot_range,
            rwidth=1,
            linewidth=3,
            color='#0066CC',  #dark blue
            label='Background after cut',
            alpha=1,
            #hatch=4*'//'
        )
    if True == False:
        # Plot.
        count_sig = plt.hist(
            variable_values_signal,
            bins=bins,
            weights=plot_weights_signal,
            range=plot_range,
            rwidth=1,
            histtype='step',
            linewidth=3,
            edgecolor='#FF0000',
            #edgecolor='red',
            label='Signal',
            stacked=False,
            alpha=1,
            #hatch=4*'\\'
        )
    if True != False:
        count_back = plt.hist(
            variable_values_background,
            bins=bins,
            weights=plot_weights_background,
            range=plot_range,
            rwidth=1,
            histtype='step',
            linewidth=3,
            edgecolor='#0000b3',
            #edgecolor='blue',
            label='Background',
            alpha=1,
            #hatch=4*'//'
        )

    x1, x2, y1, y2 = plt.axis()
    #plt.yscale('log', nonposy='clip')
    plt.axis((x1, x2, y1, y2 * 1.2))
    axes = plt.gca()
    axes.set_ylim([0, 0.12])
    axes.set_xlim(plot_range)
    x = [-1, -0.8, -0.6, -0.4, -0.2, 0, 0.2, 0.4, 0.6, 0.8, 1]
    #plt.xticks(x, x,fontweight = 'normal',fontsize = 16)
    y = ["10", r"10$^{2}$", r"10$^{3}$", r"10$^{4}$", r"10$^{5}$"]
    yi = [10, 100, 1000, 10000, 100000]
    #plt.yticks(yi, y,fontweight = 'normal',fontsize = 16)
    axes.yaxis.set_ticks_position('both')
    axes.yaxis.set_tick_params(which='both', direction='in')
    axes.xaxis.set_ticks_position('both')
    axes.xaxis.set_tick_params(which='both', direction='in')
    axes.xaxis.set_minor_locator(AutoMinorLocator(4))
    axes.yaxis.set_minor_locator(AutoMinorLocator(4))
    handles, labels = axes.get_legend_handles_labels()
    plt.legend(loc='upper right',
               ncol=1,
               prop={'size': 12},
               frameon=False,
               handles=handles[::-1])
    plt.ylabel('Normalised Number of Events', fontsize=16, fontweight='normal')
    axes.yaxis.set_label_coords(-0.1, 0.5)
    plt.xlabel("$m_{bb}$ [GeV]", fontsize=16, fontweight='normal')
    axes.xaxis.set_label_coords(0.89, -0.07)
    an1 = axes.annotate("ATLAS",
                        xy=(0.05, 0.91),
                        xycoords=axes.transAxes,
                        fontstyle='italic',
                        fontsize=16)

    offset_from = OffsetFrom(an1, (0, -1.4))
    an2 = axes.annotate(r'$\sqrt{s}$' + " = 13 TeV , 36.1 fb$^{-1}$",
                        xy=(0.05, 0.91),
                        xycoords=axes.transAxes,
                        textcoords=offset_from,
                        fontweight='normal',
                        fontsize=12)

    offset_from = OffsetFrom(an2, (0, -1.4))
    an3 = axes.annotate("1 lepton, " + str(nJets) + " jets, 2 b-tags",
                        xy=(0.05, 0.91),
                        xycoords=axes.transAxes,
                        textcoords=offset_from,
                        fontstyle='italic',
                        fontsize=12)

    offset_from = OffsetFrom(an3, (0, -1.6))
    an4 = axes.annotate("p$^V_T \geq$ 150 GeV",
                        xy=(0.05, 0.91),
                        xycoords=axes.transAxes,
                        textcoords=offset_from,
                        fontstyle='italic',
                        fontsize=12)
    plt.show(block=True)
Exemplo n.º 8
0
def bdt_plot(df,z_s = 10,z_b = 10,show=False, block=False, trafoD_bins = False, bin_number = 20):
    """Plots histogram decision score output of classifier"""

    nJets = df['nJ'].tolist()[1]
    df['decision_value'] = ((list(df['decision_value'])-0.5)*2)
    if trafoD_bins == True:
        bins, arg2, arg3 = trafoD_with_error(df)
        print(len(bins))
    else:
         bins = np.linspace(-1,1,bin_number+1)

    # Initialise plot stuff
    plt.ion()
    plt.close("all")
    fig = plt.figure(figsize=(8.5,7))
    plot_range = (-1, 1)
    plot_data = []
    plot_weights = []
    plot_colors = []
    plt.rc('font', weight='bold')
    plt.rc('xtick.major', size=5, pad=7)
    plt.rc('xtick', labelsize=10)

    plt.rcParams["font.weight"] = "bold"
    plt.rcParams["axes.labelweight"] = "bold"
    plt.rcParams["mathtext.default"] = "regular"

    df = setBinCategory(df,bins)

    decision_value_list = df['bin_scaled'].tolist()
    post_fit_weight_list = df['post_fit_weight'].tolist()
    sample_list = df['sample'].tolist()

    # Get list of hists.
    for t in class_names_grouped[::-1]:
        class_names = class_names_map[t]
        class_decision_vals = []
        plot_weight_vals = []
        for c in class_names:
            for x in range(0,len(decision_value_list)):
                if sample_list[x] == c:
                    class_decision_vals.append(decision_value_list[x])
                    plot_weight_vals.append(post_fit_weight_list[x])

        plot_data.append(class_decision_vals)
        plot_weights.append(plot_weight_vals)
        plot_colors.append(colour_map[t])


    #Plots the filled in histogram parts
    plt.hist(plot_data,bins=bins,weights=plot_weights,range=plot_range,rwidth=1,color=plot_colors,label=legend_names[::-1],stacked=True,edgecolor='none')

    #Plots the additional line over the top for signal events
    if nJets == 2:
        multiplier = 20
    elif nJets == 3:
        multiplier = 100

    plt.plot([],[],color='#FF0000',label=r'VH $\rightarrow$ Vbb x '+str(multiplier))

    df_sig = df.loc[df['Class']==1]
    plt.hist(df_sig['bin_scaled'].tolist(),bins=bins,weights=(df_sig['post_fit_weight']*multiplier).tolist(),range=plot_range,rwidth=1,histtype = 'step',linewidth=2,color='#FF0000',edgecolor='#FF0000')

    #sets axis limits and labels
    x1, x2, y1, y2 = plt.axis()
    plt.yscale('log', nonposy='clip')       # can comment out this line if log error stops plotting
    plt.axis((x1, x2, y1, y2 * 1.2))
    axes = plt.gca()
    axes.set_ylim([5,135000])
    axes.set_xlim([-1,1])
    x = [-1,-0.8,-0.6,-0.4,-0.2,0,0.2,0.4,0.6,0.8,1]
    plt.xticks(x, x,fontweight = 'normal',fontsize = 20)
    y = [r"10",r"10$^{2}$",r"10$^{3}$",r"10$^{4}$",r"10$^{5}$"]
    yi = [10,100,1000,10000,100000]
    plt.yticks(yi, y,fontweight = 'normal',fontsize = 20)       # can comment out this line if log error stops plotting

    #sets axis ticks
    axes.yaxis.set_ticks_position('both')
    axes.yaxis.set_tick_params(which='major', direction='in', length=10, width=1)
    axes.yaxis.set_tick_params(which='minor', direction='in', length=5, width=1)
    axes.xaxis.set_ticks_position('both')
    axes.xaxis.set_tick_params(which='major', direction='in', length=10, width=1)
    axes.xaxis.set_tick_params(which='minor', direction='in', length=5, width=1)
    axes.xaxis.set_minor_locator(AutoMinorLocator(4))
    handles, labels = axes.get_legend_handles_labels()

    #hack thing to get legend entries in correct order
    handles = handles[::-1]
    handles = handles+handles
    handles = handles[1:12]

    plt.legend(loc='upper right', ncol=1, prop={'size': 12},frameon=False,handles=handles)

    #axis titles and lables
    plt.ylabel("Events",fontsize = 20,fontweight='normal')
    axes.yaxis.set_label_coords(-0.07,0.93)
    plt.xlabel(r"BDT$_{VH}$ output",fontsize = 20,fontweight='normal')
    axes.xaxis.set_label_coords(0.89, -0.07)
    an1 = axes.annotate("ATLAS Internal", xy=(0.05, 0.91), xycoords=axes.transAxes,fontstyle = 'italic',fontsize = 16)
    offset_from = OffsetFrom(an1, (0, -1.4))
    an2 = axes.annotate(r'$\sqrt{s}$' + " = 13 TeV , 36.1 fb$^{-1}$", xy=(0.05,0.91), xycoords=axes.transAxes, textcoords=offset_from, fontweight='normal',fontsize = 12)
    offset_from = OffsetFrom(an2, (0, -1.4))
    an3 = axes.annotate("1 lepton, "+str(nJets)+" jets, 2 b-tags", xy=(0.05,0.91), xycoords=axes.transAxes, textcoords=offset_from,fontstyle = 'italic',fontsize = 12)
    offset_from = OffsetFrom(an3, (0, -1.6))
    an4 = axes.annotate("p$^V_T \geq$ 150 GeV", xy=(0.05,0.91), xycoords=axes.transAxes, textcoords=offset_from,fontstyle = 'italic',fontsize = 12)

    plt.show(block=block)

    return fig,axes
Exemplo n.º 9
0
    def plot(self, fig, ax, interactive=False, state=-1):
        """Using matplotlib to draw the current state of the model.

        Args:
            fig: the pyplot figure.
            ax: the axes to draw the plot.
            interactive: whether to handle mouse events.
            state: which model state to use. -1 can be used to show last state.

        """
        try:
            image, info = self.model_states[state]
        except:
            image, info = self.get_model_state()

        ax.clear()

        self.im = ax.imshow(image,
                            vmin=-2,
                            vmax=2,
                            cmap='RdYlGn',
                            interpolation=None)

        ax.axis('off')

        if state < 0:
            num_students = len(self.students) + state + 1
        else:
            num_students = min(state, len(self.students))
        ax.set_title('Classroom State ({} students)'.format(num_students))

        helper = ax.annotate("",
                             xy=(0.5, 0),
                             xycoords="axes fraction",
                             va="bottom",
                             ha="center")
        offset_from = OffsetFrom(helper, (0.5, 0))
        a = ax.annotate("seat",
                        xy=(0, 0),
                        xycoords="data",
                        xytext=(0, -10),
                        textcoords=offset_from,
                        va="top",
                        ha="center",
                        bbox=dict(boxstyle="round", fc="w"),
                        arrowprops=dict(arrowstyle="->"),
                        alpha=1)
        a.set_visible(False)

        def hover(event):
            if (event.inaxes):
                x, y = int(np.round(event.xdata)), int(np.round(event.ydata))
                value = self.im.get_array()[y][x]
                seat_utility, student_id, sociability, initial_happiness = (
                    info[y, x])

                text = ""
                if value == -0.8:
                    text = "AISLE"
                elif value == -3:
                    text = "DOOR"
                elif value <= -1:
                    text = "EMPTY SEAT\nSeat attractivness: {:.2f}\nAccessibility: {:.2f}".format(
                        seat_utility, value + 2)
                elif value >= 0:
                    text = "FILLED SEAT\n {} {:.2f} \n {} {:.2f} \n {} {:.2f} \n {} {:.2f}".format(
                        "Seat attractivness:", seat_utility,
                        "Student sociability:", sociability,
                        "Initial happiness (t = {}):".format(int(student_id)),
                        initial_happiness, "Current happiness:", value - 1)

                a.set_text(text)
                a.xy = (x, y)
                a.set_visible(True)
                fig.canvas.draw_idle()

            else:
                a.set_visible(False)
                fig.canvas.draw_idle()

        ax.set_xticks(np.arange(-0.5, image.shape[1]), minor=True)
        ax.set_yticks(np.arange(-0.5, image.shape[0]), minor=True)
        ax.grid(which='minor', color='k', linestyle='-', linewidth=2)

        if interactive:
            cid = fig.canvas.mpl_connect('motion_notify_event', hover)

        fig.tight_layout(rect=[0, 0.2, 1, 1])
Exemplo n.º 10
0
def crossquiverkey(QV, **kwargs):
    u"""
    鉛直ベクトルプロットのrefference arrowを描く

    :Arguments:
     **QV**
     
    **Keyword**
     独自キーワード
         
     =============== =========== ======================================================
     Value           Default     Description
     =============== =========== ======================================================
     data_scale
     zscale          QV.zscale   水平成分に対する鉛直成分スケール比
     dot_scale       30
     uvunit                      水平成分のreferrence arrowにつける単位
     wunit                       鉛直成分のreferrence arrowにつける単位
     =============== =========== ======================================================

     デフォルトを独自に設定しているキーワード
         
     =============== ======= ======================================================
     Value           Default Description
     =============== ======= ======================================================
     
     =============== ======= ======================================================
    """
    from matplotlib.text import OffsetFrom
    ax = kwargs.pop('ax', plt.gca())
    uvunit = kwargs.pop('uvunit', '')
    wunit = kwargs.pop('wunit', '')
    dot_scale = kwargs.pop('dot_scale', 30)

    ## Refference Allowの長さ (データ単位)
    data_scale = kwargs.pop('data_scale', None)
    zscale = kwargs.pop('zscale', None)
    if zscale == None: zscale = getattr(QV, 'zscale', 1)
    if data_scale == None:
        data_scale = getattr(
            QV, 'data_scale',
            tools.roundoff(np.hypot(QV.U, QV.V).max(), digit=1))

    offset_from = OffsetFrom(ax, (0.95, 1))
    uvlabel = '%.1f %s' % (data_scale, uvunit)
    wlabel = '%.1f %s' % (data_scale / zscale, wunit)
    ax.annotate('',
                xy=(0, 5),
                xycoords=offset_from,
                xytext=(-dot_scale, dot_scale + 5),
                textcoords=offset_from,
                ha='right',
                va='bottom',
                arrowprops=dict(arrowstyle='<->',
                                connectionstyle='angle,rad=0'))
    ax.annotate(uvlabel,
                xy=(1, 1),
                xycoords='axes fraction',
                xytext=(3, 5),
                textcoords='offset points',
                ha='right',
                va='bottom')
    ax.annotate(wlabel,
                xy=(0, 5),
                xycoords=offset_from,
                xytext=(-dot_scale * 0.8, dot_scale * 0.8),
                textcoords=offset_from,
                ha='left',
                va='bottom')