Beispiel #1
0
def add_legend(ax, label, color='red', start=270):
    x = lon1
    y = lat1
    if label == "SUOMIVIIRS":
        start = start + 110
        tmp = 42
    elif label == "MODIS":
        tmp = 30
    else:
        start = start + 50
        tmp = 36
    da = DrawingArea(10, 10, 0, 0)
    p = Circle((5, 5), 5, color=color)
    da.add_artist(p)
    ab = AnnotationBbox(
        da,
        xy=(x, y),
        xybox=(start, -14),
        xycoords='data',
        boxcoords="offset points",
        frameon=False,
        # boxcoords=("axes fraction", "data"),
        box_alignment=(0., 0.5))
    ax.add_artist(ab)

    offsetbox = TextArea(label, minimumdescent=False)
    ab = AnnotationBbox(offsetbox,
                        xy=(x, y),
                        xybox=(start + tmp, -16),
                        xycoords='data',
                        boxcoords="offset points",
                        frameon=False,
                        fontsize=FONTSIZE)
    ax.add_artist(ab)
Beispiel #2
0
def hbar(plot,
         p,
         values,
         colors=None,
         height=16,
         xoff=0,
         yoff=0,
         halign=1,
         valign=0.5,
         xycoords='data',
         boxcoords=('offset points')):
    x, y = _xy(plot, p)
    h = height
    w = sum(values) * height  #; yoff=h*0.5
    da = DrawingArea(w, h)
    x0 = -sum(values)
    if not colors:
        c = _colors.tango()
        colors = [c.next() for v in values]
    for i, v in enumerate(values):
        if v:
            da.add_artist(Rectangle((x0, 0), v * h, h, fc=colors[i],
                                    ec='none'))
        x0 += v * h
    box = AnnotationBbox(da, (x, y),
                         pad=0,
                         frameon=False,
                         xybox=(xoff, yoff),
                         xycoords=xycoords,
                         box_alignment=(halign, valign),
                         boxcoords=boxcoords)
    plot.add_artist(box)
    plot.figure.canvas.draw_idle()
Beispiel #3
0
def test_offsetbox_clipping():
    # - create a plot
    # - put an AnchoredOffsetbox with a child DrawingArea
    #   at the center of the axes
    # - give the DrawingArea a gray background
    # - put a black line across the bounds of the DrawingArea
    # - see that the black line is clipped to the edges of
    #   the DrawingArea.
    fig, ax = plt.subplots()
    size = 100
    da = DrawingArea(size, size, clip=True)
    bg = mpatches.Rectangle((0, 0),
                            size,
                            size,
                            facecolor='#CCCCCC',
                            edgecolor='None',
                            linewidth=0)
    line = mlines.Line2D([-size * .5, size * 1.5], [size / 2, size / 2],
                         color='black',
                         linewidth=10)
    anchored_box = AnchoredOffsetbox(loc=10,
                                     child=da,
                                     pad=0.,
                                     frameon=False,
                                     bbox_to_anchor=(.5, .5),
                                     bbox_transform=ax.transAxes,
                                     borderpad=0.)

    da.add_artist(bg)
    da.add_artist(line)
    ax.add_artist(anchored_box)
    ax.set_xlim((0, 1))
    ax.set_ylim((0, 1))
Beispiel #4
0
def test_offsetbox_clip_children():
    # - create a plot
    # - put an AnchoredOffsetbox with a child DrawingArea
    #   at the center of the axes
    # - give the DrawingArea a gray background
    # - put a black line across the bounds of the DrawingArea
    # - see that the black line is clipped to the edges of
    #   the DrawingArea.
    fig, ax = plt.subplots()
    size = 100
    da = DrawingArea(size, size, clip=True)
    bg = mpatches.Rectangle((0, 0), size, size,
                            facecolor='#CCCCCC',
                            edgecolor='None',
                            linewidth=0)
    line = mlines.Line2D([-size*.5, size*1.5], [size/2, size/2],
                         color='black',
                         linewidth=10)
    anchored_box = AnchoredOffsetbox(
        loc=10,
        child=da,
        pad=0.,
        frameon=False,
        bbox_to_anchor=(.5, .5),
        bbox_transform=ax.transAxes,
        borderpad=0.)

    da.add_artist(bg)
    da.add_artist(line)
    ax.add_artist(anchored_box)

    fig.canvas.draw()
    assert not fig.stale
    da.clip_children = True
    assert fig.stale
Beispiel #5
0
def add_offsetboxes(ax, size=10, margin=.1, color='black'):
    """
    Surround ax with OffsetBoxes
    """
    m, mp = margin, 1+margin
    anchor_points = [(-m, -m), (-m, .5), (-m, mp),
                     (mp, .5), (.5, mp), (mp, mp),
                     (.5, -m), (mp, -m), (.5, -m)]
    for point in anchor_points:
        da = DrawingArea(size, size)
        background = Rectangle((0, 0), width=size,
                               height=size,
                               facecolor=color,
                               edgecolor='None',
                               linewidth=0,
                               antialiased=False)
        da.add_artist(background)

        anchored_box = AnchoredOffsetbox(
            loc='center',
            child=da,
            pad=0.,
            frameon=False,
            bbox_to_anchor=point,
            bbox_transform=ax.transAxes,
            borderpad=0.)
        ax.add_artist(anchored_box)
    return anchored_box
Beispiel #6
0
def make_rect(color, alpha, size=(20, 6), height=20):
    color = color if color != None else "k"  # Default value if None
    viz = DrawingArea(30, height, 0, 1)
    viz.add_artist(
        Rectangle((0, 6), width=size[0], height=size[1], alpha=alpha,
                  fc=color))
    return viz
Beispiel #7
0
def add_offsetboxes(ax, size=10, margin=.1, color='black'):
    """
    Surround ax with OffsetBoxes
    """
    m, mp = margin, 1 + margin
    anchor_points = [(-m, -m), (-m, .5), (-m, mp), (mp, .5), (.5, mp),
                     (mp, mp), (.5, -m), (mp, -m), (.5, -m)]
    for point in anchor_points:
        da = DrawingArea(size, size)
        background = Rectangle((0, 0),
                               width=size,
                               height=size,
                               facecolor=color,
                               edgecolor='None',
                               linewidth=0,
                               antialiased=False)
        da.add_artist(background)

        anchored_box = AnchoredOffsetbox(loc='center',
                                         child=da,
                                         pad=0.,
                                         frameon=False,
                                         bbox_to_anchor=point,
                                         bbox_transform=ax.transAxes,
                                         borderpad=0.)
        ax.add_artist(anchored_box)
    return anchored_box
Beispiel #8
0
def pie(
    plot,
    p,
    values,
    colors=None,
    size=16,
    norm=True,
    xoff=0,
    yoff=0,
    halign=0.5,
    valign=0.5,
    xycoords="data",
    boxcoords=("offset points"),
):
    """
    Draw a pie chart

    Args:
    plot (Tree): A Tree plot instance
    p (Node): A Node object
    values (list): A list of floats.
    colors (list): A list of strings to pull colors from. Optional.
    size (float): Diameter of the pie chart
    norm (bool): Whether or not to normalize the values so they
      add up to 360
    xoff, yoff (float): X and Y offset. Optional, defaults to 0
    halign, valign (float): Horizontal and vertical alignment within
      box. Optional, defaults to 0.5

    """
    x, y = _xy(plot, p)
    da = DrawingArea(size, size)
    r = size * 0.5
    center = (r, r)
    x0 = 0
    S = 360.0
    if norm:
        S = 360.0 / sum(values)
    if not colors:
        c = _colors.tango()
        colors = [c.next() for v in values]
    for i, v in enumerate(values):
        theta = v * S
        if v:
            da.add_artist(Wedge(center, r, x0, x0 + theta, fc=colors[i], ec="none"))
        x0 += theta
    box = AnnotationBbox(
        da,
        (x, y),
        pad=0,
        frameon=False,
        xybox=(xoff, yoff),
        xycoords=xycoords,
        box_alignment=(halign, valign),
        boxcoords=boxcoords,
    )
    plot.add_artist(box)
    plot.figure.canvas.draw_idle()
    return box
Beispiel #9
0
def make_gui(img, dataset_name, **kwargs):
    global alphabet
    fig = plt.figure(figsize=kwargs["figsize"])
    from matplotlib import rcParams
    rcParams['axes.linewidth'] = 2
    rcParams['axes.edgecolor'] = 'k'

    plt.imshow(img)

    label_category = cv_label_category if dataset_name == "camvid" else voc_label_category
    alphabet = alphabet_cv if dataset_name == "camvid" else alphabet_voc

    vpacker_children = [TextArea("{} - {}".format(alphabet[l], cat), textprops={"weight": 'bold', "size": 10})
                        for l, cat in sorted(label_category.items(), key=lambda x: x[1])]
    box = VPacker(children=vpacker_children, align="left", pad=5, sep=5)

    # display the texts on the right side of image
    anchored_box = AnchoredOffsetbox(loc="center left",
                                     child=box,
                                     pad=0.,
                                     frameon=True,
                                     bbox_to_anchor=(1.04, 0.5),
                                     bbox_transform=plt.gca().transAxes,
                                     borderpad=0.)
    anchored_box.patch.set_linewidth(2)
    anchored_box.patch.set_facecolor('gray')
    anchored_box.patch.set_alpha(0.2)

    anchored_box.patch.set_boxstyle("round,pad=0.5, rounding_size=0.2")
    plt.gca().add_artist(anchored_box)

    # create texts for "Enter a label for the current marker"
    box1 = TextArea("Enter a label for the current marker",
                    textprops={"weight": 'bold', "size": 12})
    box2 = DrawingArea(5, 10, 0, 0)
    box2.add_artist(mpatches.Circle((5, 5), radius=5, fc=np.array((1, 0, 0)), edgecolor="k", lw=1.5))
    box = HPacker(children=[box1, box2], align="center", pad=5, sep=5)

    # anchored_box creates the text box outside of the plot
    anchored_box = AnchoredOffsetbox(loc="lower center",
                                     child=box,
                                     pad=0.,
                                     frameon=False,
                                     bbox_to_anchor=(0.5, -0.1),  # ( 0.5, -0.1)
                                     bbox_transform=plt.gca().transAxes,
                                     borderpad=0.)
    plt.gca().add_artist(anchored_box)
    plt.xticks([])
    plt.yticks([])
    plt.tight_layout(pad=2)

    buf = io.BytesIO()
    fig.savefig(buf, format="jpg", dpi=80)
    buf.seek(0)
    img_arr = np.frombuffer(buf.getvalue(), dtype=np.uint8)
    buf.close()
    im = cv2.imdecode(img_arr, 1)
    plt.close()
    return im
Beispiel #10
0
def draw_circles(ax):
    """Draw circles in axes coordinates."""
    area = DrawingArea(40, 20, 0, 0)
    area.add_artist(Circle((10, 10), 10, fc="tab:blue"))
    area.add_artist(Circle((30, 10), 5, fc="tab:red"))
    box = AnchoredOffsetbox(
        child=area, loc="upper right", pad=0, frameon=False)
    ax.add_artist(box)
Beispiel #11
0
def make_shape(color, shape, size, alpha, y_offset = 10, height = 20):
    color = color if color != None else "k" # Default value if None
    shape = shape if shape != None else "o"
    size = size*0.6+45 if size != None else 75
    viz = DrawingArea(30, height, 8, 1)
    key = mlines.Line2D([0], [y_offset], marker=shape, markersize=size/12.0,
                        mec=color, c=color, alpha=alpha)
    viz.add_artist(key)
    return viz
Beispiel #12
0
def make_line_key(label, color):
    label = str(label)
    idx = len(label)
    pad = 20 - idx
    lab = label[:max(idx, 20)]
    pad = " "*pad
    label = TextArea("  %s" % lab, textprops=dict(color="k"))
    viz = DrawingArea(20, 20, 0, 0)
    viz.add_artist(Rectangle((0, 5), width=16, height=5, fc=color))
    return HPacker(children=[viz, label], height=25, align="center", pad=5, sep=0)
Beispiel #13
0
def make_line(color, style, alpha, width = 20,
              y_offset = 10, height = 20, linewidth = 3):
    color = color if color != None else "k" # Default value if None
    style = style if style != None else "-"
    viz = DrawingArea(30, 10, 0, -5)
    x = np.arange(0.0, width, width/7.0)
    y = np.repeat(y_offset, x.size)
    key = mlines.Line2D(x, y, linestyle=style, linewidth=linewidth,
                        alpha=alpha, c=color)
    viz.add_artist(key)
    return viz
Beispiel #14
0
def pie(plot,
        p,
        values,
        colors=None,
        size=16,
        norm=True,
        xoff=0,
        yoff=0,
        halign=0.5,
        valign=0.5,
        xycoords='data',
        boxcoords=('offset points')):
    """
    Draw a pie chart

    Args:
    plot (Tree): A Tree plot instance
    p (Node): A Node object
    values (list): A list of floats.
    colors (list): A list of strings to pull colors from. Optional.
    size (float): Diameter of the pie chart
    norm (bool): Whether or not to normalize the values so they
      add up to 360
    xoff, yoff (float): X and Y offset. Optional, defaults to 0
    halign, valign (float): Horizontal and vertical alignment within
      box. Optional, defaults to 0.5

    """
    x, y = _xy(plot, p)
    da = DrawingArea(size, size)
    r = size * 0.5
    center = (r, r)
    x0 = 0
    S = 360.0
    if norm: S = 360.0 / sum(values)
    if not colors:
        c = _colors.tango()
        colors = [c.next() for v in values]
    for i, v in enumerate(values):
        theta = v * S
        if v:
            da.add_artist(
                Wedge(center, r, x0, x0 + theta, fc=colors[i], ec='none'))
        x0 += theta
    box = AnnotationBbox(da, (x, y),
                         pad=0,
                         frameon=False,
                         xybox=(xoff, yoff),
                         xycoords=xycoords,
                         box_alignment=(halign, valign),
                         boxcoords=boxcoords)
    plot.add_artist(box)
    plot.figure.canvas.draw_idle()
    return box
