Exemplo n.º 1
0
 def __init__(self, new_styles: dict, **kwargs):
     from matplotlib import rcParams as params
     self.save = params.copy()
     self.params = params
     self.new_styles = new_styles
     self.kwargs = kwargs
     self.kwargs.pop('new_styles', None)
Exemplo n.º 2
0
 def __init__(self, rc=None, fname=None):
     self.rcdict = rc
     self.fname = fname
     self._rcparams = rcParams.copy()
     if self.fname:
         rc_file(self.fname)
     if self.rcdict:
         rcParams.update(self.rcdict)
Exemplo n.º 3
0
 def __init__(self, rc=None, fname=None):
     self.rcdict = rc
     self.fname = fname
     self._rcparams = rcParams.copy()
     if self.fname:
         rc_file(self.fname)
     if self.rcdict:
         self.rcdict.update({"grid.alpha": 1.0})
         rcParams.update(self.rcdict)
Exemplo n.º 4
0
def ridge_plot(plots_dict, scores_df):
    '''took the following from the seaborn documentation
    https://seaborn.pydata.org/examples/kde_ridgeplot.html
    and applied it to visualizing score distributions
    '''
    ## backup of matplotlib parameters 
    ## to reset at the bottom of this function
    import matplotlib as mpl
    params_backup = rcParams.copy()
    
    ridge_df = scores_df[['label','score']].rename(
            columns={'score':'Score'}
        ).assign(
            **{'label': scores_df['label'].astype(str).map(plots_dict['label_map'])}
        )

    title='Score Distributions of {} vs. {}'\
                         .format(plots_dict['label_map']['1'], 
                                 plots_dict['label_map']['0'])
    sns.set(style='white', rc={'axes.facecolor': (0, 0, 0, 0)})
    
    # Create the data
    pal = sns.cubehelix_palette(3, rot=-.25, light=.7)
    g = sns.FacetGrid(
        ridge_df, row='label', hue='label', 
        aspect=3, height=2.5, palette=['#35978f','#9970ab']
    )

    ## first the curve, then a white line, then axis
    g.map(sns.kdeplot, 'Score', clip_on=False, shade=True, alpha=1, lw=1.5, bw=.2)
    g.map(sns.kdeplot, 'Score', clip_on=False, color='#f0f0f0', lw=2, bw=.2)

    # add nice distribution label on the left
    def label(x, color, label):
        ax = plt.gca()
        ax.text(-0.2, .2, label, fontweight='bold', color=color,
                ha='left', va='center', transform=ax.transAxes)
    g.map(label, 'Score')
    
    g.fig.suptitle(title)
    # add the overlap effect
    g.fig.subplots_adjust(hspace=-.25)
    # get rid of the facet labels
    g.set_titles("")
    g.set(yticks=[])
    g.set(xlim=(0, 1))
    g.despine(bottom=True, left=True)
    g.savefig('{}/score_densities.png'.format(plots_dir))
    plt.clf()
    
    ## reset matplotlib parameters
    mpl.rcParams.update(params_backup)
Exemplo n.º 5
0
 def test_styles(self):
     tmp = rcParams.copy()
     plots.set_active_style(tab10)
     g = plots.get_single_plotter()
     self.assertEqual(g.settings.line_styles.name, 'tab10')
     plots.set_active_style(planck)
     g = plots.get_single_plotter()
     self.assertTrue(g.settings.prob_y_ticks)
     plots.set_active_style(tab10)
     g = plots.get_single_plotter()
     self.assertEqual(g.settings.line_styles.name, 'tab10')
     plots.set_active_style()
     g = plots.get_single_plotter()
     self.assertFalse(g.settings.prob_y_ticks)
     g = plots.get_single_plotter(style='tab10')
     self.assertEqual(g.settings.line_styles.name, 'tab10')
     plots.set_active_style('planck')
     plots.set_active_style()
     self.assertDictEqual(tmp, rcParams)
Exemplo n.º 6
0
 def test_styles(self):
     from getdist.styles.tab10 import style_name as tab10
     from getdist.styles.planck import style_name as planck
     from matplotlib import rcParams
     tmp = rcParams.copy()
     plots.set_active_style(tab10)
     g = plots.get_single_plotter()
     self.assertEqual(g.settings.line_styles.name, 'tab10')
     plots.set_active_style(planck)
     g = plots.get_single_plotter()
     self.assertTrue(g.settings.prob_y_ticks)
     plots.set_active_style(tab10)
     g = plots.get_single_plotter()
     self.assertEqual(g.settings.line_styles.name, 'tab10')
     plots.set_active_style()
     g = plots.get_single_plotter()
     self.assertFalse(g.settings.prob_y_ticks)
     g = plots.get_single_plotter(style='tab10')
     self.assertEqual(g.settings.line_styles.name, 'tab10')
     plots.set_active_style('planck')
     plots.set_active_style()
     self.assertDictEqual(tmp, rcParams)
