Exemple #1
0
def add_letter(ax: Axes = None, offset: float = 0, offset2: float = 0, letter: str = None):
    """ add a letter indicating which subplot it is to the given figure """
    global letter_index
    from matplotlib.transforms import Affine2D, ScaledTranslation

    # get the axes
    if ax is None:
        ax = plt.gca()

    # get the figure
    fig = ax.figure

    # get the font properties for figure letters
    font = get_letter_font_prop()

    # if no letter is given
    if letter is None:
        # use the letter_format from the font
        letter = font.letter_format
        # and add a letter given the current letter_index
        letter = letter.replace("a", chr(ord("a") + letter_index))
        letter = letter.replace("A", chr(ord("A") + letter_index))
        # increase the letter index
        letter_index += 1

    # add a transform that gives the coordinates relative to the left top corner of the axes in cm
    transform = Affine2D().scale(1 / 2.54, 1 / 2.54) + fig.dpi_scale_trans + ScaledTranslation(0, 1, ax.transAxes)

    # add a text a the given position
    ax.text(-0.5+offset, offset2, letter, fontproperties=font, transform=transform, ha="center", va="bottom", picker=True)
Exemple #2
0
    def plot(
        self, ax: Axes, text_kw=None, shift=dict(units="dots", x=15), **kwargs
    ) -> List[Artist]:

        if text_kw is None:
            text_kw = {}

        if "projection" in ax.__dict__ and "transform" not in kwargs:
            from cartopy.crs import PlateCarree
            from matplotlib.transforms import offset_copy

            kwargs["transform"] = PlateCarree()
            geodetic_transform = PlateCarree()._as_mpl_transform(ax)
            text_kw["transform"] = offset_copy(geodetic_transform, **shift)

        if "color" not in kwargs:
            kwargs["color"] = "black"

        if "s" not in text_kw:
            text_kw["s"] = getattr(self, "callsign", "")

        cumul: List[Artist] = []
        cumul.append(ax.scatter(self.longitude, self.latitude, **kwargs))
        cumul.append(ax.text(self.longitude, self.latitude, **text_kw))
        return cumul
Exemple #3
0
    def plot(
        self, ax: Axes, text_kw=None, shift=None, **kwargs
    ) -> List[Artist]:  # coverage: ignore

        if shift is None:
            # flake B006
            shift = dict(units="dots", x=15)

        if text_kw is None:
            text_kw = {}
        else:
            # since we may modify it, let's make a copy
            text_kw = {**text_kw}

        if "projection" in ax.__dict__ and "transform" not in kwargs:
            from cartopy.crs import PlateCarree
            from matplotlib.transforms import offset_copy

            kwargs["transform"] = PlateCarree()
            geodetic_transform = PlateCarree()._as_mpl_transform(ax)
            text_kw["transform"] = offset_copy(geodetic_transform, **shift)

        if "color" not in kwargs:
            kwargs["color"] = "black"

        if "s" not in text_kw:
            if hasattr(self, "callsign"):
                text_kw["s"] = getattr(self, "callsign")  # noqa: B009
            if hasattr(self, "name"):
                text_kw["s"] = getattr(self, "name")  # noqa: B009

        cumul: List[Artist] = []
        cumul.append(ax.scatter(self.longitude, self.latitude, **kwargs))
        cumul.append(ax.text(self.longitude, self.latitude, **text_kw))
        return cumul
Exemple #4
0
def draw_from_point_to_bbox(parent_axes: Axes, insert_axes: Axes, point: Sequence, loc=1, **kwargs):
    """ add a box connector from a point to an axes """
    from mpl_toolkits.axes_grid1.inset_locator import TransformedBbox, BboxConnector, Bbox
    rect = TransformedBbox(Bbox([point, point]), parent_axes.transData)
    # rect = TransformedBbox(Bbox([[1, 0], [1, 0]]), parent_axes.transData)
    p1 = BboxConnector(rect, insert_axes.bbox, loc, **kwargs)
    parent_axes.add_patch(p1)
    p1.set_clip_on(False)
    return p1
Exemple #5
0
def mark_inset_pos(parent_axes: Axes, inset_axes: Axes, loc1: Union[int, Sequence[int]], loc2: Union[int, Sequence[int]], point: Sequence, **kwargs):
    """ add a box connector where the second axis is shrinked to a point """
    kwargs["lw"] = 0.8
    ax_new = plt.axes(inset_axes.get_position())
    ax_new.set_xlim(point[0], point[0])
    ax_new.set_ylim(point[1], point[1])
    mark_inset(parent_axes, ax_new, loc1, loc2, **kwargs)
    plt.xticks([])
    plt.yticks([])
    ax_new.set_zorder(inset_axes.get_zorder() - 1)