Beispiel #15
0
def add_faces_to_scatterplot(ax, X, filenames, dataset, img_size, C=None, border_size=3):
    nx, ny = (16, 10)
    x = np.linspace(X[:, 0].min(), X[:, 0].max(), nx)
    y = np.linspace(X[:, 1].min(), X[:, 1].max(), ny)
    xx,yy = np.meshgrid(x, y)
    coords =  np.hstack([xx.reshape(-1,1), yy.reshape(-1,1)])
    from sklearn.neighbors import NearestNeighbors
    nn = NearestNeighbors().fit(X)

    max_dist = np.abs(X[:, 0].min() - X[:, 0].max()) / nx

    faces_to_draw = []
    for coord in coords:
        dists, nbs = nn.kneighbors(np.atleast_2d(coord))
        if dists[0][0] < max_dist/2:
            faces_to_draw.append(nbs[0][0])

    # for nImg, img_file in enumerate(filenames):
        # if (nImg % every_n_img) != 0:
        #     continue
    for nImg, img_file in enumerate(filenames):
        if nImg not in faces_to_draw:
            continue

        arr_img = dataset.get_face(img_file, size=(img_size,img_size))[0]

        if C is not None:
            print(nImg, affectnet.AffectNet.classes[C[nImg]])
            da = DrawingArea(img_size+2*border_size, img_size+2*border_size, 0, 0)
            p = Rectangle((0, 0), img_size + 2 * border_size, img_size + 2 * border_size, color=AffectNet.colors[C[nImg]])
            da.add_artist(p)
            border = AnnotationBbox(da, X[nImg][::],
                                #xybox=(120., -80.),
                                xybox=(0., 0.),
                                xycoords='data',
                                boxcoords="offset points",
                                pad=0.0,
                                arrowprops=dict(arrowstyle="->",
                                                connectionstyle="angle,angleA=0,angleB=90,rad=3")
                                )
            ax.add_artist(border)

        im = OffsetImage(arr_img, interpolation='gaussian')
        ab = AnnotationBbox(im, X[nImg][::],
                            #xybox=(120., -80.),
                            xybox=(0., 0.),
                            xycoords='data',
                            boxcoords="offset points",
                            pad=0.0,
                            arrowprops=dict(arrowstyle="->",
                                            connectionstyle="angle,angleA=0,angleB=90,rad=3"),
                            )
        ax.add_artist(ab)
Beispiel #16
0
def make_marker_key(label, marker):
    idx = len(label)
    pad = 20 - idx
    lab = label[:max(idx, 20)]
    pad = " "*pad
    label = TextArea("  %s" % lab, textprops=dict(color="k"))
    viz = DrawingArea(15, 20, 0, 0)
    fontsize = 10
    key = mlines.Line2D([0.5*fontsize], [0.75*fontsize], marker=marker,
                               markersize=(0.5*fontsize), c="k")
    viz.add_artist(key)
    return HPacker(children=[viz, label], align="center", pad=5, sep=0)
Beispiel #17
0
def make_shape(color, shape, size, alpha, y_offset=10, height=20):
    color = color if color != None else "k"  # Default value if None
    shape = shape if shape != None else "o"
    size = size * 0.6 + 45 if size != None else 75
    viz = DrawingArea(30, height, 8, 1)
    key = mlines.Line2D([0], [y_offset],
                        marker=shape,
                        markersize=size / 12.0,
                        mec=color,
                        c=color,
                        alpha=alpha)
    viz.add_artist(key)
    return viz
Beispiel #18
0
def make_linestyle_key(label, style):
    idx = len(label)
    pad = 20 - idx
    lab = label[:max(idx, 20)]
    pad = " "*pad
    label = TextArea("  %s" % lab, textprops=dict(color="k"))
    viz = DrawingArea(30, 20, 0, 0)
    fontsize = 10
    x = np.arange(0.5, 2.25, 0.25) * fontsize
    y = np.repeat(0.75, 7) * fontsize

    key = mlines.Line2D(x, y, linestyle=style, c="k")
    viz.add_artist(key)
    return HPacker(children=[viz, label], align="center", pad=5, sep=0)
Beispiel #19
0
def make_marker_key(label, marker):
    idx = len(label)
    pad = 20 - idx
    lab = label[:max(idx, 20)]
    pad = " " * pad
    label = TextArea(": %s" % lab, textprops=dict(color="k"))
    viz = DrawingArea(15, 20, 0, 0)
    fontsize = 10
    key = mlines.Line2D([0.5 * fontsize], [0.75 * fontsize],
                        marker=marker,
                        markersize=(0.5 * fontsize),
                        c="k")
    viz.add_artist(key)
    return HPacker(children=[viz, label], align="center", pad=5, sep=0)
Beispiel #20
0
def make_line_key(label, color):
    label = str(label)
    idx = len(label)
    pad = 20 - idx
    lab = label[:max(idx, 20)]
    pad = " " * pad
    label = TextArea(": %s" % lab, textprops=dict(color="k"))
    viz = DrawingArea(20, 20, 0, 0)
    viz.add_artist(Rectangle((0, 5), width=16, height=5, fc=color))
    return HPacker(children=[viz, label],
                   height=25,
                   align="center",
                   pad=5,
                   sep=0)
Beispiel #21
0
def make_size_key(label, size):
    label = round(label, 2)
    label = str(label)
    idx = len(label)
    pad = 20 - idx
    lab = label[:max(idx, 20)]
    pad = " "*pad
    label = TextArea(": %s" % lab, textprops=dict(color="k"))
    viz = DrawingArea(15, 20, 0, 0)
    fontsize = 10
    key = mlines.Line2D([0.5*fontsize], [0.75*fontsize], marker="o", 
                               markersize=size / 20., c="k")
    viz.add_artist(key)
    return HPacker(children=[viz, label], align="center", pad=5, sep=0)
Beispiel #22
0
def make_linestyle_key(label, style):
    idx = len(label)
    pad = 20 - idx
    lab = label[:max(idx, 20)]
    pad = " " * pad
    label = TextArea(": %s" % lab, textprops=dict(color="k"))
    viz = DrawingArea(30, 20, 0, 0)
    fontsize = 10
    x = np.arange(0.5, 2.25, 0.25) * fontsize
    y = np.repeat(0.75, 7) * fontsize

    key = mlines.Line2D(x, y, linestyle=style, c="k")
    viz.add_artist(key)
    return HPacker(children=[viz, label], align="center", pad=5, sep=0)
Beispiel #23
0
def test_picking(child_type, boxcoords):
    # These all take up approximately the same area.
    if child_type == 'draw':
        picking_child = DrawingArea(5, 5)
        picking_child.add_artist(mpatches.Rectangle((0, 0), 5, 5, linewidth=0))
    elif child_type == 'image':
        im = np.ones((5, 5))
        im[2, 2] = 0
        picking_child = OffsetImage(im)
    elif child_type == 'text':
        picking_child = TextArea('\N{Black Square}', textprops={'fontsize': 5})
    else:
        assert False, f'Unknown picking child type {child_type}'

    fig, ax = plt.subplots()
    ab = AnnotationBbox(picking_child, (0.5, 0.5), boxcoords=boxcoords)
    ab.set_picker(True)
    ax.add_artist(ab)

    calls = []
    fig.canvas.mpl_connect('pick_event', lambda event: calls.append(event))

    # Annotation should be picked by an event occurring at its center.
    if boxcoords == 'axes points':
        x, y = ax.transAxes.transform_point((0, 0))
        x += 0.5 * fig.dpi / 72
        y += 0.5 * fig.dpi / 72
    elif boxcoords == 'axes pixels':
        x, y = ax.transAxes.transform_point((0, 0))
        x += 0.5
        y += 0.5
    else:
        x, y = ax.transAxes.transform_point((0.5, 0.5))
    fig.canvas.draw()
    calls.clear()
    fig.canvas.button_press_event(x, y, MouseButton.LEFT)
    assert len(calls) == 1 and calls[0].artist == ab

    # Annotation should *not* be picked by an event at its original center
    # point when the limits have changed enough to hide the *xy* point.
    ax.set_xlim(-1, 0)
    ax.set_ylim(-1, 0)
    fig.canvas.draw()
    calls.clear()
    fig.canvas.button_press_event(x, y, MouseButton.LEFT)
    assert len(calls) == 0
Beispiel #24
0
def make_size_key(label, size):
    if not isinstance(label, six.string_types):
        label = round(label, 2)
        label = str(label)
    idx = len(label)
    pad = 20 - idx
    lab = label[:max(idx, 20)]
    pad = " " * pad
    label = TextArea("  %s" % lab, textprops=dict(color="k"))
    viz = DrawingArea(15, 20, 0, 0)
    fontsize = 10
    key = mlines.Line2D([0.5 * fontsize], [0.75 * fontsize],
                        marker="o",
                        markersize=size / 20.,
                        c="k")
    viz.add_artist(key)
    return HPacker(children=[viz, label], align="center", pad=5, sep=0)
Beispiel #25
0
    def createBall(self, colour):

        radius = 2
        da = DrawingArea(radius, radius, 10, 10)
        circle = patches.Circle((0.0, 0.0),
                                radius=radius,
                                edgecolor='k',
                                facecolor=colour,
                                fill=True,
                                ls='solid',
                                clip_on=False)
        da.add_artist(circle)
        ab = AnnotationBbox(da,
                            xy=(0, 0),
                            xycoords=("data", "data"),
                            boxcoords=("data", "data"),
                            box_alignment=(5.0, 5.0),
                            frameon=False)

        return ab
Beispiel #26
0
def make_line(color,
              style,
              alpha,
              width=20,
              y_offset=10,
              height=20,
              linewidth=3):
    color = color if color != None else "k"  # Default value if None
    style = style if style != None else "-"
    viz = DrawingArea(30, 10, 0, -5)
    x = np.arange(0.0, width, width / 7.0)
    y = np.repeat(y_offset, x.size)
    key = mlines.Line2D(x,
                        y,
                        linestyle=style,
                        linewidth=linewidth,
                        alpha=alpha,
                        c=color)
    viz.add_artist(key)
    return viz
Beispiel #27
0
def hbar(plot, p, values, colors=None, height=16,
         xoff=0, yoff=0,
         halign=1, valign=0.5,
         xycoords='data', boxcoords=('offset points')):
    x, y = _xy(plot, p)
    h = height; w = sum(values) * height#; yoff=h*0.5
    da = DrawingArea(w, h)
    x0 = -sum(values)
    if not colors:
        c = _colors.tango()
        colors = [ c.next() for v in values ]
    for i, v in enumerate(values):
        if v: da.add_artist(Rectangle((x0,0), v*h, h, fc=colors[i], ec='none'))
        x0 += v*h
    box = AnnotationBbox(da, (x,y), pad=0, frameon=False,
                         xybox=(xoff, yoff),
                         xycoords=xycoords,
                         box_alignment=(halign,valign),
                         boxcoords=boxcoords)
    plot.add_artist(box)
    plot.figure.canvas.draw_idle()
Beispiel #28
0
def tipsquares(plot, p, colors="r", size=15, pad=2, edgepad=10):
    """
    RR: Bug with this function. If you attempt to call it with a list as an
    argument for p, it will not only not work (expected) but it will also
    make it so that you can't interact with the tree figure (gives errors when
    you try to add symbols, select nodes, etc.) -CZ

    Add square after tip label, anchored to the side of the plot

    Args:
        plot (Tree): A Tree plot instance.
        p (Node): A Node object (Should be a leaf node).
        colors (str): olor of drawn square. Optional, defaults to 'r' (red)
        size (float): Size of square. Optional, defaults to 15
        pad: RR: I am unsure what this does. Does not seem to have visible
          effect when I change it. -CZ
        edgepad (float): Padding from square to edge of plot. Optional,
          defaults to 10.

    """
    x, y = _xy(plot, p)  # p is a single node or point in data coordinates
    n = len(colors)
    da = DrawingArea(size * n + pad * (n - 1), size, 0, 0)
    sx = 0
    for c in colors:
        sq = Rectangle((sx, 0), size, size, color=c)
        da.add_artist(sq)
        sx += size + pad
    box = AnnotationBbox(
        da,
        (x, y),
        xybox=(-edgepad, y),
        frameon=False,
        pad=0.0,
        xycoords="data",
        box_alignment=(1, 0.5),
        boxcoords=("axes points", "data"),
    )
    plot.add_artist(box)
    plot.figure.canvas.draw_idle()
Beispiel #29
0
def tipsquares(plot, p, colors='r', size=15, pad=2, edgepad=10):
    """
    RR: Bug with this function. If you attempt to call it with a list as an
    argument for p, it will not only not work (expected) but it will also
    make it so that you can't interact with the tree figure (gives errors when
    you try to add symbols, select nodes, etc.) -CZ

    Add square after tip label, anchored to the side of the plot

    Args:
        plot (Tree): A Tree plot instance.
        p (Node): A Node object (Should be a leaf node).
        colors (str): color of drawn square. Optional, defaults to 'r' (red)
        size (float): Size of square. Optional, defaults to 15
        pad: RR: I am unsure what this does. Does not seem to have visible
          effect when I change it. -CZ
        edgepad (float): Padding from square to edge of plot. Optional,
          defaults to 10.

    """
    x, y = _xy(plot, p)  # p is a single node or point in data coordinates
    n = len(colors)
    da = DrawingArea(size * n + pad * (n - 1), size, 0, 0)
    sx = 0
    for c in colors:
        sq = Rectangle((sx, 0), size, size, color=c)
        da.add_artist(sq)
        sx += size + pad
    box = AnnotationBbox(da, (x, y),
                         xybox=(-edgepad, y),
                         frameon=False,
                         pad=0.0,
                         xycoords='data',
                         box_alignment=(1, 0.5),
                         boxcoords=('axes points', 'data'))
    plot.add_artist(box)
    plot.figure.canvas.draw_idle()
    def plot_rectangle(self, figure, axis):
        '''
        plots the legend rectangle above the left corner of the figure
        :param figure: figure on which to add the label
        :param axis: axis on which to add the label
        :return: -
        '''

        box1 = TextArea(" True: \n False: \n NaN: ",
                        textprops=dict(color="k", size=10))

        # box2 = DrawingArea(20, 27.5, 0, 0)
        # el1 = Rectangle((5, 15), width=10, height=10, angle=0, fc="g")
        # el2 = Rectangle((5, 2.5), width=10, height=10, angle=0, fc="r")
        box2 = DrawingArea(20, 45, 0, 0)
        el1 = Rectangle((5, 30), width=10, height=10, angle=0, fc="g")
        el2 = Rectangle((5, 18.5), width=10, height=10, angle=0, fc="r")
        el3 = Rectangle((5, 7), width=10, height=10, angle=0, fc='#d3d3d3')
        box2.add_artist(el1)
        box2.add_artist(el2)
        box2.add_artist(el3)

        box = HPacker(children=[box1, box2], align="center", pad=0, sep=5)

        anchored_box = AnchoredOffsetbox(
            loc=3,
            child=box,
            pad=0.,
            frameon=True,
            bbox_to_anchor=(0., 1.02),
            bbox_transform=axis.transAxes,
            borderpad=0.,
        )

        axis.add_artist(anchored_box)
        figure.subplots_adjust(top=0.8)