Exemplo n.º 7
0
def loadstyle(style_name):
    """ Load a custom style file, adding both rcParams and custom params.
    Writing a proper parser for these settings is in the Matplotlib backlog,
    so let's keep calm and avoid inventing their wheel.
    """

    style = {}
    style_file = os.path.join(HERE, '..', 'rc', style_name)
    try:
        # Check rc directory for built in styles first
        rc_file(style_file)
    except FileNotFoundError:
        # Check current working dir or path
        style_file = style_name
        try:
            rc_file(style_file)
        except FileNotFoundError as err:
            raise StyleNotFoundError(f"No such style file found: {err}")
    style = rcParams.copy()

    # The style files may also contain an extra section with typography
    # for titles and captions (these can only be separately styled in code,
    # as of Matplotlib 2.2)
    # This is a hack, but it's nice to have all styling in one file
    # The extra styling is prefixed with `#!`
    with open(style_file, 'r') as file_:
        doc = file_.readlines()
        rc_params_newsworthy = "\n".join(
            [d[2:] for d in doc if d.startswith("#!")])
    rc_params_newsworthy = yaml.safe_load(rc_params_newsworthy)
    ###
    # Typography
    ###
    style["title_font"] = [
        x.strip() for x in rc_params_newsworthy["title_font"].split(",")
    ]

    # define as pt or reltive ("smaller")
    style["subtitle.fontsize"] = rc_params_newsworthy.get(
        "subtitle.fontsize", None)

    # make annotation same font size as ticks by default
    tick_font_size = style.get('xtick.labelsize', "smaller")
    style["annotation.fontsize"] = rc_params_newsworthy.get(
        "annotation.fontsize", tick_font_size)
    style["note.fontsize"] = rc_params_newsworthy.get("note.fontsize",
                                                      "smaller")
    style["caption.fontsize"] = rc_params_newsworthy.get(
        "caption.fontsize", "smaller")

    color = rc_params_newsworthy.get("neutral_color",
                                     rcParams["figure.edgecolor"])
    black_color = rc_params_newsworthy.get("black_color", BLACK)
    dark_gray_color = rc_params_newsworthy.get("dark_gray_color", DARK_GRAY)
    light_gray_color = rc_params_newsworthy.get("light_gray_color", LIGHT_GRAY)
    strong_color = rc_params_newsworthy.get("strong_color", color)
    positive_color = rc_params_newsworthy.get("positive_color", POSITIVE)
    negative_color = rc_params_newsworthy.get("negative_color", NEGATIVE)
    warm_color = rc_params_newsworthy.get("warm_color", WARM)
    cold_color = rc_params_newsworthy.get("cold_color", COLD)
    fill_between_color = rc_params_newsworthy.get("fill_between_color",
                                                  FILL_BETWEEN)
    fill_between_alpha = rc_params_newsworthy.get("fill_between_alpha", 0.5)
    style["black_color"] = to_rgba("#" + str(black_color), 1)
    style["dark_gray_color"] = to_rgba("#" + str(dark_gray_color), 1)
    style["light_gray_color"] = to_rgba("#" + str(light_gray_color), 1)
    style["neutral_color"] = to_rgba("#" + str(color), 1)
    style["strong_color"] = to_rgba("#" + str(strong_color), 1)
    style["positive_color"] = to_rgba("#" + positive_color, 1)
    style["negative_color"] = to_rgba("#" + negative_color, 1)
    style["warm_color"] = to_rgba("#" + warm_color, 1)
    style["cold_color"] = to_rgba("#" + cold_color, 1)
    style["fill_between_color"] = to_rgba("#" + str(fill_between_color), 1)
    style["fill_between_alpha"] = float(fill_between_alpha)

    if "qualitative_colors" in rc_params_newsworthy:
        style["qualitative_colors"] = [
            to_rgba("#" + c.strip(), 1)
            for c in rc_params_newsworthy["qualitative_colors"].split(",")
        ]

    else:
        style["qualitative_colors"] = [
            to_rgba("#" + c, 1) for c in QUALITATIVE
        ]
    if "logo" in rc_params_newsworthy:
        style["logo"] = rc_params_newsworthy["logo"]

    return style
Exemplo n.º 8
0
 def __init__(self, rc=None):
     self.rcdict = rc
     self._rcparams = rcParams.copy()
     if self.rcdict:
         rcParams.update(self.rcdict)