Exemple #6
0
def draw_from_point_to_point(parent_axes: Axes, insert_axes: Axes, point1: Sequence, point2: Sequence, **kwargs):
    """ add a box connector from a point in on axes to a point in another axes """
    from mpl_toolkits.axes_grid1.inset_locator import TransformedBbox, BboxConnector, Bbox
    rect = TransformedBbox(Bbox([point1, point1]), parent_axes.transData)
    rect2 = TransformedBbox(Bbox([point2, point2]), insert_axes.transData)
    # rect = TransformedBbox(Bbox([[1, 0], [1, 0]]), parent_axes.transData)
    loc = 1
    p1 = BboxConnector(rect, rect2, loc, **kwargs)
    parent_axes.add_patch(p1)
    p1.set_clip_on(False)
    return p1
def despine(ax: Axes = None, complete: bool = False):
    """ despine the given axes """
    if not ax:
        ax = plt.gca()
    ax.spines['right'].set_visible(False)
    ax.spines['top'].set_visible(False)
    if complete:
        ax.spines['left'].set_visible(False)
        ax.spines['bottom'].set_visible(False)
        ax.set_xticks([])
        ax.set_yticks([])
    else:
        # Only show ticks on the left and bottom spines
        ax.yaxis.set_ticks_position('left')
        ax.xaxis.set_ticks_position('bottom')
Exemple #8
0
def format_plot_4(plt_4: Axes) -> None:
    """Adjust all properties of plot 4 to make it look nice.

    Add the x & y ticks, format those ticks, set the title, and place the
    text on the plot for the empty text plot.

    Parameters
    ----------
    plt_4 : `Axes`
        The object that describes the graph

    """
    plt_4.text(0.5,
               0.5,
               "CGP Grey Electoral College Spreadsheet graphed.",
               transform=plt_4.transAxes,
               fontsize=20,
               horizontalalignment="center")
    plt_4.axis("off")
def mark_inset(parent_axes: Axes,
               inset_axes: Axes,
               loc1: Union[int, Sequence[int]] = 1,
               loc2: Union[int, Sequence[int]] = 2,
               **kwargs):
    """ like the mark_inset function from matplotlib, but loc can also be a tuple """
    from mpl_toolkits.axes_grid1.inset_locator import TransformedBbox, BboxPatch, BboxConnector
    try:
        loc1a, loc1b = loc1
    except:
        loc1a = loc1
        loc1b = loc1
    try:
        loc2a, loc2b = loc2
    except:
        loc2a = loc2
        loc2b = loc2
    rect = TransformedBbox(inset_axes.viewLim, parent_axes.transData)

    pp = BboxPatch(rect, fill=False, **kwargs)
    parent_axes.add_patch(pp)
    pp.set_clip_on(False)

    p1 = BboxConnector(inset_axes.bbox, rect, loc1=loc1a, loc2=loc1b, **kwargs)
    inset_axes.add_patch(p1)
    p1.set_clip_on(False)
    p2 = BboxConnector(inset_axes.bbox, rect, loc1=loc2a, loc2=loc2b, **kwargs)
    inset_axes.add_patch(p2)
    p2.set_clip_on(False)

    return pp, p1, p2
Exemple #10
0
def plot_history(history: dict, lbl: str, ax1: Axes, ax2: Axes,
                 color: str) -> Tuple[Axes, Axes]:
    """
    根據給定的history畫圖,左為loss vs epoch,右為accuracy vs epoch
    Args:
        history (dict): keras中的history dict
        lbl (str): 該history對應的legend
        ax1 (Axes) 物件,畫線圖 (loss vs epoch)
        ax2 (Axes) 物件,畫線圖 (accuracy vs epoch)
        color (str) : 該history對應的顏色


    Returns:
        Tuple[Axes, Axes] : 畫好線的Axes物件 

    """
    acc_keyword = ['acc', 'accuracy']
    val_acc_keyword = ['val_acc', 'val_accuracy']
    ax1.plot(history['loss'], label=f'{lbl}_train', c=color)
    ax1.plot(history['val_loss'], label=f'{lbl}_val', c=color, linestyle='--')
    ax1.set_ylabel('Loss')
    ax1.set_xlabel('Epoch')
    ######### [START] for differenct keras version acc keywords #############
    try:
        # 'acc' for keras 2.1.6
        ax2.plot(history[acc_keyword[0]], label=f'{lbl}_train', c=color)
        ax2.plot(history[val_acc_keyword[0]],
                 label=f'{lbl}_val',
                 c=color,
                 linestyle='--')
    except KeyError:
        # 'accuracy' for keras > 2.1.6
        ax2.plot(history[acc_keyword[1]], label=f'{lbl}_train', c=color)
        ax2.plot(history[val_acc_keyword[1]],
                 label=f'{lbl}_val',
                 c=color,
                 linestyle='--')
    ######### [END] for differenct keras version acc keywords #############
    ax2.set_ylabel('accuracy')
    ax2.set_xlabel('Epoch')
    return ax1, ax2