Beispiel #31
0
def draw_matching(match, nbMen, nbWomen):
  width, height = 25, 50
  da = DrawingArea(width, height)
  coordM = [(  width/4, height*(nbMen-i)/(nbMen+1))     for i in range(nbMen)]
  coordW = [(3*width/4, height*(nbWomen-i)/(nbWomen+1)) for i in range(nbWomen)]
  for idWoman in range(nbWomen):
    if match[idWoman] == -1:
      xdata = [coordW[idWoman][0]]
      ydata = [coordW[idWoman][1]]
      da.add_artist(Line2D(xdata, ydata, marker="."))
  for idMan in range(nbMen):
    if idMan not in match:
      xdata = [coordM[idMan][0]]
      ydata = [coordM[idMan][1]]
      da.add_artist(Line2D(xdata, ydata, marker="."))
  for idWoman,idMan in enumerate(match):
    if idMan != -1:
      xdata = [coordM[idMan][0], coordW[idWoman][0]]
      ydata = [coordM[idMan][1], coordW[idWoman][1]]
      da.add_artist(Line2D(xdata, ydata, marker="."))
  return da
Beispiel #32
0
def make_rect(color, alpha, size = (20,6), height = 20):
    color = color if color != None else "k" # Default value if None
    viz = DrawingArea(30, height, 0, 1)
    viz.add_artist(Rectangle((0, 6), width=size[0], height=size[1],
                             alpha=alpha, fc=color))
    return viz