def Film(instance, solution, name, parameters):
    import numpy as np
    import matplotlib.pyplot as plt
    import matplotlib.animation as animation
    import warnings
    import matplotlib.cbook
    warnings.filterwarnings("ignore", category=matplotlib.cbook.mplDeprecation)

    def myround(x, base=5):
        return int(base * round(float(x) / base))

    class Update(object):
        def __init__(self, ax, instance, solution, parameters):
            self.parameters = parameters

            self.ax = ax
            self.instance = instance
            self.solution = solution

            self.X = np.array([loc.X for loc in instance.Locations],
                              dtype=float)
            self.Y = np.array([loc.Y for loc in instance.Locations],
                              dtype=float)

            self.depotLocId = 0
            self.requestLocIds = np.array(
                [r.customerLocID for r in instance.Requests]) - 1
            self.techLocIds = np.array(
                [t.locationID for t in self.instance.Technicians]) - 1

            # https://stackoverflow.com/questions/22408237/named-colors-in-matplotlib
            self.sizes = self.parameters.smallSize * np.ones(len(self.X))
            self.sizes[self.techLocIds] = self.parameters.mediumSize
            self.sizes[0] = self.parameters.largeSize
            self.linewidths = 2 * np.ones(len(self.X))
            self.colors = ['limegreen'] * len(self.sizes)
            self.colors = [
                'gold' if id in self.techLocIds else color
                for id, color in enumerate(self.colors)
            ]
            self.colors[0] = 'aquamarine'
            self.edgecolors = ['tomato'] * len(self.sizes)
            self.edgecolors[0] = 'darkcyan'

            self.waitingFor = np.zeros(len(self.X))

            em = self.parameters.extraMargin
            self.ax.set_xlim(myround(min(self.X) - em),
                             myround(max(self.X) + em))
            self.ax.set_ylim(myround(min(self.Y) - em),
                             myround(max(self.Y) + em))

            self.maxTruckRoutes = 0
            self.maxTechnicianRoutes = 0
            if not solution is None:
                self.maxTruckRoutes = max(
                    [len(day.TruckRoutes) for day in solution.Days])
                self.maxTechnicianRoutes = max(
                    [len(day.TechnicianRoutes) for day in solution.Days])

            self.artists = []
            self.artists.append(
                ax.text(0.05,
                        0.9,
                        '',
                        transform=ax.transAxes,
                        family='monospace',
                        zorder=4,
                        color='blue',
                        bbox=dict(facecolor='yellow', alpha=0.2)))
            self.artists.append(ax.scatter(self.X, self.Y, zorder=3))

            from matplotlib.collections import PatchCollection
            if parameters.actionRadius:
                from matplotlib.patches import Circle
                lo = self.techLocIds
                ar = [t.maxDayDistance / 2 for t in self.instance.Technicians]
                order = reversed(np.argsort(ar))
                circles = [
                    Circle((self.X[lo[i]], self.Y[lo[i]]), ar[i])
                    for i in order
                ]
                self.artists.append(
                    ax.add_collection(PatchCollection(circles, zorder=0)))
            else:
                self.artists.append(
                    ax.add_collection(PatchCollection([], zorder=0)))

            self.text = 0
            self.points = 1
            self.radius = 2

            self.firstTruckRoute = len(self.artists)
            for i in range(self.maxTruckRoutes):
                self.artists.append(ax.plot([], [], linewidth=6, zorder=1)[0])

            self.firstTechnicianRoute = len(self.artists)
            for i in range(self.maxTechnicianRoutes):
                self.artists.append(ax.plot([], [], linewidth=2, zorder=2)[0])

        def frames(self):
            import itertools
            nofDays = self.instance.Days
            if solution is None:
                return [
                    f for f in itertools.product(
                        *[range(nofDays), range(1)])
                ]
            else:
                perDay = max(
                    [t.maxDayDistance for t in self.instance.Technicians] +
                    [self.instance.TruckMaxDistance])
                step = myround(perDay / self.parameters.nofDaySteps)
                return [
                    f for f in itertools.product(*[
                        range(nofDays),
                        range(0, myround(perDay + step), step)
                    ])
                ]

        def init(self):
            self.artists[self.text].set_text('')

            self.artists[self.points].set_sizes(self.sizes)
            self.artists[self.points].set_color(self.colors)
            self.artists[self.points].set_edgecolors(self.edgecolors)
            self.artists[self.points].set_linewidths(self.linewidths)

            self.artists[self.radius].set_facecolor((0, 1, 0, 0.08))
            self.artists[self.radius].set_edgecolor((0, 0, 1, 0.5))
            self.artists[self.radius].set_linestyle('--')

            if not solution is None:
                for i in range(
                        self.firstTruckRoute, self.firstTruckRoute +
                        self.maxTechnicianRoutes + self.maxTruckRoutes):
                    self.artists[i].set_data([], [])

            return self.artists

        def RouteCoordinatesFromRequests(self, requests, includeDepot=True):
            requests = np.array(requests) - 1
            aux = self.requestLocIds[requests]
            aux[requests < 0] = 0
            if not includeDepot:
                aux = aux[aux > 0]
            return aux

        def RouteCoordinatesFromRequestsUpToStep(self, requests, home, step):
            def partial(X, Y, limit):
                def distance(x, y):
                    from scipy.spatial import distance
                    import math
                    return int(math.ceil(distance.euclidean(x, y)))

                points = [(x, y) for x, y in zip(X, Y)]
                segments = np.append(
                    0,
                    [distance(p1, p2) for p1, p2 in zip(points, points[1:])])
                cs = np.cumsum(segments, dtype=int)
                idx, = np.where(cs <= limit)
                if len(idx) < len(X):
                    last = idx[-1]
                    theta = (limit - cs[last]) * 1.0 / segments[last + 1]
                    if theta > 0:
                        X[last + 1] = X[last] + theta * (X[last + 1] - X[last])
                        Y[last + 1] = Y[last] + theta * (Y[last + 1] - Y[last])
                        idx = np.append(idx, last + 1)
                    X = X[idx]
                    Y = Y[idx]
                return X, Y

            route = self.RouteCoordinatesFromRequests(requests)
            route = np.append(home, route)
            route = np.append(route, home)
            return partial(self.X[route], self.Y[route], step)

        def __call__(self, day_and_step):
            i, step = day_and_step
            self.artists[self.text].set_text('{:>5d}@{:<3d}'.format(
                step, i + 1))

            active = list(
                set([
                    r.customerLocID - 1 for r in instance.Requests
                    if r.fromDay <= i + 1 <= r.toDay
                ]))

            import copy
            sizes = copy.copy(self.sizes)
            sizes[active] = self.parameters.largeSize
            self.artists[self.points].set_sizes(sizes)

            if not solution is None:
                day = self.solution.Days[i]
                if step == 0:
                    delivered = sum([truck.Route for truck in day.TruckRoutes],
                                    [])
                    installed = sum([
                        technician.Route for technician in day.TechnicianRoutes
                    ], [])

                    delivered = self.RouteCoordinatesFromRequests(
                        np.array(np.unique(delivered), dtype=int), False)
                    installed = self.RouteCoordinatesFromRequests(
                        np.array(np.unique(installed), dtype=int))

                    self.waitingFor[installed] = 0
                    self.waitingFor[self.waitingFor > 0] = self.waitingFor[
                        self.waitingFor > 0] + 1
                    self.waitingFor[delivered] = 1

                    widths = copy.copy(self.linewidths)
                    widths[self.waitingFor > 0] = 2 * (
                        self.waitingFor[self.waitingFor > 0] + 1)
                    self.artists[self.points].set_linewidths(widths)

                for i in range(
                        self.firstTruckRoute, self.firstTruckRoute +
                        self.maxTechnicianRoutes + self.maxTruckRoutes):
                    self.artists[i].set_data([], [])

                for i, truck in enumerate(day.TruckRoutes):
                    self.artists[self.firstTruckRoute + i].set_data(
                        self.RouteCoordinatesFromRequestsUpToStep(
                            truck.Route, 0, step))

                for i, technician in enumerate(day.TechnicianRoutes):
                    person = self.instance.Technicians[technician.ID - 1]
                    self.artists[self.firstTechnicianRoute + i].set_data(
                        self.RouteCoordinatesFromRequestsUpToStep(
                            technician.Route, person.locationID - 1, step))

            return self.artists

    if parameters.xkcd:
        from matplotlib import rcParams
        saved_state = rcParams.copy()
        plt.xkcd()

    fig = plt.figure()
    plt.axis('equal')
    ax = plt.axes()
    ud = Update(ax, instance, solution, parameters)

    fig.set_size_inches(ud.parameters.inchH, ud.parameters.inchV)
    ani = animation.FuncAnimation(fig,
                                  ud,
                                  frames=ud.frames(),
                                  init_func=ud.init,
                                  blit=True)

    name = name.rsplit('.', 1)[0]

    # install http://www.imagemagick.org/script/download.php#windows for ffmpeg and other writers.
    if ud.parameters.mp4:
        FFwriter = animation.FFMpegWriter(fps=ud.parameters.fps,
                                          extra_args=['-vcodec', 'libx264'])
        ani.save(name + '.mp4', writer=FFwriter)

    if ud.parameters.html:
        ani.save(name + ".htm", writer="html")

    if ud.parameters.pdf:
        from matplotlib.backends.backend_pdf import PdfPages
        with PdfPages(name + '.pdf') as pdf:
            ud.init()
            for f in ud.frames():
                ud(f)
                plt.show()
                pdf.savefig(fig)

    plt.show()
    plt.close()

    if parameters.xkcd:
        from matplotlib import rcParams
        rcParams.update(saved_state)