Exemple #11
0
def format_plot_1(plt_1: Axes, x_vals: List[int],
                  state_info_list: List[StateInfo]) -> PlotProps:
    """Adjust all properties of plot 1 to make it look nice.

    Add the x & y ticks, format those ticks, set the title, draw the mean
    line, and place the text on the plot for the pop_per_rep plot.

    Parameters
    ----------
    plt_1 : `Axes`
        The object that describes the graph
    x_vals : `List[int]`
        The list of ints that shows the states' positions
    state_info_list : `List[StateInfo]`
        Continually updated list of state calculation info

    Returns
    -------
    `PlotProps`
        A tuple of the plotted bars, text, and line objects

    """
    state_names = extract_state_names(state_info_list)
    pop_per_rep_list = extract_pop_per_rep(state_info_list)

    plt_1_bars: BarContainer = plt_1.bar(x_vals,
                                         pop_per_rep_list,
                                         align="center")

    plt_1.set_xticks(x_vals)
    plt_1.set_xticklabels(state_names, rotation="vertical")

    y_formatter = FuncFormatter(comma_format_int())

    plt_1.set_ylabel("People/Representative")
    plt_1.set_yscale("log")
    plt_1.get_yaxis().set_major_formatter(y_formatter)

    plt_1.set_title("People per representative per state")

    plt_1.grid(axis="y", which="major", lw=2)
    plt_1.grid(axis="y", which="minor", lw=0.75)
    plt_1.grid(axis="x", lw=0.75)

    mean_pop_per_seat: float = np.mean(pop_per_rep_list)
    std_dev_pop_per_seat: float = np.std(pop_per_rep_list)
    range_pop_per_seat: float = max(pop_per_rep_list) - min(pop_per_rep_list)
    geo_mean_pop_per_seat: float = geometric_mean(pop_per_rep_list)

    res_dict: PlotTextDict = {}

    res_dict["seat_txt"] = plt_1.text(0.25,
                                      0.75,
                                      f"Seat# 1",
                                      transform=plt_1.transAxes)
    res_dict["state_txt"] = plt_1.text(0.15,
                                       0.85,
                                       "State: ",
                                       transform=plt_1.transAxes)
    res_dict["mean_txt"] = plt_1.text(0.45,
                                      0.75,
                                      f"Mean: {mean_pop_per_seat:,.2f}",
                                      transform=plt_1.transAxes)
    res_dict["std_dev_txt"] = plt_1.text(
        0.35,
        0.85,
        f"Std. Dev. {std_dev_pop_per_seat:,.2f}",
        transform=plt_1.transAxes)
    res_dict["range_txt"] = plt_1.text(0.70,
                                       0.75,
                                       f"Range: {range_pop_per_seat:,.2f}",
                                       transform=plt_1.transAxes)
    res_dict["geo_mean_txt"] = plt_1.text(
        0.6,
        0.85,
        f"Geo. Mean: {geo_mean_pop_per_seat:,.2f}",
        transform=plt_1.transAxes)
    mean_line: Line2D = plt_1.axhline(y=mean_pop_per_seat,
                                      xmin=0.0,
                                      xmax=1.0,
                                      color="r")

    return (plt_1_bars, mean_line, res_dict)