Beispiel #33
0
    def summarizePerformance(self, test_data_set, learning_algo, *args,
                             **kwargs):
        """ Plot of the low-dimensional representation of the environment built by the model
        """

        all_possib_inp = []
        #labels=[]
        for x_b in range(self._nx_block):  #[1]:#range(self._nx_block):
            for y_b in range(self._height):
                for x_p in range(self._width - self._width_paddle + 1):
                    state = self.get_observation(
                        y_b, x_b * ((self._width - 1) // (self._nx_block - 1)),
                        x_p)
                    all_possib_inp.append(state)

                    #labels.append(x_b)

        #arr=np.array(all_possib_inp)
        #arr=arr.reshape(arr.shape[0],-1)
        #np.savetxt('tsne_python/catcherH_X.txt',arr.reshape(arr.shape[0],-1))
        #np.savetxt('tsne_python/cacherH_labels.txt',np.array(labels))

        all_possib_inp = np.expand_dims(all_possib_inp, axis=1)
        all_possib_abs_states = learning_algo.encoder.predict(all_possib_inp)

        n = self._height - 1
        historics = []
        for i, observ in enumerate(test_data_set.observations()[0][0:n]):
            historics.append(np.expand_dims(observ, axis=0))
        historics = np.array(historics)
        abs_states = learning_algo.encoder.predict(historics)
        actions = test_data_set.actions()[0:n]
        if self.inTerminalState() == False:
            self._mode_episode_count += 1
        print("== Mean score per episode is {} over {} episodes ==".format(
            self._mode_score / (self._mode_episode_count + 0.0001),
            self._mode_episode_count))

        import matplotlib.pyplot as plt
        from mpl_toolkits.mplot3d import Axes3D
        import matplotlib.cm as cm
        m = cm.ScalarMappable(cmap=cm.jet)

        x = np.array(abs_states)[:, 0]
        y = np.array(abs_states)[:, 1]
        z = np.array(abs_states)[:, 2]

        fig = plt.figure()
        ax = fig.add_subplot(111, projection='3d')
        ax.set_xlabel(r'$X_1$')
        ax.set_ylabel(r'$X_2$')
        ax.set_zlabel(r'$X_3$')

        for j in range(3):
            # Plot the trajectory
            for i in range(30):  #(n-1):
                ax.plot(x[j * 24 + i:j * 24 + i + 2],
                        y[j * 24 + i:j * 24 + i + 2],
                        z[j * 24 + i:j * 24 + i + 2],
                        color=plt.cm.cool(255 * i / n),
                        alpha=0.5)

        # Plot the estimated transitions
        for i in range(n - 1):
            predicted1 = learning_algo.transition.predict(
                [abs_states[i:i + 1], np.array([[1, 0]])])
            predicted2 = learning_algo.transition.predict(
                [abs_states[i:i + 1], np.array([[0, 1]])])
            ax.plot(np.concatenate([x[i:i + 1], predicted1[0, :1]]),
                    np.concatenate([y[i:i + 1], predicted1[0, 1:2]]),
                    np.concatenate([z[i:i + 1], predicted1[0, 2:3]]),
                    color="0.75",
                    alpha=0.75)
            ax.plot(np.concatenate([x[i:i + 1], predicted2[0, :1]]),
                    np.concatenate([y[i:i + 1], predicted2[0, 1:2]]),
                    np.concatenate([z[i:i + 1], predicted2[0, 2:3]]),
                    color="0.25",
                    alpha=0.75)

        # Plot the colorbar for the trajectory
        fig.subplots_adjust(right=0.7)
        ax1 = fig.add_axes([0.725, 0.15, 0.025, 0.7])
        # Set the colormap and norm to correspond to the data for which the colorbar will be used.
        cmap = matplotlib.cm.cool
        norm = matplotlib.colors.Normalize(vmin=0, vmax=1)

        # ColorbarBase derives from ScalarMappable and puts a colorbar in a specified axes, so it has
        # everything needed for a standalone colorbar.  There are many more kwargs, but the
        # following gives a basic continuous colorbar with ticks and labels.
        cb1 = matplotlib.colorbar.ColorbarBase(ax1,
                                               cmap=cmap,
                                               norm=norm,
                                               orientation='vertical')
        cb1.set_label('Beginning to end of trajectory')

        # Plot the dots at each time step depending on the action taken
        length_block = self._height * (self._width - self._width_paddle + 1)
        for i in range(self._nx_block):
            line3 = ax.scatter(
                all_possib_abs_states[i * length_block:(i + 1) * length_block,
                                      0],
                all_possib_abs_states[i * length_block:(i + 1) * length_block,
                                      1],
                all_possib_abs_states[i * length_block:(i + 1) * length_block,
                                      2],
                s=10,
                marker='x',
                depthshade=True,
                edgecolors='k',
                alpha=0.3)
        line2 = ax.scatter(x,
                           y,
                           z,
                           c=np.tile(np.expand_dims(1 - actions / 2., axis=1),
                                     (1, 3)) - 0.25,
                           s=50,
                           marker='o',
                           edgecolors='k',
                           alpha=0.75,
                           depthshade=True)
        axes_lims = [ax.get_xlim(), ax.get_ylim(), ax.get_zlim()]
        zrange = axes_lims[2][1] - axes_lims[2][0]

        # Plot the legend for the dots
        from matplotlib.patches import Circle, Rectangle
        from matplotlib.offsetbox import AnchoredOffsetbox, TextArea, DrawingArea, HPacker
        box1 = TextArea(" State representation (action 0, action 1): ",
                        textprops=dict(color="k"))

        box2 = DrawingArea(60, 20, 0, 0)
        el1 = Circle((10, 10), 5, fc="0.75", edgecolor="k", alpha=0.75)
        el2 = Circle((30, 10), 5, fc="0.25", edgecolor="k", alpha=0.75)
        #el3 = Circle((50, 10), 5, fc="0", edgecolor="k")
        box2.add_artist(el1)
        box2.add_artist(el2)
        #box2.add_artist(el3)

        box = HPacker(children=[box1, box2], align="center", pad=0, sep=5)

        anchored_box = AnchoredOffsetbox(
            loc=3,
            child=box,
            pad=0.,
            frameon=True,
            bbox_to_anchor=(0., 1.07),
            bbox_transform=ax.transAxes,
            borderpad=0.,
        )
        ax.add_artist(anchored_box)

        # Plot the legend for transition estimates
        box1b = TextArea(" Estimated transitions (action 0, action 1): ",
                         textprops=dict(color="k"))
        box2b = DrawingArea(60, 20, 0, 0)
        el1b = Rectangle((5, 10), 15, 2, fc="0.75", alpha=0.75)
        el2b = Rectangle((25, 10), 15, 2, fc="0.25", alpha=0.75)
        box2b.add_artist(el1b)
        box2b.add_artist(el2b)

        boxb = HPacker(children=[box1b, box2b], align="center", pad=0, sep=5)

        anchored_box = AnchoredOffsetbox(
            loc=3,
            child=boxb,
            pad=0.,
            frameon=True,
            bbox_to_anchor=(0., 0.98),
            bbox_transform=ax.transAxes,
            borderpad=0.,
        )
        ax.add_artist(anchored_box)

        ax.w_xaxis.set_pane_color((0.99, 0.99, 0.99, 0.99))
        ax.w_yaxis.set_pane_color((0.99, 0.99, 0.99, 0.99))
        ax.w_zaxis.set_pane_color((0.99, 0.99, 0.99, 0.99))
        #plt.savefig('fig_base'+str(learning_algo.update_counter)+'.pdf')

        # Plot the Q_vals
        c = learning_algo.Q.predict(
            np.concatenate((np.expand_dims(x, axis=1), np.expand_dims(
                y, axis=1), np.expand_dims(z, axis=1)),
                           axis=1))
        m1 = ax.scatter(x,
                        y,
                        z + zrange / 20,
                        c=c[:, 0],
                        vmin=-1.,
                        vmax=1.,
                        cmap=plt.cm.RdYlGn)
        m2 = ax.scatter(x,
                        y,
                        z + 3 * zrange / 40,
                        c=c[:, 1],
                        vmin=-1.,
                        vmax=1.,
                        cmap=plt.cm.RdYlGn)

        #plt.colorbar(m3)
        ax2 = fig.add_axes([0.85, 0.15, 0.025, 0.7])
        cmap = matplotlib.cm.RdYlGn
        norm = matplotlib.colors.Normalize(vmin=-1, vmax=1)

        # ColorbarBase derives from ScalarMappable and puts a colorbar
        # in a specified axes, so it has everything needed for a
        # standalone colorbar.  There are many more kwargs, but the
        # following gives a basic continuous colorbar with ticks
        # and labels.
        cb1 = matplotlib.colorbar.ColorbarBase(ax2,
                                               cmap=cmap,
                                               norm=norm,
                                               orientation='vertical')
        cb1.set_label('Estimated expected return')

        # plt.show()
        for ii in range(-15, 345, 30):
            ax.view_init(elev=20., azim=ii)
            plt.savefig('fig_w_V_div5_forcelr_forcessdiv2' +
                        str(learning_algo.update_counter) + '_' + str(ii) +
                        '.pdf')

        # fig_visuV
        fig = plt.figure()
        ax = fig.add_subplot(111, projection='3d')

        x = np.array([i for i in range(5) for jk in range(25)]) / 4. * (
            axes_lims[0][1] - axes_lims[0][0]) + axes_lims[0][0]
        y = np.array([j for i in range(5) for j in range(5)
                      for k in range(5)]) / 4. * (
                          axes_lims[1][1] - axes_lims[1][0]) + axes_lims[1][0]
        z = np.array([k for i in range(5) for j in range(5)
                      for k in range(5)]) / 4. * (
                          axes_lims[2][1] - axes_lims[2][0]) + axes_lims[2][0]

        c = learning_algo.Q.predict(
            np.concatenate((np.expand_dims(x, axis=1), np.expand_dims(
                y, axis=1), np.expand_dims(z, axis=1)),
                           axis=1))
        c = np.max(c, axis=1)

        m = ax.scatter(x, y, z, c=c, vmin=-1., vmax=1., cmap=plt.hot())
        fig.subplots_adjust(right=0.8)
        ax2 = fig.add_axes([0.875, 0.15, 0.025, 0.7])
        cmap = matplotlib.cm.hot
        norm = matplotlib.colors.Normalize(vmin=-1, vmax=1)

        # ColorbarBase derives from ScalarMappable and puts a colorbar
        # in a specified axes, so it has everything needed for a
        # standalone colorbar.  There are many more kwargs, but the
        # following gives a basic continuous colorbar with ticks
        # and labels.
        cb1 = matplotlib.colorbar.ColorbarBase(ax2,
                                               cmap=cmap,
                                               norm=norm,
                                               orientation='vertical')
        cb1.set_label('Estimated expected return')

        #plt.show()
        #plt.savefig('fig_visuV'+str(learning_algo.update_counter)+'.pdf')

        # fig_visuR
        fig = plt.figure()
        ax = fig.add_subplot(111, projection='3d')

        x = np.array([i for i in range(5) for jk in range(25)]) / 4. * (
            axes_lims[0][1] - axes_lims[0][0]) + axes_lims[0][0]
        y = np.array([j for i in range(5) for j in range(5)
                      for k in range(5)]) / 4. * (
                          axes_lims[1][1] - axes_lims[1][0]) + axes_lims[1][0]
        z = np.array([k for i in range(5) for j in range(5)
                      for k in range(5)]) / 4. * (
                          axes_lims[2][1] - axes_lims[2][0]) + axes_lims[2][0]

        coords = np.concatenate((np.expand_dims(
            x, axis=1), np.expand_dims(y, axis=1), np.expand_dims(z, axis=1)),
                                axis=1)
        repeat_nactions_coord = np.repeat(coords, self.nActions(), axis=0)
        identity_matrix = np.diag(np.ones(self.nActions()))
        tile_identity_matrix = np.tile(identity_matrix, (5 * 5 * 5, 1))

        c = learning_algo.R.predict(
            [repeat_nactions_coord, tile_identity_matrix])
        c = np.max(np.reshape(c, (125, self.nActions())), axis=1)

        m = ax.scatter(x, y, z, c=c, vmin=-1., vmax=1., cmap=plt.hot())
        fig.subplots_adjust(right=0.8)
        ax2 = fig.add_axes([0.875, 0.15, 0.025, 0.7])
        cmap = matplotlib.cm.hot
        norm = matplotlib.colors.Normalize(vmin=-1, vmax=1)

        # ColorbarBase derives from ScalarMappable and puts a colorbar
        # in a specified axes, so it has everything needed for a
        # standalone colorbar.  There are many more kwargs, but the
        # following gives a basic continuous colorbar with ticks
        # and labels.
        cb1 = matplotlib.colorbar.ColorbarBase(ax2,
                                               cmap=cmap,
                                               norm=norm,
                                               orientation='vertical')
        cb1.set_label('Estimated expected return')

        #plt.show()
        #plt.savefig('fig_visuR'+str(learning_algo.update_counter)+'.pdf')

        matplotlib.pyplot.close("all")  # avoids memory leaks
"""
from matplotlib.patches import Ellipse
import matplotlib.pyplot as plt
from matplotlib.offsetbox import AnchoredOffsetbox, TextArea, DrawingArea, HPacker

fig = plt.figure(1, figsize=(3, 3))
ax = plt.subplot(111)

box1 = TextArea(" Test : ", textprops=dict(color="k"))

box2 = DrawingArea(60, 20, 0, 0)
el1 = Ellipse((10, 10), width=16, height=5, angle=30, fc="r")
el2 = Ellipse((30, 10), width=16, height=5, angle=170, fc="g")
el3 = Ellipse((50, 10), width=16, height=5, angle=230, fc="b")
box2.add_artist(el1)
box2.add_artist(el2)
box2.add_artist(el3)

box = HPacker(children=[box1, box2], align="center", pad=0, sep=5)

anchored_box = AnchoredOffsetbox(
    loc=3,
    child=box,
    pad=0.,
    frameon=True,
    bbox_to_anchor=(0., 1.02),
    bbox_transform=ax.transAxes,
    borderpad=0.,
)
Beispiel #35
0
 def _init_legend_box(self, handles, labels):
     """
     Initiallize the legend_box. The legend_box is an instance of
     the OffsetBox, which is packed with legend handles and
     texts. Once packed, their location is calculated during the
     drawing time.
     """
     fontsize = self._fontsize
     text_list = []  # the list of text instances
     handle_list = []  # the list of text instances
     label_prop = dict(verticalalignment='baseline',
                       horizontalalignment='left',
                       fontproperties=self.prop,
                       )
     labelboxes = []
     handleboxes = []
     height = self._approx_text_height() * 0.7
     descent = 0.
     for handle, lab in zip(handles, labels):
         if isinstance(handle, RegularPolyCollection) or \
                isinstance(handle, CircleCollection):
             npoints = self.scatterpoints
         else:
             npoints = self.numpoints
         if npoints > 1:
             xdata = np.linspace(0.3*fontsize,
                                 (self.handlelength-0.3)*fontsize,
                                 npoints)
             xdata_marker = xdata
         elif npoints == 1:
             xdata = np.linspace(0, self.handlelength*fontsize, 2)
             xdata_marker = [0.5*self.handlelength*fontsize]
         if isinstance(handle, Line2D):
             ydata = ((height-descent)/2.)*np.ones(xdata.shape, float)
             legline = Line2D(xdata, ydata)
             legline.update_from(handle)
             self._set_artist_props(legline) # after update
             legline.set_clip_box(None)
             legline.set_clip_path(None)
             legline.set_drawstyle('default')
             legline.set_marker('None')
             handle_list.append(legline)
             legline_marker = Line2D(xdata_marker, ydata[:len(xdata_marker)])
             legline_marker.update_from(handle)
             self._set_artist_props(legline_marker)
             legline_marker.set_clip_box(None)
             legline_marker.set_clip_path(None)
             legline_marker.set_linestyle('None')
             legline._legmarker = legline_marker
         elif isinstance(handle, Patch):
             p = Rectangle(xy=(0., 0.),
                           width = self.handlelength*fontsize,
                           height=(height-descent),
                           )
             p.update_from(handle)
             self._set_artist_props(p)
             p.set_clip_box(None)
             p.set_clip_path(None)
             handle_list.append(p)
         elif isinstance(handle, LineCollection):
             ydata = ((height-descent)/2.)*np.ones(xdata.shape, float)
             legline = Line2D(xdata, ydata)
             self._set_artist_props(legline)
             legline.set_clip_box(None)
             legline.set_clip_path(None)
             lw = handle.get_linewidth()[0]
             dashes = handle.get_dashes()[0]
             color = handle.get_colors()[0]
             legline.set_color(color)
             legline.set_linewidth(lw)
             if dashes[0] is not None: # dashed line
                 legline.set_dashes(dashes[1])
             handle_list.append(legline)
         elif isinstance(handle, RegularPolyCollection):
             ydata = height*self._scatteryoffsets
             size_max, size_min = max(handle.get_sizes()),\
                                  min(handle.get_sizes())
             if self.scatterpoints < 4:
                 sizes = [.5*(size_max+size_min), size_max,
                          size_min]
             else:
                 sizes = (size_max-size_min)*np.linspace(0,1,self.scatterpoints)+size_min
             p = type(handle)(handle.get_numsides(),
                              rotation=handle.get_rotation(),
                              sizes=sizes,
                              offsets=zip(xdata_marker,ydata),
                              transOffset=self.get_transform(),
                              )
             p.update_from(handle)
             p.set_figure(self.figure)
             p.set_clip_box(None)
             p.set_clip_path(None)
             handle_list.append(p)
         elif isinstance(handle, CircleCollection):
             ydata = height*self._scatteryoffsets
             size_max, size_min = max(handle.get_sizes()),\
                                  min(handle.get_sizes())
             if self.scatterpoints < 4:
                 sizes = [.5*(size_max+size_min), size_max,
                          size_min]
             else:
                 sizes = (size_max-size_min)*np.linspace(0,1,self.scatterpoints)+size_min
             p = type(handle)(sizes,
                              offsets=zip(xdata_marker,ydata),
                              transOffset=self.get_transform(),
                              )
             p.update_from(handle)
             p.set_figure(self.figure)
             p.set_clip_box(None)
             p.set_clip_path(None)
             handle_list.append(p)
         else:
             handle_type = type(handle)
             warnings.warn("Legend does not support %s\nUse proxy artist instead.\n\nhttp://matplotlib.sourceforge.net/users/legend_guide.html#using-proxy-artist\n" % (str(handle_type),))
             handle_list.append(None)
         handle = handle_list[-1]
         if handle is not None: # handle is None is the artist is not supproted
             textbox = TextArea(lab, textprops=label_prop,
                                multilinebaseline=True, minimumdescent=True)
             text_list.append(textbox._text)
             labelboxes.append(textbox)
             handlebox = DrawingArea(width=self.handlelength*fontsize,
                                     height=height,
                                     xdescent=0., ydescent=descent)
             handlebox.add_artist(handle)
             if isinstance(handle, RegularPolyCollection) or \
                    isinstance(handle, CircleCollection):
                 handle._transOffset = handlebox.get_transform()
                 handle.set_transform(None)
             if hasattr(handle, "_legmarker"):
                 handlebox.add_artist(handle._legmarker)
             handleboxes.append(handlebox)
     if len(handleboxes) > 0:
         ncol = min(self._ncol, len(handleboxes))
         nrows, num_largecol = divmod(len(handleboxes), ncol)
         num_smallcol = ncol-num_largecol
         largecol = safezip(range(0, num_largecol*(nrows+1), (nrows+1)),
                            [nrows+1] * num_largecol)
         smallcol = safezip(range(num_largecol*(nrows+1), len(handleboxes), nrows),
                            [nrows] * num_smallcol)
     else:
         largecol, smallcol = [], []
     handle_label = safezip(handleboxes, labelboxes)
     columnbox = []
     for i0, di in largecol+smallcol:
         itemBoxes = [HPacker(pad=0,
                              sep=self.handletextpad*fontsize,
                              children=[h, t], align="baseline")
                      for h, t in handle_label[i0:i0+di]]
         itemBoxes[-1].get_children()[1].set_minimumdescent(False)
         columnbox.append(VPacker(pad=0,
                                     sep=self.labelspacing*fontsize,
                                     align="baseline",
                                     children=itemBoxes))
     if self._mode == "expand":
         mode = "expand"
     else:
         mode = "fixed"
     sep = self.columnspacing*fontsize
     self._legend_handle_box = HPacker(pad=0,
                                       sep=sep, align="baseline",
                                       mode=mode,
                                       children=columnbox)
     self._legend_title_box = TextArea("")
     self._legend_box = VPacker(pad=self.borderpad*fontsize,
                                sep=self.labelspacing*fontsize,
                                align="center",
                                children=[self._legend_title_box,
                                          self._legend_handle_box])
     self._legend_box.set_figure(self.figure)
     self.texts = text_list
     self.legendHandles = handle_list
    offsetbox = TextArea("Test", minimumdescent=False)

    ab = AnnotationBbox(offsetbox,
                        xy,
                        xybox=(1.02, xy[1]),
                        xycoords='data',
                        boxcoords=("axes fraction", "data"),
                        box_alignment=(0., 0.5),
                        arrowprops=dict(arrowstyle="->"))
    ax.add_artist(ab)

    from matplotlib.patches import Circle
    da = DrawingArea(20, 20, 0, 0)
    p = Circle((10, 10), 10)
    da.add_artist(p)

    xy = [0.3, 0.55]
    ab = AnnotationBbox(da,
                        xy,
                        xybox=(1.02, xy[1]),
                        xycoords='data',
                        boxcoords=("axes fraction", "data"),
                        box_alignment=(0., 0.5),
                        arrowprops=dict(arrowstyle="->"))
    #arrowprops=None)

    ax.add_artist(ab)

    arr = np.arange(100).reshape((10, 10))
    im = OffsetImage(arr, zoom=2)
Beispiel #37
0
        os.remove(temppath)
        size(W, HEIGHT+dy+40)
else:
    def pltshow(mplpyplot):
        mplpyplot.show()
# nodebox section end

fig, ax = plt.subplots(figsize=(3, 3))

box1 = TextArea(" Test : ", textprops=dict(color="k"))

box2 = DrawingArea(60, 20, 0, 0)
el1 = Ellipse((10, 10), width=16, height=5, angle=30, fc="r")
el2 = Ellipse((30, 10), width=16, height=5, angle=170, fc="g")
el3 = Ellipse((50, 10), width=16, height=5, angle=230, fc="b")
box2.add_artist(el1)
box2.add_artist(el2)
box2.add_artist(el3)

box = HPacker(children=[box1, box2],
              align="center",
              pad=0, sep=5)

anchored_box = AnchoredOffsetbox(loc=3,
                                 child=box, pad=0.,
                                 frameon=True,
                                 bbox_to_anchor=(0., 1.02),
                                 bbox_transform=ax.transAxes,
                                 borderpad=0.,
                                 )
Beispiel #38
0
    def _init_legend_box(self, handles, labels):
        """
        Initiallize the legend_box. The legend_box is an instance of
        the OffsetBox, which is packed with legend handles and
        texts. Once packed, their location is calculated during the
        drawing time.
        """

        fontsize = self.fontsize

        # legend_box is a HPacker, horizontally packed with
        # columns. Each column is a VPacker, vertically packed with
        # legend items. Each legend item is HPacker packed with
        # legend handleBox and labelBox. handleBox is an instance of
        # offsetbox.DrawingArea which contains legend handle. labelBox
        # is an instance of offsetbox.TextArea which contains legend
        # text.

        text_list = []  # the list of text instances
        handle_list = []  # the list of text instances

        label_prop = dict(
            verticalalignment='baseline',
            horizontalalignment='left',
            fontproperties=self.prop,
        )

        labelboxes = []

        for l in labels:
            textbox = TextArea(l,
                               textprops=label_prop,
                               multilinebaseline=True,
                               minimumdescent=True)
            text_list.append(textbox._text)
            labelboxes.append(textbox)

        handleboxes = []

        # The approximate height and descent of text. These values are
        # only used for plotting the legend handle.
        height = self._approx_text_height() * 0.7
        descent = 0.

        # each handle needs to be drawn inside a box of (x, y, w, h) =
        # (0, -descent, width, height).  And their corrdinates should
        # be given in the display coordinates.

        # NOTE : the coordinates will be updated again in
        # _update_legend_box() method.

        # The transformation of each handle will be automatically set
        # to self.get_trasnform(). If the artist does not uses its
        # default trasnform (eg, Collections), you need to
        # manually set their transform to the self.get_transform().

        for handle in handles:
            if isinstance(handle, RegularPolyCollection):
                npoints = self.scatterpoints
            else:
                npoints = self.numpoints
            if npoints > 1:
                # we put some pad here to compensate the size of the
                # marker
                xdata = np.linspace(0.3 * fontsize,
                                    (self.handlelength - 0.3) * fontsize,
                                    npoints)
                xdata_marker = xdata
            elif npoints == 1:
                xdata = np.linspace(0, self.handlelength * fontsize, 2)
                xdata_marker = [0.5 * self.handlelength * fontsize]

            if isinstance(handle, Line2D):
                ydata = ((height - descent) / 2.) * np.ones(xdata.shape, float)
                legline = Line2D(xdata, ydata)

                legline.update_from(handle)
                self._set_artist_props(legline)  # after update
                legline.set_clip_box(None)
                legline.set_clip_path(None)
                legline.set_drawstyle('default')
                legline.set_marker('None')

                handle_list.append(legline)

                legline_marker = Line2D(xdata_marker,
                                        ydata[:len(xdata_marker)])
                legline_marker.update_from(handle)
                self._set_artist_props(legline_marker)
                legline_marker.set_clip_box(None)
                legline_marker.set_clip_path(None)
                legline_marker.set_linestyle('None')
                # we don't want to add this to the return list because
                # the texts and handles are assumed to be in one-to-one
                # correpondence.
                legline._legmarker = legline_marker

            elif isinstance(handle, Patch):
                p = Rectangle(
                    xy=(0., 0.),
                    width=self.handlelength * fontsize,
                    height=(height - descent),
                )
                p.update_from(handle)
                self._set_artist_props(p)
                p.set_clip_box(None)
                p.set_clip_path(None)
                handle_list.append(p)
            elif isinstance(handle, LineCollection):
                ydata = ((height - descent) / 2.) * np.ones(xdata.shape, float)
                legline = Line2D(xdata, ydata)
                self._set_artist_props(legline)
                legline.set_clip_box(None)
                legline.set_clip_path(None)
                lw = handle.get_linewidth()[0]
                dashes = handle.get_dashes()[0]
                color = handle.get_colors()[0]
                legline.set_color(color)
                legline.set_linewidth(lw)
                legline.set_dashes(dashes)
                handle_list.append(legline)

            elif isinstance(handle, RegularPolyCollection):

                #ydata = self._scatteryoffsets
                ydata = height * self._scatteryoffsets

                size_max, size_min = max(handle.get_sizes()),\
                                     min(handle.get_sizes())
                # we may need to scale these sizes by "markerscale"
                # attribute. But other handle types does not seem
                # to care about this attribute and it is currently ignored.
                if self.scatterpoints < 4:
                    sizes = [.5 * (size_max + size_min), size_max, size_min]
                else:
                    sizes = (size_max - size_min) * np.linspace(
                        0, 1, self.scatterpoints) + size_min

                p = type(handle)(
                    handle.get_numsides(),
                    rotation=handle.get_rotation(),
                    sizes=sizes,
                    offsets=zip(xdata_marker, ydata),
                    transOffset=self.get_transform(),
                )

                p.update_from(handle)
                p.set_figure(self.figure)
                p.set_clip_box(None)
                p.set_clip_path(None)
                handle_list.append(p)

            else:
                handle_list.append(None)

            handlebox = DrawingArea(width=self.handlelength * fontsize,
                                    height=height,
                                    xdescent=0.,
                                    ydescent=descent)

            handle = handle_list[-1]
            handlebox.add_artist(handle)
            if hasattr(handle, "_legmarker"):
                handlebox.add_artist(handle._legmarker)
            handleboxes.append(handlebox)

        # We calculate number of lows in each column. The first
        # (num_largecol) columns will have (nrows+1) rows, and remaing
        # (num_smallcol) columns will have (nrows) rows.
        nrows, num_largecol = divmod(len(handleboxes), self._ncol)
        num_smallcol = self._ncol - num_largecol

        # starting index of each column and number of rows in it.
        largecol = safezip(range(0, num_largecol * (nrows + 1), (nrows + 1)),
                           [nrows + 1] * num_largecol)
        smallcol = safezip(
            range(num_largecol * (nrows + 1), len(handleboxes), nrows),
            [nrows] * num_smallcol)

        handle_label = safezip(handleboxes, labelboxes)
        columnbox = []
        for i0, di in largecol + smallcol:
            # pack handleBox and labelBox into itemBox
            itemBoxes = [
                HPacker(pad=0,
                        sep=self.handletextpad * fontsize,
                        children=[h, t],
                        align="baseline") for h, t in handle_label[i0:i0 + di]
            ]
            # minimumdescent=False for the text of the last row of the column
            itemBoxes[-1].get_children()[1].set_minimumdescent(False)

            # pack columnBox
            columnbox.append(
                VPacker(pad=0,
                        sep=self.labelspacing * fontsize,
                        align="baseline",
                        children=itemBoxes))

        if self._mode == "expand":
            mode = "expand"
        else:
            mode = "fixed"

        sep = self.columnspacing * fontsize

        self._legend_box = HPacker(pad=self.borderpad * fontsize,
                                   sep=sep,
                                   align="baseline",
                                   mode=mode,
                                   children=columnbox)

        self._legend_box.set_figure(self.figure)

        self.texts = text_list
        self.legendHandles = handle_list
Beispiel #39
0
#ax_off.patch.set_visible(False)
#ax_off.axis('off')

#%%====================================TEST=================================%%#
boxc1 = TextArea(' AHeA available:\n AHeA used for the study:',
                 textprops=dict(color='k', fontsize=9))
Boxc2 = DrawingArea(12.5, 20)
Recc0 = Rectangle((5, 0),
                  width=6,
                  height=6,
                  angle=45,
                  fc='darkred',
                  ec='darkred')
Recc1 = Circle((5, 15), radius=3.5, fc='darkred', ec='darkred')

Boxc2.add_artist(Recc0)
Boxc2.add_artist(Recc1)

boxc = HPacker(children=[boxc1, Boxc2], align="center", pad=3, sep=2.5)

anchored_boxc = AnchoredOffsetbox(loc=3,
                                  child=boxc,
                                  pad=0,
                                  frameon=True,
                                  borderpad=0)
5
fig = matplotlib.pyplot.gcf()
gs = plt.GridSpec(100,
                  100,
                  bottom=0.23249,
                  left=0.14166,
ab = AnnotationBbox(offsetbox, xy,
                    xybox=(1.02, xy[1]),
                    xycoords='data',
                    boxcoords=("axes fraction", "data"),
                    box_alignment=(0., 0.5),
                    arrowprops=dict(arrowstyle="->"))
ax.add_artist(ab)

# Define a 2nd position to annotate (don't display with a marker this time)
xy = [0.3, 0.55]

# Annotate the 2nd position with a circle patch
da = DrawingArea(20, 20, 0, 0)
p = Circle((10, 10), 10)
da.add_artist(p)

ab = AnnotationBbox(da, xy,
                    xybox=(1.02, xy[1]),
                    xycoords='data',
                    boxcoords=("axes fraction", "data"),
                    box_alignment=(0., 0.5),
                    arrowprops=dict(arrowstyle="->"))

ax.add_artist(ab)

# Annotate the 2nd position with an image (a generated array of pixels)
arr = np.arange(100).reshape((10, 10))
im = OffsetImage(arr, zoom=2)
im.image.axes = ax
Beispiel #41
0
def plot_rst(xList, yList, fnameList):
    '''docstring for plot_rst()''' 
    fig = plt.gcf()
    fig.clf()
    ax =  plt.subplot2grid((5,1),(0, 0),rowspan = 4)
    #ax = plt.subplot(111)


    xy = (0.5, 0.7)



    offsetbox = TextArea("Test", minimumdescent=False)

    ab = AnnotationBbox(offsetbox, xy,
                        xybox=(1.02, xy[1]),
                        xycoords='data',
                        boxcoords=("axes fraction", "data"),
                        box_alignment=(0.,0.5),
                        arrowprops=dict(arrowstyle="->"))
    ax.add_artist(ab)


    from matplotlib.patches import Circle
    da = DrawingArea(20, 20, 0, 0)
    p = Circle((10, 10), 10)
    da.add_artist(p)

    xy = [0.3, 0.55]
    ab = AnnotationBbox(da, xy,
                        xybox=(1.02, xy[1]),
                        xycoords='data',
                        boxcoords=("axes fraction", "data"),
                        box_alignment=(0.,0.5),
                        arrowprops=dict(arrowstyle="->"))
                        #arrowprops=None)

    ax.add_artist(ab)




    # another image


    from matplotlib._png import read_png
    #fn = get_sample_data("./61.png", asfileobj=False)
    arr_lena = read_png("./61.png")
    imagebox = OffsetImage(arr_lena, zoom=0.2)
    xy = (0.1, 0.1)
    print fnameList
    for i in range(0,len(fnameList)):
        ax.add_artist(AnnotationBbox(imagebox, xy,
                            xybox=(0.1 + i*0.2, -0.15),
                            xycoords='data',
                            boxcoords=("axes fraction", "data"),
                            #boxcoords="offset points",
                            pad=0.1,
                            arrowprops=dict(arrowstyle="->",
                                            connectionstyle="angle,angleA=0,angleB=90,rad=3")
                            ))

    ax.set_xlim(0, 1)
    ax.set_ylim(0, 1)


    plt.draw()
    plt.show()
Beispiel #42
0
def plot_maze_abstract_transitions(
    all_inputs, all_abs_inputs, model, global_step, plot_dir
):
    """Plots the abstract representation from the CRAR agent for the SimpleMaze environment.

    Heavily borrowed from:
        https://github.com/VinF/deer/blob/master/examples/test_CRAR/simple_maze_env.py
    """

    if not isinstance(plot_dir, Path):
        plot_dir = Path(plot_dir)

    exp_seq = list(reversed(most_recent(model.replay_buffer.buffer, 1000)))

    n = 1000
    history = []
    for i, (obs, *_) in enumerate(exp_seq):
        history.append(obs)
    history = np.array(history)

    abstract_states = model.agent.encode(history)
    m = cm.ScalarMappable(cmap=cm.jet)
    x, y = abstract_states.detach().cpu().numpy().T

    fig = plt.figure()
    ax = fig.add_subplot(111)
    ax.set_xlabel(r"$X_1$")
    ax.set_ylabel(r"$X_2$")

    for i in range(n - 1):
        predicted1 = (
            model.agent.compute_transition(
                abstract_states[i : i + 1], torch.as_tensor([0], device="cuda")
            )
            .detach()
            .cpu()
            .numpy()
        )

        predicted2 = (
            (
                model.agent.compute_transition(
                    abstract_states[i : i + 1], torch.as_tensor([1], device="cuda")
                )
            )
            .detach()
            .cpu()
            .numpy()
        )

        predicted3 = (
            (
                model.agent.compute_transition(
                    abstract_states[i : i + 1], torch.as_tensor([2], device="cuda")
                )
            )
            .detach()
            .cpu()
            .numpy()
        )

        predicted4 = (
            (
                model.agent.compute_transition(
                    abstract_states[i : i + 1], torch.as_tensor([3], device="cuda")
                )
            )
            .detach()
            .cpu()
            .numpy()
        )

        ax.plot(
            np.concatenate([x[i : i + 1], predicted1[0, :1]]),
            np.concatenate([y[i : i + 1], predicted1[0, 1:2]]),
            color="royalblue",
            alpha=0.75,
        )

        ax.plot(
            np.concatenate([x[i : i + 1], predicted2[0, :1]]),
            np.concatenate([y[i : i + 1], predicted2[0, 1:2]]),
            color="crimson",
            alpha=0.75,
        )

        ax.plot(
            np.concatenate([x[i : i + 1], predicted3[0, :1]]),
            np.concatenate([y[i : i + 1], predicted3[0, 1:2]]),
            color="mediumspringgreen",
            alpha=0.75,
        )

        ax.plot(
            np.concatenate([x[i : i + 1], predicted4[0, :1]]),
            np.concatenate([y[i : i + 1], predicted4[0, 1:2]]),
            color="black",
            alpha=0.75,
        )
    # Plot the dots at each time step depending on the action taken
    length_block = [[0, 18], [18, 19], [19, 31]]
    for i in range(3):
        colors = ["blue", "orange", "green"]
        line3 = ax.scatter(
            all_abs_inputs[length_block[i][0] : length_block[i][1], 0],
            all_abs_inputs[length_block[i][0] : length_block[i][1], 1],
            c=colors[i],
            marker="x",
            edgecolors="k",
            alpha=0.5,
            s=100,
        )
    axes_lims = [ax.get_xlim(), ax.get_ylim()]

    box1b = TextArea(
        " Estimated transitions (action 0, 1, 2 and 3): ", textprops=dict(color="k")
    )
    box2b = DrawingArea(90, 20, 0, 0)
    el1b = Rectangle((5, 10), 15, 2, fc="royalblue", alpha=0.75)
    el2b = Rectangle((25, 10), 15, 2, fc="crimson", alpha=0.75)
    el3b = Rectangle((45, 10), 15, 2, fc="mediumspringgreen", alpha=0.75)
    el4b = Rectangle((65, 10), 15, 2, fc="black", alpha=0.75)
    box2b.add_artist(el1b)
    box2b.add_artist(el2b)
    box2b.add_artist(el3b)
    box2b.add_artist(el4b)

    boxb = HPacker(children=[box1b, box2b], align="center", pad=0, sep=5)

    anchored_box = AnchoredOffsetbox(
        loc=3,
        child=boxb,
        pad=0.0,
        frameon=True,
        bbox_to_anchor=(0.0, 0.98),
        bbox_transform=ax.transAxes,
        borderpad=0.0,
    )
    ax.add_artist(anchored_box)
    plot_dir.mkdir(parents=True, exist_ok=True)
    plt.savefig(plot_dir / f"plot_{global_step}.pdf")
Beispiel #43
0
    def summarizePerformance(self, test_data_set, learning_algo, *args,
                             **kwargs):
        """ Plot of the low-dimensional representation of the environment built by the model
        """

        all_possib_inp = [
        ]  # Will store all possible inputs (=observation) for the CRAR agent
        labels_maze = []
        self.create_map()
        for y_a in range(self._size_maze):
            for x_a in range(self._size_maze):
                state = copy.deepcopy(self._map)
                state[self._size_maze // 2, self._size_maze // 2] = 0
                if (state[x_a, y_a] == 0):
                    if (self._higher_dim_obs == True):
                        all_possib_inp.append(
                            self.get_higher_dim_obs([[x_a, y_a]],
                                                    [self._pos_goal]))
                    else:
                        state[x_a, y_a] = 0.5
                        all_possib_inp.append(state)

                    ## labels
                    #if(y_a<self._size_maze//2):
                    #    labels_maze.append(0.)
                    #elif(y_a==self._size_maze//2):
                    #    labels_maze.append(1.)
                    #else:
                    #    labels_maze.append(2.)

        #arr=np.array(all_possib_inp)
        #if(self._higher_dim_obs==False):
        #    arr=arr.reshape(arr.shape[0],-1)
        #else:
        #    arr=arr.reshape(arr.shape[0],-1)
        #
        #np.savetxt('tsne_python/mazesH_X.txt',arr.reshape(arr.shape[0],-1))
        #np.savetxt('tsne_python/mazesH_labels.txt',np.array(labels_maze))

        all_possib_inp = np.expand_dims(np.array(all_possib_inp,
                                                 dtype='float'),
                                        axis=1)

        all_possib_abs_states = learning_algo.encoder.predict(all_possib_inp)
        if (all_possib_abs_states.ndim == 4):
            all_possib_abs_states = np.transpose(
                all_possib_abs_states,
                (0, 3, 1,
                 2))  # data_format='channels_last' --> 'channels_first'

        n = 1000
        historics = []
        for i, observ in enumerate(test_data_set.observations()[0][0:n]):
            historics.append(np.expand_dims(observ, axis=0))
        historics = np.array(historics)

        abs_states = learning_algo.encoder.predict(historics)
        if (abs_states.ndim == 4):
            abs_states = np.transpose(
                abs_states,
                (0, 3, 1,
                 2))  # data_format='channels_last' --> 'channels_first'

        actions = test_data_set.actions()[0:n]

        if self.inTerminalState() == False:
            self._mode_episode_count += 1
        print("== Mean score per episode is {} over {} episodes ==".format(
            self._mode_score / (self._mode_episode_count + 0.0001),
            self._mode_episode_count))

        m = cm.ScalarMappable(cmap=cm.jet)

        x = np.array(abs_states)[:, 0]
        y = np.array(abs_states)[:, 1]
        if (self.intern_dim > 2):
            z = np.array(abs_states)[:, 2]

        fig = plt.figure()
        if (self.intern_dim == 2):
            ax = fig.add_subplot(111)
            ax.set_xlabel(r'$X_1$')
            ax.set_ylabel(r'$X_2$')
        else:
            ax = fig.add_subplot(111, projection='3d')
            ax.set_xlabel(r'$X_1$')
            ax.set_ylabel(r'$X_2$')
            ax.set_zlabel(r'$X_3$')

        # Plot the estimated transitions
        for i in range(n - 1):
            predicted1 = learning_algo.transition.predict(
                [abs_states[i:i + 1],
                 np.array([[1, 0, 0, 0]])])
            predicted2 = learning_algo.transition.predict(
                [abs_states[i:i + 1],
                 np.array([[0, 1, 0, 0]])])
            predicted3 = learning_algo.transition.predict(
                [abs_states[i:i + 1],
                 np.array([[0, 0, 1, 0]])])
            predicted4 = learning_algo.transition.predict(
                [abs_states[i:i + 1],
                 np.array([[0, 0, 0, 1]])])
            if (self.intern_dim == 2):
                ax.plot(np.concatenate([x[i:i + 1], predicted1[0, :1]]),
                        np.concatenate([y[i:i + 1], predicted1[0, 1:2]]),
                        color="0.9",
                        alpha=0.75)
                ax.plot(np.concatenate([x[i:i + 1], predicted2[0, :1]]),
                        np.concatenate([y[i:i + 1], predicted2[0, 1:2]]),
                        color="0.65",
                        alpha=0.75)
                ax.plot(np.concatenate([x[i:i + 1], predicted3[0, :1]]),
                        np.concatenate([y[i:i + 1], predicted3[0, 1:2]]),
                        color="0.4",
                        alpha=0.75)
                ax.plot(np.concatenate([x[i:i + 1], predicted4[0, :1]]),
                        np.concatenate([y[i:i + 1], predicted4[0, 1:2]]),
                        color="0.15",
                        alpha=0.75)
            else:
                ax.plot(np.concatenate([x[i:i + 1], predicted1[0, :1]]),
                        np.concatenate([y[i:i + 1], predicted1[0, 1:2]]),
                        np.concatenate([z[i:i + 1], predicted1[0, 2:3]]),
                        color="0.9",
                        alpha=0.75)
                ax.plot(np.concatenate([x[i:i + 1], predicted2[0, :1]]),
                        np.concatenate([y[i:i + 1], predicted2[0, 1:2]]),
                        np.concatenate([z[i:i + 1], predicted2[0, 2:3]]),
                        color="0.65",
                        alpha=0.75)
                ax.plot(np.concatenate([x[i:i + 1], predicted3[0, :1]]),
                        np.concatenate([y[i:i + 1], predicted3[0, 1:2]]),
                        np.concatenate([z[i:i + 1], predicted3[0, 2:3]]),
                        color="0.4",
                        alpha=0.75)
                ax.plot(np.concatenate([x[i:i + 1], predicted4[0, :1]]),
                        np.concatenate([y[i:i + 1], predicted4[0, 1:2]]),
                        np.concatenate([z[i:i + 1], predicted4[0, 2:3]]),
                        color="0.15",
                        alpha=0.75)

        # Plot the dots at each time step depending on the action taken
        length_block = [[0, 18], [18, 19], [19, 31]]
        for i in range(3):
            colors = ['blue', 'orange', 'green']
            if (self.intern_dim == 2):
                line3 = ax.scatter(all_possib_abs_states[
                    length_block[i][0]:length_block[i][1], 0],
                                   all_possib_abs_states[
                                       length_block[i][0]:length_block[i][1],
                                       1],
                                   c=colors[i],
                                   marker='x',
                                   edgecolors='k',
                                   alpha=0.5,
                                   s=100)
            else:
                line3 = ax.scatter(all_possib_abs_states[
                    length_block[i][0]:length_block[i][1], 0],
                                   all_possib_abs_states[
                                       length_block[i][0]:length_block[i][1],
                                       1],
                                   all_possib_abs_states[
                                       length_block[i][0]:length_block[i][1],
                                       2],
                                   marker='x',
                                   depthshade=True,
                                   edgecolors='k',
                                   alpha=0.5,
                                   s=50)

        if (self.intern_dim == 2):
            axes_lims = [ax.get_xlim(), ax.get_ylim()]
        else:
            axes_lims = [ax.get_xlim(), ax.get_ylim(), ax.get_zlim()]

        # Plot the legend for transition estimates
        box1b = TextArea(" Estimated transitions (action 0, 1, 2 and 3): ",
                         textprops=dict(color="k"))
        box2b = DrawingArea(90, 20, 0, 0)
        el1b = Rectangle((5, 10), 15, 2, fc="0.9", alpha=0.75)
        el2b = Rectangle((25, 10), 15, 2, fc="0.65", alpha=0.75)
        el3b = Rectangle((45, 10), 15, 2, fc="0.4", alpha=0.75)
        el4b = Rectangle((65, 10), 15, 2, fc="0.15", alpha=0.75)
        box2b.add_artist(el1b)
        box2b.add_artist(el2b)
        box2b.add_artist(el3b)
        box2b.add_artist(el4b)

        boxb = HPacker(children=[box1b, box2b], align="center", pad=0, sep=5)

        anchored_box = AnchoredOffsetbox(
            loc=3,
            child=boxb,
            pad=0.,
            frameon=True,
            bbox_to_anchor=(0., 0.98),
            bbox_transform=ax.transAxes,
            borderpad=0.,
        )
        ax.add_artist(anchored_box)

        #plt.show()
        plt.savefig('fig_base' + str(learning_algo.update_counter) + '.pdf')

        #        # Plot the Q_vals
        #        c = learning_algo.Q.predict(np.concatenate((np.expand_dims(x,axis=1),np.expand_dims(y,axis=1),np.expand_dims(z,axis=1)),axis=1))
        #        #print "actions,C"
        #        #print actions
        #        #print c
        #        #c=np.max(c,axis=1)
        #        m1=ax.scatter(x, y, z+zrange/20, c=c[:,0], vmin=-1., vmax=1., cmap=plt.cm.RdYlGn)
        #        m2=ax.scatter(x, y, z+3*zrange/40, c=c[:,1], vmin=-1., vmax=1., cmap=plt.cm.RdYlGn)
        #
        #        #plt.colorbar(m3)
        #        ax2 = fig.add_axes([0.85, 0.15, 0.025, 0.7])
        #        cmap = matplotlib.cm.RdYlGn
        #        norm = matplotlib.colors.Normalize(vmin=-1, vmax=1)
        #
        #        # ColorbarBase derives from ScalarMappable and puts a colorbar
        #        # in a specified axes, so it has everything needed for a
        #        # standalone colorbar.  There are many more kwargs, but the
        #        # following gives a basic continuous colorbar with ticks
        #        # and labels.
        #        cb1 = matplotlib.colorbar.ColorbarBase(ax2, cmap=cmap,norm=norm,orientation='vertical')
        #        cb1.set_label('Estimated expected return')
        #
        #        #plt.show()
        #        plt.savefig('fig_w_V'+str(learning_algo.update_counter)+'.pdf')
        #
        #
        #        # fig_visuV
        #        fig = plt.figure()
        #        ax = fig.add_subplot(111, projection='3d')
        #
        #        x = np.array([i for i in range(5) for jk in range(25)])/4.*(axes_lims[0][1]-axes_lims[0][0])+axes_lims[0][0]
        #        y = np.array([j for i in range(5) for j in range(5) for k in range(5)])/4.*(axes_lims[1][1]-axes_lims[1][0])+axes_lims[1][0]
        #        z = np.array([k for i in range(5) for j in range(5) for k in range(5)])/4.*(axes_lims[2][1]-axes_lims[2][0])+axes_lims[2][0]
        #
        #        c = learning_algo.Q.predict(np.concatenate((np.expand_dims(x,axis=1),np.expand_dims(y,axis=1),np.expand_dims(z,axis=1)),axis=1))
        #        c=np.max(c,axis=1)
        #        #print "c"
        #        #print c
        #
        #        m=ax.scatter(x, y, z, c=c, vmin=-1., vmax=1., cmap=plt.hot())
        #        #plt.colorbar(m)
        #        fig.subplots_adjust(right=0.8)
        #        ax2 = fig.add_axes([0.875, 0.15, 0.025, 0.7])
        #        cmap = matplotlib.cm.hot
        #        norm = matplotlib.colors.Normalize(vmin=-1, vmax=1)
        #
        #        # ColorbarBase derives from ScalarMappable and puts a colorbar
        #        # in a specified axes, so it has everything needed for a
        #        # standalone colorbar.  There are many more kwargs, but the
        #        # following gives a basic continuous colorbar with ticks
        #        # and labels.
        #        cb1 = matplotlib.colorbar.ColorbarBase(ax2, cmap=cmap,norm=norm,orientation='vertical')
        #        cb1.set_label('Estimated expected return')
        #
        #        #plt.show()
        #        plt.savefig('fig_visuV'+str(learning_algo.update_counter)+'.pdf')
        #
        #
        #        # fig_visuR
        #        fig = plt.figure()
        #        ax = fig.add_subplot(111, projection='3d')
        #
        #        x = np.array([i for i in range(5) for jk in range(25)])/4.*(axes_lims[0][1]-axes_lims[0][0])+axes_lims[0][0]
        #        y = np.array([j for i in range(5) for j in range(5) for k in range(5)])/4.*(axes_lims[1][1]-axes_lims[1][0])+axes_lims[1][0]
        #        z = np.array([k for i in range(5) for j in range(5) for k in range(5)])/4.*(axes_lims[2][1]-axes_lims[2][0])+axes_lims[2][0]
        #
        #        coords=np.concatenate((np.expand_dims(x,axis=1),np.expand_dims(y,axis=1),np.expand_dims(z,axis=1)),axis=1)
        #        repeat_nactions_coord=np.repeat(coords,self.nActions(),axis=0)
        #        identity_matrix = np.diag(np.ones(self.nActions()))
        #        tile_identity_matrix=np.tile(identity_matrix,(5*5*5,1))
        #
        #        c = learning_algo.R.predict([repeat_nactions_coord,tile_identity_matrix])
        #        c=np.max(np.reshape(c,(125,self.nActions())),axis=1)
        #        #print "c"
        #        #print c
        #        #mini=np.min(c)
        #        #maxi=np.max(c)
        #
        #        m=ax.scatter(x, y, z, c=c, vmin=-1., vmax=1., cmap=plt.hot())
        #        #plt.colorbar(m)
        #        fig.subplots_adjust(right=0.8)
        #        ax2 = fig.add_axes([0.875, 0.15, 0.025, 0.7])
        #        cmap = matplotlib.cm.hot
        #        norm = matplotlib.colors.Normalize(vmin=-1, vmax=1)
        #
        #        # ColorbarBase derives from ScalarMappable and puts a colorbar
        #        # in a specified axes, so it has everything needed for a
        #        # standalone colorbar.  There are many more kwargs, but the
        #        # following gives a basic continuous colorbar with ticks
        #        # and labels.
        #        cb1 = matplotlib.colorbar.ColorbarBase(ax2, cmap=cmap,norm=norm,orientation='vertical')
        #        cb1.set_label('Estimated expected return')
        #
        #        #plt.show()
        #        plt.savefig('fig_visuR'+str(learning_algo.update_counter)+'.pdf')

        matplotlib.pyplot.close("all")  # avoids memory leaks
Beispiel #44
0
class EccwPlot(EccwCompute):
    """
    Plot critical enveloppes of the critical coulomb wedge.
    """

    _point_center = (0.0, 0.0)
    _point_top = (0.0, 0.0)
    _point_bottom = (0.0, 0.0)
    _point_left = (0.0, 0.0)
    _point_right = (0.0, 0.0)
    _sketch_box_width = 0.0
    _sketch_box_height = 0.0
    _padding = 10.0
    _sketch_size_factor = 1.0
    _sketch_surface = 5000.0
    _fault_gap = 1.0
    _arrow_L = 1.0
    _arrow_gap = 1.0
    _arrow_head_width = 1.0
    _arrow_head_length = 1.0

    def __init__(self, **kwargs):
        EccwCompute.__init__(self, **kwargs)
        self.sketch_size_factor = kwargs.get("sketch_size_factor", 1.0)
        self.legend = None
        self._new_figure()
        self.init_figure()

    @property
    def sketch_size_factor(self):
        return self._sketch_size_factor

    @sketch_size_factor.setter
    def sketch_size_factor(self, value):
        self._sketch_size_factor = float(value)
        # Surface of sketeched prism :
        # arbitrary set, allows a cst looking.
        self._sketch_surface = 5000.0 * self._sketch_size_factor
        self._fault_gap = self._sketch_surface / sqrt(
            self._sketch_surface) / 4.0
        self._arrow_L = self._fault_gap * 2.0 / 3.0
        self._arrow_gap = self._arrow_L / 2.0
        self._arrow_head_width = self._arrow_L / 3.0
        self._arrow_head_length = self._arrow_L / 2.0

    ## Private methods ########################################################

    def _new_figure(self):
        self.figure = plt.figure("ECCW", figsize=(8, 6))
        # self.axe = self.figure.add_subplot(111)
        self.axe = self.figure.gca()

    def _get_alphamax(self):
        return atan(
            (1 - self._lambdaB) / (1 - self._density_ratio) * tan(self._phiB))

    def _store_if_valid(self, beta, alpha, betas, alphas):
        if self._is_valid_taper(alpha, beta):
            betas.append(degrees(beta))
            alphas.append(degrees(alpha))

    def _compute_betas_alphas(self, alphas):
        """Return nested lists of valid values of beta, alpha"""
        # self._check_params()
        betas_ul, betas_ur, betas_dr, betas_dl = [], [], [], []
        alphas_ul, alphas_ur, alphas_dr, alphas_dl = [], [], [], []
        for alpha in alphas:
            lambdaB_D2 = self._convert_lambda(alpha, self._lambdaB)
            lambdaD_D2 = self._convert_lambda(alpha, self._lambdaD)
            alpha_prime = self._convert_alpha(alpha, lambdaB_D2)
            # Weird if statement because asin in PSI_D is your ennemy !
            if -self._phiB <= alpha_prime <= self._phiB:
                psi0_1, psi0_2 = self._PSI_0(alpha_prime, self._phiB)
                psiD_11, psiD_12 = self._PSI_D(psi0_1, self._phiB, self._phiD,
                                               lambdaB_D2, lambdaD_D2)
                psiD_21, psiD_22 = self._PSI_D(psi0_2, self._phiB, self._phiD,
                                               lambdaB_D2, lambdaD_D2)
                beta_dl = psiD_11 - psi0_1 - alpha
                beta_ur = psiD_12 - psi0_1 - alpha
                beta_dr = psiD_21 - psi0_2 - alpha + pi  # Don't ask why +pi
                beta_ul = psiD_22 - psi0_2 - alpha
                # beta, alpha, betas_alphas, i
                self._store_if_valid(beta_dl, alpha, betas_dl, alphas_dl)
                self._store_if_valid(beta_ur, alpha, betas_ur, alphas_ur)
                self._store_if_valid(beta_dr, alpha, betas_dr, alphas_dr)
                self._store_if_valid(beta_ul, alpha, betas_ul, alphas_ul)
        betas_up = betas_ul + betas_ur[::-1]
        alphas_up = alphas_ul + alphas_ur[::-1]
        betas_down = betas_dl[::-1] + betas_dr
        alphas_down = alphas_dl[::-1] + alphas_dr
        return betas_up, alphas_up, betas_down, alphas_down

    def _get_centroid(self, X, Y):
        """Compute the centroid of a polygon.
        Fisrt and last points are differents.
        """
        Ss, Cxs, Cys = [], [], []
        # Explore Polygon by element triangles.
        for i in range(1, len(X) - 2):
            # Surface of triangle times 2.
            Ss.append((X[i] - X[0]) * (Y[i + 1] - Y[0]) - (X[i + 1] - X[0]) *
                      (Y[i] - Y[0]))
            # Centroid of triangle.
            Cxs.append((X[0] + X[i] + X[i + 1]) / 3.0)
            Cys.append((Y[0] + Y[i] + Y[i + 1]) / 3.0)
        Ss.append((X[-2] - X[0]) * (Y[-1] - Y[0]) - (X[-1] - X[0]) *
                  (Y[-2] - Y[0]))
        Cxs.append((X[0] + X[-2] + X[-1]) / 3.0)
        Cys.append((Y[0] + Y[-2] + Y[-1]) / 3.0)
        A = sum(Ss)
        if abs(A) < self._numtol:
            # Compute x and y with an alternative (approximated) method.
            Xmin, Xmax = min(X), max(X)
            Ymin, Ymax = min(Y), max(Y)
            x = Xmin + (Xmax - Xmin) / 2.0
            y = Ymin + (Ymax - Ymin) / 2.0
        else:
            # Centroid is weighed average of element triangle centroids.
            x = sum([Cx * S for Cx, S in zip(Cxs, Ss)]) / A
            y = sum([Cy * S for Cy, S in zip(Cys, Ss)]) / A
        return x, y

    def _test_value(self, value, other, values, others, v_min, v_max):
        if value is not None:
            if v_min < value < v_max:
                values.append(value)
                others.append(other)

    def _draw_arrow(self, angle, x, y, solution, gamma=True):
        xL, yL = self._arrow_L * cos(angle), self._arrow_L * sin(angle)
        dum_l = sqrt(self._arrow_gap**2.0 + self._arrow_L**2.0) / 2.0
        dum_angle = atan(self._arrow_gap / self._arrow_L)
        if solution is "B":
            dx = dum_l * cos(angle - dum_angle)
            dy = dum_l * sin(angle - dum_angle)
            way = "right" if gamma else "left"
        else:
            dx = dum_l * cos(angle + dum_angle)
            dy = dum_l * sin(angle + dum_angle)
            way = "left" if gamma else "right"
        if gamma:
            p1 = patches.FancyArrow(
                x - dx,
                y - dy,
                xL,
                yL,
                lw=1,
                head_width=self._arrow_head_width,
                head_length=self._arrow_head_length,
                fc="k",
                ec="k",
                shape=way,
                length_includes_head=True,
            )
            p2 = patches.FancyArrow(
                x + dx,
                y + dy,
                -xL,
                -yL,
                lw=1,
                head_width=self._arrow_head_width,
                head_length=self._arrow_head_length,
                fc="k",
                ec="k",
                shape=way,
                length_includes_head=True,
            )
        else:
            p1 = patches.FancyArrow(
                x - dx,
                y + dy,
                xL,
                -yL,
                lw=1,
                head_width=self._arrow_head_width,
                head_length=self._arrow_head_length,
                fc="k",
                ec="k",
                shape=way,
                length_includes_head=True,
            )
            p2 = patches.FancyArrow(
                x + dx,
                y - dy,
                -xL,
                yL,
                lw=1,
                head_width=self._arrow_head_width,
                head_length=self._arrow_head_length,
                fc="k",
                ec="k",
                shape=way,
                length_includes_head=True,
            )
        self.drawing_aera.add_artist(p1)
        self.drawing_aera.add_artist(p2)

    def _draw_faults(self,
                     a_f,
                     x_f,
                     y_f,
                     xgap_f,
                     ygap_f,
                     ifirst,
                     incr,
                     col="gray"):
        xt, yt = self._prism_tip
        i = ifirst
        while 1:
            i += incr
            Ni = [x_f - i * xgap_f, y_f - i * ygap_f]
            b_f = Ni[1] - a_f * Ni[0]
            X, Y = [], []
            # Fault intersection with base
            try:
                x = (self._b_basal - b_f) / (a_f - self._a_basal)
                y = a_f * x + b_f
                self._append_if_node_in_box(x, y, X, Y)
            except ZeroDivisionError:
                pass
            # Fault intersection with topo
            x = (self._b_topo - b_f) / (a_f - self._a_topo)
            y = a_f * x + b_f
            self._append_if_node_in_box(x, y, X, Y)
            # Fault intersection with rear arc
            A = 1 + a_f**2.0
            B = 2.0 * (a_f * (b_f - yt) - xt)
            C = xt**2.0 + (b_f - yt)**2.0 - self._L**2.0
            D = B**2.0 - 4 * A * C
            if D >= 0.0:
                x = (-B - sqrt(D)) / 2.0 / A
                y = a_f * x + b_f
                self._append_if_node_in_box(x, y, X, Y)
                x = (-B + sqrt(D)) / 2.0 / A
                y = a_f * x + b_f
                self._append_if_node_in_box(x, y, X, Y)
            if len(X) < 2:
                break
            p = lines.Line2D(X, Y, lw=1, c=col)
            self.drawing_aera.add_artist(p)

    def _get_gamma_A(self):
        return (pi / 2.0 + self._phiB - 2.0 * self._alpha + self._alpha_prime +
                asin(sin(self._alpha_prime) / sin(self._phiB))) / 2.0

    def _get_theta_A(self):
        return (pi / 2.0 + self._phiB + 2.0 * self._alpha - self._alpha_prime -
                asin(sin(self._alpha_prime) / sin(self._phiB))) / 2.0

    def _get_gamma_B(self):
        return (pi / 2.0 - self._phiB - 2.0 * self._alpha + self._alpha_prime -
                asin(sin(self._alpha_prime) / sin(self._phiB))) / 2.0

    def _get_theta_B(self):
        return (pi / 2.0 - self._phiB + 2.0 * self._alpha - self._alpha_prime +
                asin(sin(self._alpha_prime) / sin(self._phiB))) / 2.0

    def _append_if_node_in_box(self, x, y, X, Y):
        foo = self._padding - self._numtol
        bar = self._padding + self._numtol
        if foo <= x <= self._sketch_box_width - bar:
            if foo <= y <= self._sketch_box_height - bar:
                X.append(x)
                Y.append(y)

    def _get_curve_settings(self, **kwargs):
        return {
            "c": kwargs.get("color", "k"),
            "lw": kwargs.get("thickness", 2),
            "ls": kwargs.get("style", "-"),
            "figure": self.figure,
        }

    ## Public methods #########################################################

    def init_figure(self):
        self.axe.set_xlabel(r"Décollement angle $\beta$ [deg]", fontsize=12)
        self.axe.set_ylabel(r"Critical slope $\alpha_c$ [deg]", fontsize=12)
        self.axe.grid(True)

    def reset_figure(self):
        if not plt.fignum_exists(self.figure.number):
            del self.figure
            self._new_figure()
        self.axe.clear()
        self.axe = self.figure.gca()
        self.init_figure()

    def show(self, block=False):
        plt.show(block=block)

    def add_title(self, title=""):
        self.axe.set_title(title, fontsize=16)

    def add_legend(self):
        self.legend = plt.legend(loc="best", fontsize="10")
        if self.legend is not None:
            self.legend.draggable()

    def add_refpoint(self, *args, **kwargs):
        try:
            beta = kwargs["beta"]
            alpha = kwargs["alpha"]
        except KeyError:
            raise KeyError("EccwPlot.add_refpoint method awaits at least the "
                           "following key word arguments: 'beta' and 'alpha'")
        label = kwargs.get("label", "")
        size = kwargs.get("size", 5)
        style = kwargs.get("style", "o")
        color = kwargs.get("color", "k")
        path_effects = [
            pe.PathPatchEffect(edgecolor="k", facecolor=color, linewidth=0.5)
        ]
        plt.plot(
            beta,
            alpha,
            ls="",
            marker=style,
            ms=size,
            label=label,
            path_effects=path_effects,
            figure=self.figure,
        )

    def add_curve(self, **kwargs):
        """Plot complete solution plus a given solution.
        Use directe solution f(alpha) = beta.
        """
        inverse = kwargs.get("inverse", dict())
        normal = kwargs.get("normal", dict())
        label = kwargs.get("label", "")
        alphamax = self._get_alphamax()
        alphas = np.arange(-alphamax, alphamax, alphamax * 2 / 1e4)
        bs_up, as_up, bs_dw, as_dw = self._compute_betas_alphas(alphas)
        betas, alphas = bs_up + bs_dw[::-1], as_up + as_dw[::-1]
        if normal or inverse:
            n_settings = self._get_curve_settings(**normal)
            i_settings = self._get_curve_settings(**inverse)
            l_norm, l_inv = label + " normal", label + " inverse"
            path_effects = [
                pe.Stroke(linewidth=n_settings["lw"] + 0.5, foreground="k"),
                pe.Normal(),
            ]
            plt.plot(bs_up,
                     as_up,
                     label=l_norm,
                     path_effects=path_effects,
                     **n_settings)
            # Bottom line is inverse mecanism.
            path_effects = [
                pe.Stroke(linewidth=i_settings["lw"] + 0.5, foreground="k"),
                pe.Normal(),
            ]
            plt.plot(bs_dw,
                     as_dw,
                     label=l_inv,
                     path_effects=path_effects,
                     **i_settings)
        else:
            settings = self._get_curve_settings(**kwargs)
            path_effects = [
                pe.Stroke(linewidth=settings["lw"] + 0.5, foreground="k"),
                pe.Normal(),
            ]
            plt.plot(betas,
                     alphas,
                     label=label,
                     path_effects=path_effects,
                     **settings)

        # Get bounding and central points (used by sketch).
        b, a = self._get_centroid(betas, alphas)
        self._point_center = (b, a)
        i = np.argmax(as_up)
        self._point_top = (bs_up[i], degrees(alphamax))
        self._point_top = (betas[i], degrees(alphamax))
        i = np.argmin(as_dw)
        self._point_bottom = (bs_dw[i], -degrees(alphamax))
        self._point_left = (bs_up[0], as_up[0])
        self._point_right = (bs_up[-1], as_up[-1])

    def add_point(self, **kwargs):
        beta = kwargs.get("beta", None)
        alpha = kwargs.get("alpha", None)
        sketch = kwargs.get("sketch", False)
        # line = kwargs.get('line', True)
        settings = {
            "linestyle":
            "",
            "marker":
            kwargs.get("style", "o"),
            "markersize":
            kwargs.get("size", 5),
            "label":
            kwargs.get("label", ""),
            "path_effects": [
                pe.PathPatchEffect(edgecolor="k",
                                   facecolor=kwargs.get("color", "k"),
                                   linewidth=0.5)
            ],
            "figure":
            self.figure,
        }
        betas, alphas = [], []
        pinf, minf = float("inf"), float("-inf")
        if beta is not None:
            a_min = kwargs.get("alpha_min", minf)
            a_max = kwargs.get("alpha_max", pinf)
            # if a_min == minf and a_max == pinf and line:
            #     plt.axvline(beta, lw=1.5, c='gray', figure=self.figure)
            self.beta = beta
            (alpha1, ), (alpha2, ) = self.compute_alpha()
            self._test_value(alpha1, beta, alphas, betas, a_min, a_max)
            self._test_value(alpha2, beta, alphas, betas, a_min, a_max)
            if sketch is True:
                for alpha in alphas:
                    self.alpha = alpha
                    self.add_sketch(**kwargs)
        elif alpha is not None:
            b_min = kwargs.get("beta_min", minf)
            b_max = kwargs.get("beta_max", pinf)
            # if b_min == minf and b_max == pinf and line:
            #     plt.axhline(alpha, lw=1, c='gray', figure=self.figure)
            self.alpha = alpha
            beta1, beta2 = self.compute_beta_old(
            )  #TODO potential bug with context
            self._test_value(beta1, alpha, betas, alphas, b_min, b_max)
            self._test_value(beta2, alpha, betas, alphas, b_min, b_max)
            if sketch is True:
                for beta in betas:
                    self.beta = beta
                    self.add_sketch(**kwargs)
        plt.plot(betas, alphas, **settings)

    def add_line(self, **kwargs):
        beta = kwargs.get("beta", None)
        alpha = kwargs.get("alpha", None)
        setting = {
            "ls": "-",
            "lw": 2.0,
            "c": (0.8, 0.8, 0.8, 1),
            "zorder": -10,
            "figure": self.figure,
        }
        xmin, xmax = self.axe.get_xlim()
        ymin, ymax = self.axe.get_ylim()
        pinf, minf = float("inf"), float("-inf")
        if beta is not None:
            a_min = kwargs.get("alpha_min", minf)
            a_max = kwargs.get("alpha_max", pinf)
            if a_min == minf and a_max == pinf:
                plt.axvline(beta, **setting)
            elif a_min == minf:
                x = (a_max - xmin) / (xmax - xmin) - 0.1
                plt.axvline(beta, xmax=x, **setting)
                plt.plot((beta, beta), (xmin, a_max), **setting)
            elif a_max == pinf:
                x = (a_min - xmin) / (xmax - xmin) + 0.1
                plt.axvline(beta, xmin=x, **setting)
                plt.plot((beta, beta), (a_min, xmax), **setting)
            else:
                plt.plot((beta, beta), (a_min, a_max), **setting)
        if alpha is not None:
            b_min = kwargs.get("beta_min", minf)
            b_max = kwargs.get("beta_max", pinf)
            if b_min == minf and b_max == pinf:
                plt.axhline(alpha, **setting)
            elif b_min == minf:
                x = (b_max - xmin) / (xmax - xmin) - 0.1
                plt.axhline(alpha, xmax=x, **setting)
                plt.plot((xmin, b_max), (alpha, alpha), **setting)
            elif b_max == pinf:
                x = (b_min - xmin) / (xmax - xmin) + 0.1
                plt.axhline(alpha, xmin=x, **setting)
                plt.plot((b_min, xmax), (alpha, alpha), **setting)
            else:
                plt.plot((b_min, b_max), (alpha, alpha), **setting)

    def add_sketch(self, **kwargs):
        """Draw section sketch at current value [beta, alpha].
        Draw also:
        * potential preferential fault network;
        * slip directions on fault network.
        """
        self.sketch_size_factor = kwargs.get("sketch_size_factor", 1.0)
        # Renaming is cheapper than multiple access.
        alpha, beta = self._alpha, self._beta
        a_deg, b_deg = self.alpha, self.beta
        padding = self._padding
        # Surface of prism : arbitrary set, allows a cst looking.
        # Box distance from enveloppe.
        box_dist_from_curve = (self._point_top[1] -
                               self._point_bottom[1]) / 10.0
        try:
            L = sqrt(self._sketch_surface / sin((alpha + beta) / 2.0) * cos(
                (alpha + beta) / 2.0))
        except ZeroDivisionError:
            # alpha + beta == 0. means there is no prism !
            return
        self._L = L
        # Init sketching aera ans draw background of prism.
        # Prism is a basal and a topo line, so discribed by 3 points.
        if alpha < 0.0:
            x1 = padding + 2.0 * L * sin((alpha + beta) / 2.0) * sin(
                (beta - alpha) / 2.0)
            y1 = padding
        elif beta < 0.0:
            x1, y1 = padding, padding + L * sin(-beta)
        else:
            x1, y1 = padding + L * (1.0 - cos(beta)), padding
        x2, y2 = x1 + L * cos(beta), y1 + L * sin(beta)
        x3, y3 = x2 - L * cos(alpha), y2 + L * sin(alpha)
        self._prism_tip = (x2, y2)
        # Prism is also discribed by two lines.
        # Slope of vectors [1-2] and [2-3]
        self._a_basal, self._a_topo = tan(beta), -tan(alpha)
        # Initial ordinates
        self._b_basal = y2 - self._a_basal * x2
        self._b_topo = y2 - self._a_topo * x2
        self._sketch_box_width = x2 + padding
        self._sketch_box_height = max(y3, y2) - min(y1, y2) + 2 * padding
        # Content of annotationbox
        self.drawing_aera = DrawingArea(self._sketch_box_width,
                                        self._sketch_box_height, 0.0, 0.0)
        # Fill the prism
        XY = [[x1, y1], [x2, y2]]
        for angle in np.arange(alpha, -beta, -(alpha + beta) / 1.0e2):
            XY.append([x2 - L * cos(angle), y2 + L * sin(angle)])
        p = patches.Polygon(XY, edgecolor="none", facecolor="w")
        self.drawing_aera.add_artist(p)
        # Identify wich part of critical enveloppe is concerned.
        slope = abs(
            atan((self._point_center[1] - a_deg) /
                 (self._point_center[0] - b_deg)))
        dist_from_curve_b = box_dist_from_curve * cos(slope)
        dist_from_curve_a = box_dist_from_curve * sin(slope)
        (alpha1, ), (alpha2, ) = self.compute_alpha(deg=False)
        a_mid = alpha1 + (alpha2 - alpha1) / 2.0
        if alpha <= a_mid:  # bottom part -> inverse faults
            if b_deg < self._point_bottom[0]:  # bottom left quadrant
                quadrant, solution = "BL", "B"
            else:  # bottom right quadrant
                quadrant, solution = "BR", "A"
        else:  # upper part -> normal faults
            if b_deg < self._point_top[0]:  # Top left quadrant
                quadrant, solution = "TL", "A"
            else:  # Top right quadrant
                quadrant, solution = "TR", "B"
        if solution == "A":
            g = self._get_gamma_A()
            t = self._get_theta_A()
        else:
            g = self._get_gamma_B()
            t = self._get_theta_B()
        if quadrant == "TL":
            box_alignment, xshift, yshift = (1.0, 0.0), -1.0, 1.0
        elif quadrant == "TR":
            box_alignment, xshift, yshift = (0.0, 0.0), 1.0, 1.0
        elif quadrant == "BL":
            box_alignment, xshift, yshift = (1.0, 1.0), -1.0, -1.0
        elif quadrant == "BR":
            box_alignment, xshift, yshift = (0.0, 1.0), 1.0, -1.0

        # Fault network.
        xgap = self._fault_gap * cos((beta - alpha) / 2.0)
        ygap = self._fault_gap * sin((beta - alpha) / 2.0)
        L_A, L_B, angle = L / 3.0, L * 2.0 / 3.0, alpha - (alpha + beta) / 2.0
        # Gamma oriented faults
        L_g = L_A if quadrant in ["TL", "BL"] else L_B
        x_g, y_g = x2 - L_g * cos(angle), y2 + L_g * sin(angle)
        xgap_g = xgap / sin(g - (beta - alpha) / 2.0)
        ygap_g = ygap / sin(g - (beta - alpha) / 2.0)
        a_g = tan(g)
        self._draw_faults(a_g, x_g, y_g, xgap_g, ygap_g, -1, 1)
        self._draw_faults(a_g, x_g, y_g, xgap_g, ygap_g, 0, -1)
        # Theta oriented faults
        L_t = L_B if quadrant in ["TL", "BL"] else L_A
        x_t, y_t = x2 - L_t * cos(angle), y2 + L_t * sin(angle)
        xgap_t = xgap / sin(t + (beta - alpha) / 2.0)
        ygap_t = ygap / sin(t + (beta - alpha) / 2.0)
        a_t = -tan(t)  # Fault slope theta
        self._draw_faults(a_t, x_t, y_t, xgap_t, ygap_t, -1, 1)
        self._draw_faults(a_t, x_t, y_t, xgap_t, ygap_t, 0, -1)

        # Prism limits.
        # Drawed above faults to mask faults tips.
        p = lines.Line2D([x1, x2, x3], [y1, y2, y3], lw=2, color="gray")
        self.drawing_aera.add_artist(p)

        # Arrows.
        # Gamma oriented inverse arrows.
        self._draw_arrow(g, x_g, y_g, solution, gamma=True)
        # Theta oriented inverse arrows.
        self._draw_arrow(t, x_t, y_t, solution, gamma=False)
        # arrows base
        x, y = x1 + L * cos(beta) / 2.0, y1 + L * sin(beta) / 2.0
        if self.context == "Compression":
            solution = "B"
        else:
            solution = "A"
        self._draw_arrow(beta, x, y, solution, gamma=True)

        # Set and display annotation box.
        ab = AnnotationBbox(
            self.drawing_aera,
            [b_deg, a_deg],
            xybox=(
                b_deg + xshift * dist_from_curve_b,
                a_deg + yshift * dist_from_curve_a,
            ),
            xycoords="data",
            boxcoords=("data", "data"),
            box_alignment=box_alignment,
            bboxprops=dict(boxstyle="round", fc=(0.9, 0.9, 0.9), ec="none"),
            arrowprops=dict(
                arrowstyle="wedge,tail_width=2.",
                fc=(0.9, 0.9, 0.9),
                ec=(0.8, 0.8, 0.8),
                patchA=None,
                relpos=(0.5, 0.5),
            ),
        )
        self.axe.add_artist(ab).draggable()
    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)
Beispiel #46
0
    def _init_legend_box(self, handles, labels):
        """
        Initiallize the legend_box. The legend_box is an instance of
        the OffsetBox, which is packed with legend handles and
        texts. Once packed, their location is calculated during the
        drawing time.
        """

        fontsize = self.fontsize

        # legend_box is a HPacker, horizontally packed with
        # columns. Each column is a VPacker, vertically packed with
        # legend items. Each legend item is HPacker packed with
        # legend handleBox and labelBox. handleBox is an instance of
        # offsetbox.DrawingArea which contains legend handle. labelBox
        # is an instance of offsetbox.TextArea which contains legend
        # text.


        text_list = []  # the list of text instances
        handle_list = []  # the list of text instances

        label_prop = dict(verticalalignment='baseline',
                          horizontalalignment='left',
                          fontproperties=self.prop,
                          )

        labelboxes = []

        for l in labels:
            textbox = TextArea(l, textprops=label_prop,
                               multilinebaseline=True, minimumdescent=True)
            text_list.append(textbox._text)
            labelboxes.append(textbox)

        handleboxes = []


        # The approximate height and descent of text. These values are
        # only used for plotting the legend handle.
        height = self._approx_text_height() * 0.7
        descent = 0.

        # each handle needs to be drawn inside a box of (x, y, w, h) =
        # (0, -descent, width, height).  And their corrdinates should
        # be given in the display coordinates.

        # NOTE : the coordinates will be updated again in
        # _update_legend_box() method.

        # The transformation of each handle will be automatically set
        # to self.get_trasnform(). If the artist does not uses its
        # default trasnform (eg, Collections), you need to
        # manually set their transform to the self.get_transform().

        for handle in handles:
            if isinstance(handle, RegularPolyCollection):
                npoints = self.scatterpoints
            else:
                npoints = self.numpoints
            if npoints > 1:
                # we put some pad here to compensate the size of the
                # marker
                xdata = np.linspace(0.3*fontsize,
                                    (self.handlelength-0.3)*fontsize,
                                    npoints)
                xdata_marker = xdata
            elif npoints == 1:
                xdata = np.linspace(0, self.handlelength*fontsize, 2)
                xdata_marker = [0.5*self.handlelength*fontsize]

            if isinstance(handle, Line2D):
                ydata = ((height-descent)/2.)*np.ones(xdata.shape, float)
                legline = Line2D(xdata, ydata)

                legline.update_from(handle)
                self._set_artist_props(legline) # after update
                legline.set_clip_box(None)
                legline.set_clip_path(None)
                legline.set_drawstyle('default')
                legline.set_marker('None')

                handle_list.append(legline)

                legline_marker = Line2D(xdata_marker, ydata[:len(xdata_marker)])
                legline_marker.update_from(handle)
                self._set_artist_props(legline_marker)
                legline_marker.set_clip_box(None)
                legline_marker.set_clip_path(None)
                legline_marker.set_linestyle('None')
                # we don't want to add this to the return list because
                # the texts and handles are assumed to be in one-to-one
                # correpondence.
                legline._legmarker = legline_marker

            elif isinstance(handle, Patch):
                p = Rectangle(xy=(0., 0.),
                              width = self.handlelength*fontsize,
                              height=(height-descent),
                              )
                p.update_from(handle)
                self._set_artist_props(p)
                p.set_clip_box(None)
                p.set_clip_path(None)
                handle_list.append(p)
            elif isinstance(handle, LineCollection):
                ydata = ((height-descent)/2.)*np.ones(xdata.shape, float)
                legline = Line2D(xdata, ydata)
                self._set_artist_props(legline)
                legline.set_clip_box(None)
                legline.set_clip_path(None)
                lw = handle.get_linewidth()[0]
                dashes = handle.get_dashes()[0]
                color = handle.get_colors()[0]
                legline.set_color(color)
                legline.set_linewidth(lw)
                legline.set_dashes(dashes)
                handle_list.append(legline)

            elif isinstance(handle, RegularPolyCollection):

                #ydata = self._scatteryoffsets
                ydata = height*self._scatteryoffsets

                size_max, size_min = max(handle.get_sizes()),\
                                     min(handle.get_sizes())
                # we may need to scale these sizes by "markerscale"
                # attribute. But other handle types does not seem
                # to care about this attribute and it is currently ignored.
                if self.scatterpoints < 4:
                    sizes = [.5*(size_max+size_min), size_max,
                             size_min]
                else:
                    sizes = (size_max-size_min)*np.linspace(0,1,self.scatterpoints)+size_min

                p = type(handle)(handle.get_numsides(),
                                 rotation=handle.get_rotation(),
                                 sizes=sizes,
                                 offsets=zip(xdata_marker,ydata),
                                 transOffset=self.get_transform(),
                                 )

                p.update_from(handle)
                p.set_figure(self.figure)
                p.set_clip_box(None)
                p.set_clip_path(None)
                handle_list.append(p)

            else:
                handle_list.append(None)

            handlebox = DrawingArea(width=self.handlelength*fontsize,
                                    height=height,
                                    xdescent=0., ydescent=descent)

            handle = handle_list[-1]
            handlebox.add_artist(handle)
            if hasattr(handle, "_legmarker"):
                handlebox.add_artist(handle._legmarker)
            handleboxes.append(handlebox)


        # We calculate number of lows in each column. The first
        # (num_largecol) columns will have (nrows+1) rows, and remaing
        # (num_smallcol) columns will have (nrows) rows.
        nrows, num_largecol = divmod(len(handleboxes), self._ncol)
        num_smallcol = self._ncol-num_largecol

        # starting index of each column and number of rows in it.
        largecol = safezip(range(0, num_largecol*(nrows+1), (nrows+1)),
                           [nrows+1] * num_largecol)
        smallcol = safezip(range(num_largecol*(nrows+1), len(handleboxes), nrows),
                           [nrows] * num_smallcol)

        handle_label = safezip(handleboxes, labelboxes)
        columnbox = []
        for i0, di in largecol+smallcol:
            # pack handleBox and labelBox into itemBox
            itemBoxes = [HPacker(pad=0,
                                 sep=self.handletextpad*fontsize,
                                 children=[h, t], align="baseline")
                         for h, t in handle_label[i0:i0+di]]
            # minimumdescent=False for the text of the last row of the column
            itemBoxes[-1].get_children()[1].set_minimumdescent(False)

            # pack columnBox
            columnbox.append(VPacker(pad=0,
                                        sep=self.labelspacing*fontsize,
                                        align="baseline",
                                        children=itemBoxes))

        if self._mode == "expand":
            mode = "expand"
        else:
            mode = "fixed"

        sep = self.columnspacing*fontsize

        self._legend_box = HPacker(pad=self.borderpad*fontsize,
                                      sep=sep, align="baseline",
                                      mode=mode,
                                      children=columnbox)

        self._legend_box.set_figure(self.figure)

        self.texts = text_list
        self.legendHandles = handle_list
Beispiel #47
0
def test_annotationbbox_extents():
    plt.rcParams.update(plt.rcParamsDefault)
    fig, ax = plt.subplots(figsize=(4, 3), dpi=100)

    ax.axis([0, 1, 0, 1])

    an1 = ax.annotate("Annotation",
                      xy=(.9, .9),
                      xytext=(1.1, 1.1),
                      arrowprops=dict(arrowstyle="->"),
                      clip_on=False,
                      va="baseline",
                      ha="left")

    da = DrawingArea(20, 20, 0, 0, clip=True)
    p = mpatches.Circle((-10, 30), 32)
    da.add_artist(p)

    ab3 = AnnotationBbox(da, [.5, .5],
                         xybox=(-0.2, 0.5),
                         xycoords='data',
                         boxcoords="axes fraction",
                         box_alignment=(0., .5),
                         arrowprops=dict(arrowstyle="->"))
    ax.add_artist(ab3)

    im = OffsetImage(np.random.rand(10, 10), zoom=3)
    im.image.axes = ax
    ab6 = AnnotationBbox(im, (0.5, -.3),
                         xybox=(0, 75),
                         xycoords='axes fraction',
                         boxcoords="offset points",
                         pad=0.3,
                         arrowprops=dict(arrowstyle="->"))
    ax.add_artist(ab6)

    fig.canvas.draw()
    renderer = fig.canvas.get_renderer()

    # Test Annotation
    bb1w = an1.get_window_extent(renderer)
    bb1e = an1.get_tightbbox(renderer)

    target1 = [332.9, 242.8, 467.0, 298.9]
    assert_allclose(bb1w.extents, target1, atol=2)
    assert_allclose(bb1e.extents, target1, atol=2)

    # Test AnnotationBbox
    bb3w = ab3.get_window_extent(renderer)
    bb3e = ab3.get_tightbbox(renderer)

    target3 = [-17.6, 129.0, 200.7, 167.9]
    assert_allclose(bb3w.extents, target3, atol=2)
    assert_allclose(bb3e.extents, target3, atol=2)

    bb6w = ab6.get_window_extent(renderer)
    bb6e = ab6.get_tightbbox(renderer)

    target6 = [180.0, -32.0, 230.0, 92.9]
    assert_allclose(bb6w.extents, target6, atol=2)
    assert_allclose(bb6e.extents, target6, atol=2)

    # Test bbox_inches='tight'
    buf = io.BytesIO()
    fig.savefig(buf, bbox_inches='tight')
    buf.seek(0)
    shape = plt.imread(buf).shape
    targetshape = (350, 504, 4)
    assert_allclose(shape, targetshape, atol=2)

    # Simple smoke test for tight_layout, to make sure it does not error out.
    fig.canvas.draw()
    fig.tight_layout()
    fig.canvas.draw()