Exemple #12
0
def format_plot_3(plt_3: Axes, x_vals: List[int],
                  state_info_list: List[StateInfo]) -> BarContainer:
    """Adjust all properties of plot 3 to make it look nice.

    Add the x & y ticks, format those ticks, set the title, and place the
    text on the plot for the priority num plot.

    Parameters
    ----------
    plt_3 : `Axes`
        The object that describes the graph
    x_vals : `List[int]`
        The list of ints that shows the states' position's
    state_info_list : `List[StateInfo]`
        Continually updated list of state calculation info

    Returns
    -------
    `BarContainer`
        The objects describing the plotted bars

    """
    state_names = extract_state_names(state_info_list)
    priority_list = extract_priority(state_info_list)

    plt_3_bars: BarContainer = plt_3.bar(x_vals,
                                         priority_list,
                                         align="center",
                                         color="g")
    plt_3.set_xticks(x_vals)
    plt_3.set_xticklabels(state_names, rotation="vertical")

    y_formatter: FuncFormatter = FuncFormatter(comma_format_int())

    plt_3.set_ylabel("Priority value")
    plt_3.set_yscale("log")
    plt_3.get_yaxis().set_major_formatter(y_formatter)
    plt_3.text(0.3,
               0.9,
               "Highlighted, is the state with the highest priority value",
               transform=plt_3.transAxes)

    plt_3.grid(axis="y", which="major", lw=2)
    plt_3.grid(axis="y", which="minor", lw=0.75)
    plt_3.grid(axis="x", lw=0.75)

    plt_3.set_title("Priority values per state")

    return plt_3_bars
Exemple #13
0
def format_plot_2(plt_2: Axes, x_vals: List[int],
                  state_info_list: List[StateInfo]) -> BarContainer:
    """Adjust all properties of plot 2 to make it look nice.

    Add the x & y ticks, format those ticks, set the title, and place the
    text on the plot for the number of reps plot.

    Parameters
    ----------
    plt_2 : `Axes`
        The object that describes the graph
    x_vals : `List[int]`
        The list of ints that shows the states' position's
    state_info_list : `List[StateInfo]`
        Continually updated list of state calculation info

    Returns
    -------
    `BarContainer`
        The objects describing the plotted bars

    """
    state_names = extract_state_names(state_info_list)
    reps_list = extract_reps(state_info_list)

    plt_2_bars: BarContainer = plt_2.bar(x_vals,
                                         reps_list,
                                         align="center",
                                         color="r")
    plt_2.set_xticks(x_vals)
    plt_2.set_xticklabels(state_names, rotation="vertical")

    y_axis = plt_2.get_yaxis()

    minor_loc = MultipleLocator(5)
    y_axis.set_minor_locator(minor_loc)

    plt_2.set_ylabel("Representatives")
    plt_2.set_ylim(top=60, bottom=0)

    plt_2.grid(axis="y", which="major", lw=2)
    plt_2.grid(axis="y", which="minor", lw=0.75)
    plt_2.grid(axis="x", lw=0.75)

    plt_2.set_title("Representatives per state")

    return plt_2_bars
def update(frameNum: int, img: mltimg.AxesImage, grid: np.ndarray, N: int,
           ax: mltax.Axes, G: int):

    newGrid = grid.copy()
    visited = np.zeros(N * N).reshape(N, N)
    counters = np.zeros(len(BEINGS))
    reported = []
    global FRAME
    if frameNum == 1:
        print("SUCCESS Simulation begins.")

    # implementation of the rules of Life
    for i in range(N):
        for j in range(N):
            rareCase = False
            myNeighbours = checkNeighbours(i, j, grid)
            me = int(grid[i][j])
            if myNeighbours == 0:
                rareCase = True
            if me != 0 and myNeighbours < 2:  # underpopulation
                newGrid[i][j] = 0
            if me != 0 and (myNeighbours == 2
                            or myNeighbours == 3):  # next generation
                newGrid[i][j] = 255
            if me != 0 and myNeighbours > 3:  # overpopulation
                newGrid[i][j] = 0
            if me != 255 and myNeighbours == 3:  # reproduction
                newGrid[i][j] = 255
            # count Life patterns if not checked already
            if int(visited[i][j]) == 0:
                res, visited = countLife(i, j, grid, visited, rareCase)
                # if something detected, count it
                if len(res) > 0:
                    reported.append(res)
                    counters[int(res[0])] += 1
                    global TOTAL_COUNTERS
                    TOTAL_COUNTERS[int(res[0])] += 1

    # update total counters for seeds and others
    num, visited = countOthers(grid, visited)
    global TOTAL_OTHERS
    TOTAL_OTHERS += num

    global TOTAL_LIVES
    TOTAL_LIVES += len(reported)

    # report the count at every frame
    handleReport("------ Generation {0} ------\n".format(FRAME))
    handleReport("Total Life Beings: {0}\n".format(len(reported)))
    handleReport("Total Other Beings: {0}\n".format(num))
    handleReport("+++++++++++++++++++++++++++\n")
    for i in range(len(BEINGS)):
        handleReport("{n}: {v}\n".format(n=BEINGS_STR[i], v=int(counters[i])))
    handleReport("+++++++++++++++++++++++++++\n")
    for j in range(len(reported)):
        handleReport("{i}. {n} at {y}, {x}\n".format(
            i=j + 1,
            n=BEINGS_STR[reported[j][0]],
            y=reported[j][1],
            x=reported[j][2]))

    # at last, calculate percentage of appearance
    if frameNum == (G - 1):
        handleReport("======= Incidence % =======\n")
        if TOTAL_LIVES == 0 and TOTAL_OTHERS == 0:
            TOTAL_LIVES = 1  # to avoid div by zero
        for i in range(len(BEINGS)):
            handleReport("{n}: {v} %\n".format(
                n=BEINGS_STR[i],
                v=round(
                    (TOTAL_COUNTERS[i] / (TOTAL_LIVES + TOTAL_OTHERS)) * 100.0,
                    2)))
        handleReport("{n}: {v} %\n".format(
            n="others",
            v=round((TOTAL_OTHERS / (TOTAL_LIVES + TOTAL_OTHERS)) * 100.0, 2)))
        handleReport("", True)
        print("SUCCESS Simulation Report is now available.")

    # update data
    ax.set_title("Conway's Game of Life\nGeneration = {0}".format(frameNum +
                                                                  1))
    img.set_data(newGrid)
    img.set_cmap('binary')
    grid[:] = newGrid[:]
    FRAME += 1
    return img,
def plot_data_since(data_adaptor: DataAdaptor,
                    type_: ValueType,
                    countries: Iterable[str],
                    ax: Axes,
                    start: Optional[int] = None,
                    legend: bool = False) -> None:

    data_country = data_adaptor.get_time_series_for_country(
        type_, countries, start)

    time_data = data_country.index.days if start else data_country.index
    ax.plot(time_data, data_country[countries])
    if legend:
        ax.legend(countries)
    ax.set_yscale("log")
    if start:
        ax.set_xlim(-1.0, data_country.index.days.max())
    ax.set_ylim(start, data_country.max().max())
    ax.set_ylabel(type_.value)
    if start:
        ax.set_xlabel(f"Days since {start} {type_.value}")
    else:
        ax.set_xlabel("Date")
Exemple #16
0
 def draw_samples(self, ax: Axes):
     ax.scatter([s[1] for s in self._samples], [s[0] for s in self._samples], s=1, c='red')
def plot_delta_since(data_adaptor: DataAdaptor,
                     type_: ValueType,
                     countries: Iterable[str],
                     ax: Axes,
                     rolling: int = 1,
                     start: Optional[int] = None,
                     legend: bool = False) -> None:

    data_country = data_adaptor.get_time_delta_for_country(
        type_, countries, start, rolling)
    data_country[data_country <= 0] = np.NAN
    if start:
        data_country = data_country[data_country.index.days >= 0]

    time_data = data_country.index.days if start else data_country.index
    ax.plot(time_data, data_country[countries])
    if legend:
        ax.legend(countries)
    ax.set_yscale("log")
    ax.set_ylim(data_country.min().min(), data_country.max().max())
    ylabel = f"{type_.value} per day"
    if rolling > 1:
        ylabel += f" ({rolling} day moving average)"
    ax.set_ylabel(ylabel)
    if start:
        ax.set_xlabel(f"Days since {start} {type_.value}")
    else:
        ax.set_xlabel("Date")
def prettifyLife(ax: mltax.Axes, N: int) -> None:
    if N <= 50:
        ax.grid()
        ax = plt.gca()
        ax.set_xticks(np.arange(-.5, N - 1, 1))
        ax.set_yticks(np.arange(-.51, N - 1, 1))
        ax.set_xticklabels(np.arange(0, N, 1))
        ax.set_yticklabels(np.arange(0, N, 1))
    elif N > 50 and N < 80:
        ax.grid()
        ax = plt.gca()
        labels = [" " for x in range(N)]
        plt.xticks(np.arange(-.5, N - 1, 1), labels)
        plt.yticks(np.arange(-.51, N - 1, 1), labels)