Пример #1
0
def plot_polygon_collection(ax,
                            geoms,
                            values=None,
                            colormap='gist_rainbow',
                            facecolor=None,
                            edgecolor=None,
                            alpha=0.5,
                            linewidth=1.0,
                            **kwargs):
    """ Plot a collection of Polygon geometries """
    patches = []
    for poly in geoms:
        a = np.asarray(poly.exterior)
        if poly.has_z:
            poly = shapely.geometry.Polygon(zip(*poly.exterior.xy))
        patches.append(Polygon(a))
    patches = PatchCollection(patches,
                              facecolor=facecolor,
                              linewidth=linewidth,
                              edgecolor=edgecolor,
                              alpha=alpha,
                              **kwargs)

    if values is not None:
        patches.set_array(values)
        patches.set_cmap(colormap)
    ax.add_collection(patches, autolim=True)
    ax.autoscale_view()
    return patches
Пример #2
0
def plot_polygon_collection(ax,
                            geoms,
                            values=None,
                            colormap='Greens',
                            facecolor=None,
                            edgecolor=None,
                            alpha=0.7,
                            linewidth=1.0,
                            **kwargs):
    """ Plot a collection of Polygon geometries """

    patches = []

    for poly in geoms:
        a = np.asarray(poly.exterior)
        patches.append(Polygon(a))

    patches = PatchCollection(patches,
                              facecolor=facecolor,
                              linewidth=linewidth,
                              edgecolor=edgecolor,
                              alpha=alpha,
                              **kwargs)

    if values is not None:
        patches.set_array(values)
        patches.set_cmap(colormap)

    ax.add_collection(patches, autolim=True)
    # ax.autoscale_view()
    return patches
Пример #3
0
def plot_distribution(ax,
                      cmap,
                      probabilitydist,
                      fig,
                      time_from,
                      reference_data=None):
    from matplotlib.patches import Rectangle
    from matplotlib.collections import PatchCollection
    patches = []
    colors = []
    for ct, dt in enumerate(probabilitydist):
        disp = 0.0
        if reference_data is not None:
            disp = reference_data[time_from + ct]

        for y in dt.bins:
            s = Rectangle((time_from + ct, y + disp),
                          1,
                          dt.resolution,
                          fill=True,
                          lw=0)
            patches.append(s)
            colors.append(dt.density(y))
    scale = Transformations.Scale()
    colors = scale.apply(colors)
    pc = PatchCollection(patches=patches, match_original=True)
    pc.set_clim([0, 1])
    pc.set_cmap(cmap)
    pc.set_array(np.array(colors))
    ax.add_collection(pc)
    cb = fig.colorbar(pc, ax=ax)
    cb.set_label('Density')
def plotCustomColors(ax,
                     df,
                     column,
                     custom_cmap,
                     linewidth=1.0,
                     alpha=1.0,
                     edgecolor='black'):

    # Get Min and max
    vmin = None
    vmax = None

    # Flatten possible MultiPlygons
    components, component_colors_or_values = _flatten_multi_geoms(
        df['geometry'], df[column])

    collection = PatchCollection([PolygonPatch(poly) for poly in components],
                                 linewidth=linewidth,
                                 edgecolor=edgecolor,
                                 alpha=alpha)
    collection.set_array(np.array(df[column]))
    collection.set_cmap(custom_cmap)
    collection.set_clim(vmin, vmax)
    ax.add_collection(collection, autolim=True)
    return ax
Пример #5
0
def draw_disc(cpx, cpy, area, size):
    # input arguments:
    ## cpx, cpy: x,y/positions of the vertices of all cells
    # format: list (1 element per cell) of sublists (1 number per vertex, eg 3 numbers for a triangle).
    ## area: cell area
    # format: 1-dimentsional numpy array (1 number per cell)
    ## size: 'large' for the large disc and 'small' for the small disc

    polygs = []
    for i in range(len(cpx)):
        polyg = []
        for j in range(len(cpx[i])):
            polyg.append([cpx[i][j], cpy[i][j]])
        polygs.append(Polygon(polyg))
    patches = PatchCollection(polygs)
    patches.set_cmap('jet')
    colors = 1 * area
    colors[
        colors >
        14] = 14  # color value for all the mitotic cells (area>14) is set to 14
    patches.set_array(np.array(colors))  # for colors

    fig = plt.figure()
    panel = fig.add_subplot(1, 1, 1)
    panel.add_collection(patches)
    fig.colorbar(patches)
    panel.set_xlim(min(min(cpx)) - 5, max(max(cpx)) + 5)
    panel.set_ylim(min(min(cpy)) - 5, max(max(cpy)) + 5)
    panel.set_aspect('equal')
    plt.title(size + ' wing disc')
Пример #6
0
def plot_distribution(ax, cmap, probabilitydist, fig, time_from, reference_data=None):
    """
    Plot forecasted ProbabilityDistribution objects on a matplotlib axis

    :param ax: matplotlib axis
    :param cmap: matplotlib colormap name
    :param probabilitydist: list of ProbabilityDistribution objects
    :param fig: matplotlib figure
    :param time_from: starting time (on x axis) to begin the plots
    :param reference_data:
    :return:
    """
    from matplotlib.patches import Rectangle
    from matplotlib.collections import PatchCollection
    patches = []
    colors = []
    for ct, dt in enumerate(probabilitydist):
        disp = 0.0
        if reference_data is not None:
            disp = reference_data[time_from+ct]

        for y in dt.bins:
            s = Rectangle((time_from+ct, y+disp), 1, dt.resolution, fill=True, lw = 0)
            patches.append(s)
            colors.append(dt.density(y))
    scale = Transformations.Scale()
    colors = scale.apply(colors)
    pc = PatchCollection(patches=patches, match_original=True)
    pc.set_clim([0, 1])
    pc.set_cmap(cmap)
    pc.set_array(np.array(colors))
    ax.add_collection(pc)
    cb = fig.colorbar(pc, ax=ax)
    cb.set_label('Density')
Пример #7
0
def plot_polygon_collection(ax,
                            geoms,
                            values=None,
                            color=None,
                            cmap=None,
                            vmin=None,
                            vmax=None,
                            **kwargs):
    """
    Plots a collection of Polygon and MultiPolygon geometries to `ax`
    Parameters
    ----------
    ax : matplotlib.axes.Axes
        where shapes will be plotted
    geoms : a sequence of `N` Polygons and/or MultiPolygons (can be mixed)
    values : a sequence of `N` values, optional
        Values will be mapped to colors using vmin/vmax/cmap. They should
        have 1:1 correspondence with the geometries (not their components).
        Otherwise follows `color` / `facecolor` kwargs.
    edgecolor : single color or sequence of `N` colors
        Color for the edge of the polygons
    facecolor : single color or sequence of `N` colors
        Color to fill the polygons. Cannot be used together with `values`.
    color : single color or sequence of `N` colors
        Sets both `edgecolor` and `facecolor`
    **kwargs
        Additional keyword arguments passed to the collection
    Returns
    -------
    collection : matplotlib.collections.Collection that was plotted
    """
    from descartes.patch import PolygonPatch
    from matplotlib.collections import PatchCollection

    geoms, values = _flatten_multi_geoms(geoms, values)
    if None in values:
        values = None

    # PatchCollection does not accept some kwargs.
    if 'markersize' in kwargs:
        del kwargs['markersize']

    # color=None overwrites specified facecolor/edgecolor with default color
    if color is not None:
        kwargs['color'] = color

    collection = PatchCollection([PolygonPatch(poly) for poly in geoms],
                                 **kwargs)

    if values is not None:
        collection.set_array(np.asarray(values))
        collection.set_cmap(cmap)
        collection.set_clim(vmin, vmax)

    ax.add_collection(collection, autolim=True)
    ax.autoscale_view()
    return collection
Пример #8
0
def draw_voronoi(box, cells, ax=None):
    """Helper function to draw 2D Voronoi diagram.

    Args:
        box (:class:`freud.box.Box`):
            Simulation box.
        cells (:class:`numpy.ndarray`):
            Array containing Voronoi polytope vertices.
        color_by_sides (bool):
            If :code:`True`, color cells by the number of sides.
            (Default value = :code:`False`)
        ax (:class:`matplotlib.axes.Axes`): axes object to plot.
            If :code:`None`, make a new axes and figure object.
            (Default value = :code:`None`).

    Returns:
        :class:`matplotlib.axes.Axes`: axes object with the diagram.
    """
    if not MATPLOTLIB:
        return None
    try:
        from matplotlib import cm
        from matplotlib.collections import PatchCollection
        from matplotlib.patches import Polygon, Rectangle
    except ImportError:
        return None

    if ax is None:
        fig = Figure()
        ax = fig.subplots()

    # Draw Voronoi cells
    patches = [Polygon(cell[:, :2]) for cell in cells]
    patch_collection = PatchCollection(patches, edgecolors='black', alpha=0.4)
    cmap = cm.Set1

    colors = np.random.permutation(np.arange(len(patches)))

    cmap = cm.get_cmap('Set1', np.unique(colors).size)
    bounds = np.array(range(min(colors), max(colors)+2))

    patch_collection.set_array(np.array(colors))
    patch_collection.set_cmap(cmap)
    patch_collection.set_clim(bounds[0], bounds[-1])
    ax.add_collection(patch_collection)

    ax.set_title('Voronoi Diagram')
    ax.set_xlim((-box.Lx/2, box.Lx/2))
    ax.set_ylim((-box.Ly/2, box.Ly/2))

    # Set equal aspect and draw box
    ax.set_aspect('equal', 'datalim')
    box_patch = Rectangle([-box.Lx/2, -box.Ly/2], box.Lx,
                          box.Ly, alpha=1, fill=None)
    ax.add_patch(box_patch)
    return ax
def paw_plot(sdata=None, sdata_bg=None, cdata=None, cmap=None, clim=None, edgecolor='#555555', bgcolor='#cccccc', legend=True, ax=None):
    ax = ax if ax else plt.gca()
        
    r = np.array([ 0, 1, 1, 1, 1, 1 ])
    theta = np.array([ 0, 30, 75, 120, 165, 210 ]) * np.pi / 180.0
    theta = np.array([ -5, 25, 70, 115, 160, 205 ]) * np.pi / 180.0
#    theta = np.array([ 0, 30, 72, 114, 156, 198 ]) * np.pi / 180.0
    
    if sdata is None:
        sdata = np.array([4,1,1,1,1,1])*.08
                
    if cdata is None:
        cdata = np.ones(len(r))
    
    if cmap is None:
        cmap = 'magma'
        
    if clim is None:
        clim = [0,1]
    
    xx = r * np.cos(theta)
    yy = r * np.sin(theta)            
    
    patches = [ mpatch.Circle((x,y),rad) for (x,y,rad) in zip(xx,yy,np.sqrt(sdata)) ]
    col = PatchCollection(patches, zorder=2)
    col.set_array(cdata)    
    col.set_cmap(cmap)
    col.set_edgecolor(edgecolor)
    col.set_clim(vmin=clim[0], vmax=clim[1])        
    
    ax.add_patch(mpatch.Arc((0.0, 0.0), 2.0, 2.0, angle=0.0, 
                            theta1=theta[1]*180.0/np.pi, theta2=theta[-1]*180.0/np.pi, 
                            edgecolor=edgecolor,facecolor='none', zorder=0, linestyle='--'))
   
    ax.add_collection(col)
    
    
    if legend:
        plt.colorbar(col)
        
    if sdata_bg is not None: 
        patches = [ mpatch.Circle((x,y),rad) for (x,y,rad) in zip(xx,yy,np.sqrt(sdata_bg)) ]
        col = PatchCollection(patches, zorder=1)
        col.set_edgecolor(edgecolor)
        col.set_facecolor(bgcolor)
        ax.add_collection(col)   
    
    ax.axis('equal')   
    ax.axis('off')
    
    ax.set_xlim([-1.2,1.2])
    ax.set_ylim([-.8,1.35])
Пример #10
0
def draw1DColumn(ax,
                 x,
                 val,
                 thk,
                 width=30,
                 ztopo=0,
                 cmin=1,
                 cmax=1000,
                 cmap=None,
                 name=None,
                 textoffset=0.0):
    """Draw a 1D column (e.g., from a 1D inversion) on a given ax.

    Examples
    --------
    >>> import numpy as np
    >>> import matplotlib.pyplot as plt
    >>> from pygimli.mplviewer import draw1DColumn
    >>> thk = [1, 2, 3, 4]
    >>> val = thk
    >>> fig, ax = plt.subplots()
    >>> draw1DColumn(ax, 0.5, val, thk, width=0.1, cmin=1, cmax=4, name="VES")
    <matplotlib.collections.PatchCollection object at ...>
    >>> ax.set_ylim(-np.sum(thk), 0)
    (-10, 0)
    """
    z = -np.hstack((0., np.cumsum(thk), np.sum(thk) * 1.5)) + ztopo
    recs = []
    for i in range(len(val)):
        recs.append(Rectangle((x - width / 2., z[i]), width, z[i + 1] - z[i]))

    pp = PatchCollection(recs)
    col = ax.add_collection(pp)

    pp.set_edgecolor(None)
    pp.set_linewidths(0.0)

    if cmap is not None:
        if isinstance(cmap, str):
            pp.set_cmap(pg.mplviewer.cmapFromName(cmap))
        else:
            pp.set_cmap(cmap)

    pp.set_norm(colors.LogNorm(cmin, cmax))
    pp.set_array(np.array(val))
    pp.set_clim(cmin, cmax)
    if name:
        ax.text(x + textoffset, ztopo, name, ha='center', va='bottom')

    updateAxes_(ax)

    return col
Пример #11
0
    def create_warming_strips_plot(df):
        FIRST = 2020
        LAST = 2021  # inclusive

        # Reference period for the center of the color scale
        FIRST_REFERENCE = 1971
        LAST_REFERENCE = 2000
        LIM = 0.7  # degrees

        # the colors in this colormap come from http://colorbrewer2.org
        # the 8 more saturated colors from the 9 blues / 9 reds

        cmap = ListedColormap([
            '#08306b',
            '#08519c',
            '#2171b5',
            '#4292c6',
            '#6baed6',
            '#9ecae1',
            '#c6dbef',
            '#deebf7',
            '#fee0d2',
            '#fcbba1',
            '#fc9272',
            '#fb6a4a',
            '#ef3b2c',
            '#cb181d',
            '#a50f15',
            '#67000d',
        ])

        fig = plt.figure(figsize=(10, 1))

        ax = fig.add_axes([0, 0, 1, 1])
        ax.set_axis_off()

        # create a collection with a rectangle for each year

        col = PatchCollection(
            [Rectangle((y, 0), 1, 1) for y in range(FIRST, LAST + 1)])

        # set data, colormap and color limits

        col.set_array(anomaly)
        col.set_cmap(cmap)
        col.set_clim(reference - LIM, reference + LIM)
        ax.add_collection(col)
        ax.set_ylim(0, 1)
        ax.set_xlim(FIRST, LAST + 1)

        fig.savefig('{}_warming_stripes.png'.format(CMIP6_name))
Пример #12
0
class ArrayDisplay:
    """
    Display a top-town view of a telescope array
    """
    def __init__(self,
                 telx,
                 tely,
                 mirrorarea,
                 axes=None,
                 title="Array",
                 autoupdate=True):

        patches = [
            Circle(xy=(x, y), radius=np.sqrt(a))
            for x, y, a in zip(telx, tely, mirrorarea)
        ]

        self.autoupdate = autoupdate
        self.telescopes = PatchCollection(patches)
        self.telescopes.set_clim(0, 100)
        self.telescopes.set_array(np.zeros(len(telx)))
        self.telescopes.set_cmap('spectral_r')
        self.telescopes.set_edgecolor('none')

        self.axes = axes if axes is not None else plt.gca()
        self.axes.add_collection(self.telescopes)
        self.axes.set_aspect(1.0)
        self.axes.set_title(title)
        self.axes.set_xlim(-1000, 1000)
        self.axes.set_ylim(-1000, 1000)

        self.bar = plt.colorbar(self.telescopes)
        self.bar.set_label("Value")

    @property
    def values(self):
        """An array containing a value per telescope"""
        return self.telescopes.get_array()

    @values.setter
    def values(self, values):
        """ set the telescope colors to display  """
        self.telescopes.set_array(values)
        self._update()

    def _update(self):
        """ signal a redraw if necessary """
        if self.autoupdate:
            plt.draw()
Пример #13
0
def plot_polygons(geoms,
                  ax,
                  values=None,
                  colormap='Set1',
                  facecolor=None,
                  edgecolor=None,
                  alpha=1.0,
                  linewidth=1.0,
                  **kwargs):
    """Makes a MatPlotLib PatchCollection out of Polygon and/or MultiPolygon geometries 
     Thanks to http://stackoverflow.com/a/33753927 and David Sullivan"""

    # init list to store
    patches = []
    newvals = []

    for polynum in range(len(geoms)):  # for  polygon # i
        poly = geoms.iloc[polynum]  # find data.geometry[i]
        if type(
                poly
        ) != shapely.geometry.polygon.Polygon:  # if that is not a shapely Polygon object
            for currpoly in poly.geoms:  # then for data.geometry[i].geoms
                a = np.asarray(
                    currpoly.exterior
                )  # make a an array of those exterior values and
                patches.append(Polygon(a))  # append ato patches
                if values is not None:  # if values, add value to newvals
                    newvals.append(values.iloc[polynum])
        else:
            a = np.asarray(poly.exterior)
            patches.append(Polygon(a))
            if values is not None:
                newvals.append(values.iloc[polynum])

    patches = PatchCollection(patches,
                              facecolor=facecolor,
                              linewidth=linewidth,
                              edgecolor=edgecolor,
                              alpha=alpha,
                              **kwargs)
    if values is not None:
        patches.set_array(np.asarray(newvals))
        patches.set_cmap(colormap)
        norm = matplotlib.colors.Normalize()
        norm.autoscale(newvals)
        patches.set_norm(norm)
    ax.add_collection(patches, autolim=True)
    ax.autoscale_view()
    return patches
Пример #14
0
def plot_density_rectange(ax, cmap, density, fig, resolution, time_from,
                          time_to):
    from matplotlib.patches import Rectangle
    from matplotlib.collections import PatchCollection
    patches = []
    colors = []
    for x in density.index:
        for y in density.columns:
            s = Rectangle((time_from + x, y), 1, resolution, fill=True, lw=0)
            patches.append(s)
            colors.append(density[y][x] * 5)
    pc = PatchCollection(patches=patches, match_original=True)
    pc.set_clim([0, 1])
    pc.set_cmap(cmap)
    pc.set_array(np.array(colors))
    ax.add_collection(pc)
    cb = fig.colorbar(pc, ax=ax)
    cb.set_label('Density')
Пример #15
0
class ArrayDisplay:

    """
    Display a top-town view of a telescope array
    """

    def __init__(self, telx, tely, mirrorarea,
                 axes=None, title="Array", autoupdate=True):

        patches = [Circle(xy=(x, y), radius=np.sqrt(a))
                   for x, y, a in zip(telx, tely, mirrorarea)]

        self.autoupdate = autoupdate
        self.telescopes = PatchCollection(patches)
        self.telescopes.set_clim(0, 100)
        self.telescopes.set_array(np.zeros(len(telx)))
        self.telescopes.set_cmap('spectral_r')
        self.telescopes.set_edgecolor('none')

        self.axes = axes if axes is not None else plt.gca()
        self.axes.add_collection(self.telescopes)
        self.axes.set_aspect(1.0)
        self.axes.set_title(title)
        self.axes.set_xlim(-1000, 1000)
        self.axes.set_ylim(-1000, 1000)

        self.bar = plt.colorbar(self.telescopes)
        self.bar.set_label("Value")

    @property
    def values(self):
        """An array containing a value per telescope"""
        return self.telescopes.get_array()

    @values.setter
    def values(self, values):
        """ set the telescope colors to display  """
        self.telescopes.set_array(values)
        self._update()

    def _update(self):
        """ signal a redraw if necessary """
        if self.autoupdate:
            plt.draw()
Пример #16
0
def draw1DColumn(ax, x, val, thk, width=30, ztopo=0, cmin=1, cmax=1000,
                 cmap=None, name=None, textoffset=0.0):
    """Draw a 1D column (e.g., from a 1D inversion) on a given ax.

    Examples
    --------
    >>> import numpy as np
    >>> import matplotlib.pyplot as plt
    >>> from pygimli.mplviewer import draw1DColumn
    >>> thk = [1, 2, 3, 4]
    >>> val = thk
    >>> fig, ax = plt.subplots()
    >>> draw1DColumn(ax, 0.5, val, thk, width=0.1, cmin=1, cmax=4, name="VES")
    <matplotlib.collections.PatchCollection object at ...>
    >>> ax.set_ylim(-np.sum(thk), 0)
    (-10, 0)
    """
    z = -np.hstack((0., np.cumsum(thk), np.sum(thk) * 1.5)) + ztopo
    recs = []
    for i in range(len(val)):
        recs.append(Rectangle((x - width / 2., z[i]), width, z[i + 1] - z[i]))

    pp = PatchCollection(recs)
    col = ax.add_collection(pp)

    pp.set_edgecolor(None)
    pp.set_linewidths(0.0)

    if cmap is not None:
        if isinstance(cmap, str):
            pp.set_cmap(pg.mplviewer.cmapFromName(cmap))
        else:
            pp.set_cmap(cmap)

    pp.set_norm(colors.LogNorm(cmin, cmax))
    pp.set_array(np.array(val))
    pp.set_clim(cmin, cmax)
    if name:
        ax.text(x+textoffset, ztopo, name, ha='center', va='bottom')

    updateAxes_(ax)

    return col
Пример #17
0
def draw_patches(list_of_polygons,
                 intensity_list=None,
                 cm='inferno',
                 empty_face=False,
                 norm=None,
                 alpha=None):
    patches = [Polygon(polygon, lw=0.1) for polygon in list_of_polygons]
    pc = PatchCollection(patches)
    if not empty_face:
        if intensity_list is None:
            raise ValueError('values not provided for Voronoi plot.')
        pc.set_array(np.array(intensity_list))
        pc.set_edgecolor('face')
        pc.set_cmap(cm)
        pc.set_norm(norm)
    else:
        pc.set_edgecolor([0.3, 0.3, 0.5])
        pc.set_facecolor([0, 0, 0, 0])
    return pc
Пример #18
0
def make_collection(map, df_plotvar_t, cmap, tick_values, variable_scale,
    plotvar_bounds, groupvar):
    patches = []
    colors = []

    if variable_scale=="logodds":
        df_plotvar_t = logit(df_plotvar_t)
    else:
        pass

    if groupvar == "country_id":
        for info, shape in zip(map.ID_info, map.ID):
            gid = info['ID']
            if gid in df_plotvar_t.index.values:
                prob = df_plotvar_t.loc[gid]
                patch = Polygon(np.array(shape), True)
                patches.append(patch)
                colors.append(prob)

    elif groupvar == "pg_id":
        for info, shape in zip(map.GID_info, map.GID):
            gid = info['GID']
            if gid in df_plotvar_t.index.values:
                prob = df_plotvar_t.loc[gid]
                patch = Polygon(np.array(shape), True)
                patches.append(patch)
                colors.append(prob)
    else:
        raise NotImplementedError

    collection = PatchCollection(patches, zorder=2)
    collection.set_array(np.array(colors).flatten())
    collection.set_cmap(cmap)


    # If we have custom tick values, set the ticks as the colorlimit
    if tick_values:
        collection.set_clim(np.min(tick_values), np.max(tick_values))
    else:
        collection.set_clim(plotvar_bounds[0], plotvar_bounds[1])

    return collection
Пример #19
0
def visualise(sim):
    X = np.arange(sim.A.size).reshape(sim.A.shape) % sim.A.shape[0]
    Y = (np.arange(sim.A.size).reshape(sim.A.shape) % sim.A.shape[1]).T

    U = cos(sim.A)
    V = sin(sim.A)

    fig, ax = plt.subplots(1, 1, figsize=(15, 15))

    rects = []

    # create rectangles for vortex/antivortex determination
    for i in range(sim.V.shape[0]):
        for j in range(sim.V.shape[1]):
            rect = patches.Rectangle(xy=(i, j), height=1, width=1)
            rects.append(rect)
    rects = PatchCollection(rects)

    # Set colors for the rectangles
    col = 'RdBu'
    r_cmap = plt.get_cmap(col)
    r_cmap_r = plt.get_cmap(col + "_r") #eto kostil' =)
    rects.set_cmap(r_cmap)
    rects.set_clim(vmin=-1, vmax=1)

    rects.set_animated(True)
    rects.set_array(sim.V.flatten('F') / 2)
    ax.add_collection(rects)

    # create legend
    legend_boxes = [patches.Patch(facecolor=r_cmap(0.7), label='Antiortex'),
                    patches.Patch(facecolor=r_cmap_r(0.7), label='Vortex')]
    ax.legend(handles=legend_boxes)

    # build an initial quiver plot
    q = ax.quiver(X, Y, U, V, pivot='tail', cmap=plt.cm.get_cmap('hsv'), units='inches', scale=4)
    fig.colorbar(q, label='Angles (2 pi)')
    ax.set_xlim(-1, sim.A.shape[0])
    ax.set_ylim(-1, sim.A.shape[1])
    q.set_UVC(U, V, C=sim.A)

    return q, fig, rects
Пример #20
0
def draw_disc(cpx, cpy, area, size):
    polygs = []
    for i in range(len(cpx)):
        polyg = []
        for j in range(len(cpx[i])):
            polyg.append([cpx[i][j], cpy[i][j]])
        polygs.append(Polygon(polyg))
    patches = PatchCollection(polygs)
    patches.set_cmap('jet')
    colors = 1 * area
    colors[colors > 14] = 14
    patches.set_array(np.array(colors))  #for colors

    fig = plt.figure()
    panel = plt.gca()
    panel.add_collection(patches)
    fig.colorbar(patches)
    panel.set_xlim(min(min(cpx)) - 5, max(max(cpx)) + 5)
    panel.set_ylim(min(min(cpy)) - 5, max(max(cpy)) + 5)
    panel.set_aspect('equal')
    plt.title(size + ' wing disc')
Пример #21
0
def draw_map(map: GeographicalMap, mode='random', data=None):
    fig, ax = plt.subplots(figsize=(18, 10))
    ax.set_xlim(map.xmin, map.xmax)
    ax.set_ylim(map.ymin, map.ymax)

    patches = PatchCollection(
        [matplotlib.patches.Polygon(p, fill=False) for p in map.polygons])

    to_line = lambda e: map.centroids[(e.v1, e.v2), :]
    land_edges = [to_line(e) for e in map.edges.values() if e.type == 'land']
    air_edges = [to_line(e) for e in map.edges.values() if e.type == 'air']
    land_edges = LineCollection(land_edges, linewidths=0.3, colors='red')
    air_edges = LineCollection(air_edges, linewidths=0.1, colors='green')

    ax.add_collection(patches)

    if mode == 'random':
        patches.set_array(np.random.randint(0, 20, size=map.N))
        patches.set_cmap(matplotlib.cm.jet)
    elif mode == 'population':
        patches.set_array(map.population)
        patches.set_cmap(matplotlib.cm.jet)
        patches.set_norm(matplotlib.colors.LogNorm())
        plt.colorbar(patches, ax=ax)
    elif mode == 'graph':
        patches.set_color('black')
        patches.set_facecolor('white')
        patches.set_linewidth(0.1)
        ax.scatter(map.centroids[:, 0], map.centroids[:, 1], s=5)

        # Plot edges.
        ax.add_collection(land_edges)
        ax.add_collection(air_edges)
    elif mode == 'data':
        patches.set_array(data)
        patches.set_cmap(matplotlib.cm.jet)
        plt.colorbar(patches, ax=ax)

    plt.show()
Пример #22
0
def patchValMap(vals, xvec=None, yvec=None, ax=None, cMin=None, cMax=None,
                logScale=None, label=None, dx=1, dy=None, **kwargs):
    """Plot previously generated (generateVecMatrix) y map (category).

    Parameters
    ----------
    vals : iterable
        to show
    xvec : dict {i:num}
        dict (must match vals.shape[0])
    ymap : iterable
        vector for x axis (must match vals.shape[0])
    ax : mpl.axis
        axis to plot, if not given a new figure is created
    cMin/cMax : float
        minimum/maximum color values
    logScale : bool
        logarithmic colour scale [min(vals)>0]
    label : string
        colorbar label
    """
    if cMin is None:
        cMin = np.min(vals)
    if cMax is None:
        cMax = np.max(vals)

    if logScale is None:
        logScale = (cMin > 0.0)

    norm = None
    if logScale and cMin > 0:
        norm = LogNorm(vmin=cMin, vmax=cMax)
    else:
        norm = Normalize(vmin=cMin, vmax=cMax)

    if 'ax' is None:
        ax = plt.subplots()[1]

    recs = []
    if dy is None:  # map y values to unique
        ymap = {xy: ii for ii, xy in enumerate(np.unique(yvec))}
        for i in range(len(vals)):
            recs.append(Rectangle((xvec[i] - dx / 2, ymap[yvec[i]] - 0.5),
                                  dx, 1))
    else:
        for i in range(len(vals)):
            recs.append(Rectangle((xvec[i] - dx / 2, yvec[i] - dy / 2),
                                  dx, dy))

    pp = PatchCollection(recs)
    # ax.clear()
    col = ax.add_collection(pp)
    pp.set_edgecolor(None)
    pp.set_linewidths(0.0)

    cmap = pg.mplviewer.cmapFromName(**kwargs)
    cmap.set_bad('grey')
    if kwargs.pop('markOutside', True):
        cmap.set_under('darkgrey')
        cmap.set_bad('lightgrey')
    pp.set_cmap(cmap)

    pp.set_norm(norm)
    pp.set_array(np.array(vals))
    pp.set_clim(cMin, cMax)
    ax.set_xlim(min(xvec) - dx / 2, max(xvec) + dx / 2)
    ax.set_ylim(len(ymap) - 0.5, -0.5)

    updateAxes_(ax)
    cbar = kwargs.pop('colorBar', True)

    if cbar is True:  # not for cbar=1, which is really confusing!
        cbar = pg.mplviewer.createColorBar(col, cMin=cMin, cMax=cMax,
                                           nLevs=5, label=label)
    elif cbar is not False:  # what the hell is this?
        pg.mplviewer.updateColorBar(cbar, cMin=cMin, cMax=cMax,
                                    nLevs=5, label=label)

    return ax, cbar, ymap
    # but each (x, y) grid point in the DataFrame is defined at its center,
    # so generate xy pairs by shifting down and left by (dx/2, dy/2)
    xy_pairs = zip(df['x'].values - p['dx']/2., df['y'].values - p['dy']/2.)
    patches = [Rectangle(xy, width=p['dx'], height=p['dy']) for xy in xy_pairs]

    # build PatchCollection from the Patches
    from matplotlib.collections import PatchCollection
    pc = PatchCollection(patches, edgecolor='None')
    patches = None # patches is huge (~2 GB!), so clear it from RAM ASAP
    pickle.dump(pc, open(pc_fname, 'w')) # cache PatchCollection so it can be reused

# give soil moisture data to the PatchCollection
pc.set_array(df[map_var].values)

# color the PatchCollection based on soil moisture
pc.set_cmap(cmap) # set color map
if 'ticks' in map_vars[map_var].keys(): # set color map limits based on min/max tick values
    pc.set_clim([min(map_vars[map_var]['ticks']),
                max(map_vars[map_var]['ticks'])])

## Plot the map
from matplotlib import use
use('agg') # prevent matplotlib from using interactive mode

import matplotlib.pyplot as plt

# create the figure
size = (w/float(dpi), h/float(dpi)) # convert to from pixels to inches
fig = plt.figure(1, size, dpi=dpi)

# create axes and add the PatchCollection
Пример #24
0
    def Plot2D(self, xy=None, elecon=None, u=None, color=None, ax=None, show=0,
               weight=None, colorby=None, linestyle='-', label=None, xlim=None,
               ylim=None, filename=None, **kwds):
        assert self.dimensions == 2
        from matplotlib.patches import Polygon
        import matplotlib.lines as mlines
        from matplotlib.collections import PatchCollection
        from matplotlib.cm import coolwarm, Spectral
        import matplotlib.pyplot as plt

        if xy is None:
            xy = array(self.coord)
        if elecon is None:
            elecon = []
            for blk in self.eleblx:
                elecon.extend(blk.elecon.tolist())
            elecon = asarray(elecon)
        if u is not None:
            xy += u.reshape(xy.shape)

        patches = []
        for points in xy[elecon[:]]:
            quad = Polygon(points, True)
            patches.append(quad)

        if ax is None:
            fig, ax = plt.subplots()

        #colors = 100 * random.rand(len(patches))
        p = PatchCollection(patches, linewidth=weight, **kwds)
        if colorby is not None:
            colorby = asarray(colorby).flatten()
            if len(colorby) == len(xy):
                # average value in element
                colorby = array([average(colorby[points]) for points in elecon])
            p.set_cmap(Spectral)  #coolwarm)
            p.set_array(colorby)
            p.set_clim(vmin=colorby.min(), vmax=colorby.max())
            fig.colorbar(p)
        else:
            p.set_edgecolor(color)
            p.set_facecolor('None')
            p.set_linewidth(weight)
            p.set_linestyle(linestyle)

        if label:
            ax.plot([], [], color=color, linestyle=linestyle, label=label)

        ax.add_collection(p)

        if not ylim:
            ymin, ymax = amin(xy[:,1]), amax(xy[:,1])
            dy = max(abs(ymin*.05), abs(ymax*.05))
            ax.set_ylim([ymin-dy, ymax+dy])
        else:
            ax.set_ylim(ylim)

        if not xlim:
            xmin, xmax = amin(xy[:,0]), amax(xy[:,0])
            dx = max(abs(xmin*.05), abs(xmax*.05))
            ax.set_xlim([xmin-dx, xmax+dx])
        else:
            ax.set_xlim(xlim)
        ax.set_aspect('equal')

        if show:
            plt.show()

        if filename is not None:
            plt.legend()
            plt.savefig(filename, transparent=True,
                        bbox_inches="tight", pad_inches=0)

        return ax
Пример #25
0
def voronoi_plot(box, polytopes, ax=None, color_by_sides=True, cmap=None):
    """Helper function to draw 2D Voronoi diagram.

    Args:
        box (:class:`freud.box.Box`):
            Simulation box.
        polytopes (:class:`numpy.ndarray`):
            Array containing Voronoi polytope vertices.
        ax (:class:`matplotlib.axes.Axes`): Axes object to plot.
            If :code:`None`, make a new axes and figure object.
            (Default value = :code:`None`).
        color_by_sides (bool):
            If :code:`True`, color cells by the number of sides.
            If :code:`False`, random colors are used for each cell.
            (Default value = :code:`True`).
        cmap (str):
            Colormap name to use (Default value = :code:`None`).

    Returns:
        :class:`matplotlib.axes.Axes`: Axes object with the diagram.
    """
    from matplotlib import cm
    from matplotlib.collections import PatchCollection
    from matplotlib.patches import Polygon
    from mpl_toolkits.axes_grid1.axes_divider import make_axes_locatable
    from matplotlib.colorbar import Colorbar

    if ax is None:
        fig = Figure()
        ax = fig.subplots()

    # Draw Voronoi polytopes
    patches = [Polygon(poly[:, :2]) for poly in polytopes]
    patch_collection = PatchCollection(patches, edgecolors='black', alpha=0.4)

    if color_by_sides:
        colors = np.array([len(poly) for poly in polytopes])
        num_colors = np.ptp(colors) + 1
    else:
        colors = np.random.RandomState().permutation(np.arange(len(patches)))
        num_colors = np.unique(colors).size

    # Ensure we have enough colors to uniquely identify the cells
    if cmap is None:
        if color_by_sides and num_colors <= 10:
            cmap = 'tab10'
        else:
            if num_colors > 20:
                warnings.warn('More than 20 unique colors were requested. '
                              'Consider providing a colormap to the cmap '
                              'argument.', UserWarning)
            cmap = 'tab20'
    cmap = cm.get_cmap(cmap, num_colors)
    bounds = np.arange(np.min(colors), np.max(colors)+1)

    patch_collection.set_array(np.array(colors)-0.5)
    patch_collection.set_cmap(cmap)
    patch_collection.set_clim(bounds[0]-0.5, bounds[-1]+0.5)
    ax.add_collection(patch_collection)

    # Draw box
    corners = [[0, 0, 0], [0, 1, 0], [1, 1, 0], [1, 0, 0]]
    # Need to copy the last point so that the box is closed.
    corners.append(corners[0])
    corners = box.make_absolute(corners)[:, :2]
    ax.plot(corners[:, 0], corners[:, 1], color='k')

    # Set title, limits, aspect
    ax.set_title('Voronoi Diagram')
    ax.set_xlim((np.min(corners[:, 0]), np.max(corners[:, 0])))
    ax.set_ylim((np.min(corners[:, 1]), np.max(corners[:, 1])))
    ax.set_aspect('equal', 'datalim')

    # Add colorbar for number of sides
    if color_by_sides:
        ax_divider = make_axes_locatable(ax)
        cax = ax_divider.append_axes("right", size="7%", pad="10%")
        cb = Colorbar(cax, patch_collection)
        cb.set_label("Number of sides")
        cb.set_ticks(bounds)
    return ax
Пример #26
0
max_abs = np.max(np.abs(year_mean))


fig = plt.figure(figsize=(12, 6))
ax1 = fig.add_subplot(2, 1, 1)
ax2 = fig.add_subplot(2, 1, 2)


cmap = plt.get_cmap('RdBu_r')

rectangles = [Rectangle((year, 0), 1, 1) for year in year_mean.index]


col1 = PatchCollection(rectangles)
col1.set_array(year_mean)
col1.set_cmap(cmap)
col2 = deepcopy(col1)
col2.set_clim(-max_abs, max_abs)

ax1.add_collection(col1)
ax2.add_collection(col2)

for ax in (ax1, ax2):
    ax.set_ylim(0, 1)
    ax.set_yticks([])
    ax.set_xlim(1880, 2019)

ax1.set_title('Color scale over full range')
ax2.set_title('Color scale centered at 0°C')
fig.colorbar(col1, ax=ax1, label='GTA / °C')
fig.colorbar(col2, ax=ax2, label='GTA / °C')
Пример #27
0
class CameraDisplay:

    """Camera Display using matplotlib.

    Parameters
    ----------
    geometry : `~ctapipe.io.CameraGeometry`
        Definition of the Camera/Image
    axis : `matplotlib.axes.Axes`
        A matplotlib axes object to plot on, or None to create a new one
    title : str
        Title to put on camera plot
    allow_pick : bool (default False)
        if True, allow user to click and select a pixel
    autoupdate : bool (default True)
        redraw automatically (otherwise need to call plt.draw())
    antialiased : bool  (default True)
        whether to draw in antialiased mode or not.

    Notes
    -----

    Speed: 
        CameraDisplay is not intended to be very fast (matplotlib
        is not a very speed performant graphics library, it is
        intended for nice output plots). However, most of the
        slowness of CameraDisplay is in the constructor.  Once one is
        displayed, changing the image that is displayed is relatively
        fast and efficient. Therefore it is best to initialize an
        instance, and change the data, rather than generating new
        CameraDisplays.

    Pixel Implementation: 
        Pixels are rendered as a
        `matplotlib.collections.PatchCollection` of Polygons (either 6
        or 4 sided).  You can access the PatchCollection directly (to
        e.g. change low-level style parameters) via
        `CameraDisplay.pixels`

    Output: 
        Since CameraDisplay uses matplotlib, any display can be
        saved to any output file supported via
        plt.savefig(filename). This includes `.pdf` and `.png`.

    """

    def __init__(self, geometry, axes=None, title="Camera",
                 allow_pick=False, autoupdate=True, antialiased=True):
        self.axes = axes if axes is not None else plt.gca()
        self.geom = geometry
        self.pixels = None
        self.cmap = plt.cm.jet
        self.autoupdate = autoupdate
        self._active_pixel = None
        self._active_pixel_label = None
        
        # initialize the plot and generate the pixels as a
        # RegularPolyCollection

        patches = []

        for xx, yy, aa in zip(u.Quantity(self.geom.pix_x).value,
                              u.Quantity(self.geom.pix_y).value,
                              u.Quantity(np.array(self.geom.pix_area))):
            if self.geom.pix_type.startswith("hex"):
                rr = sqrt(aa * 2 / 3 / sqrt(3))
                poly = RegularPolygon((xx, yy), 6, radius=rr,
                                      orientation=np.radians(0),
                                      fill=True)
            else:
                rr = sqrt(aa) * sqrt(2)
                poly = Rectangle((xx, yy), width=rr, height=rr,
                                 angle=np.radians(0),
                                 fill=True)

            patches.append(poly)

        self.pixels = PatchCollection(patches, cmap=self.cmap, linewidth=0)
        self.axes.add_collection(self.pixels)
        
        # Set up some nice plot defaults
        
        self.axes.set_aspect('equal', 'datalim')
        self.axes.set_title(title)
        self.axes.set_xlabel("X position ({})".format(self.geom.pix_x.unit))
        self.axes.set_ylabel("Y position ({})".format(self.geom.pix_y.unit))
        self.axes.autoscale_view()

        # set up a patch to display when a pixel is clicked (and
        # pixel_picker is enabled):
        
        self._active_pixel = copy.copy(patches[0])
        self._active_pixel.set_facecolor('r')
        self._active_pixel.set_alpha(0.5)
        self._active_pixel.set_linewidth(2.0)
        self._active_pixel.set_visible(False)
        self.axes.add_patch(self._active_pixel)
        
        self._active_pixel_label = plt.text(self._active_pixel.xy[0],
                                            self._active_pixel.xy[1],
                                            "0",
                                            horizontalalignment='center',
                                            verticalalignment='center')
        self._active_pixel_label.set_visible(False)
        
        # enable ability to click on pixel and do something (can be
        # enabled on-the-fly later as well:
        
        if allow_pick:
            self.enable_pixel_picker()

    def enable_pixel_picker(self):
        """ enable ability to click on pixels """
        self.pixels.set_picker(True)  # enable click
        self.pixels.set_pickradius(sqrt(u.Quantity(self.geom.pix_area[0])
                                        .value) / np.pi)
        self.pixels.set_snap(True)  # snap cursor to pixel center
        self.axes.figure.canvas.mpl_connect('pick_event', self._on_pick)

    def set_cmap(self, cmap):
        """ Change the color map 

        Parameters
        ----------
        self: type
            description
        cmap: `matplotlib.colors.ColorMap`
            a color map, e.g. from `matplotlib.pyplot.cm.*`
        """
        self.pixels.set_cmap(cmap)

    def set_image(self, image):
        """
        Change the image displayed on the Camera.

        Parameters
        ----------
        image: array_like
            array of values corresponding to the pixels in the CameraGeometry.
        """
        image = np.asanyarray(image)
        if image.shape != self.geom.pix_x.shape:
            raise ValueError("Image has a different shape {} than the"
                             "given CameraGeometry {}"
                             .format(image.shape, self.geom.pix_x.shape))
        self.pixels.set_array(image)
        self.update()

    def update(self):
        """ signal a redraw if necessary """
        if self.autoupdate:
            plt.draw()

    def add_colorbar(self):
        """ add a colobar to the camera plot """
        self.axes.figure.colorbar(self.pixels)

    def add_ellipse(self, centroid, length, width, angle, asymmetry=0.0,
                    **kwargs):
        """
        plot an ellipse on top of the camera

        Parameters
        ----------
        centroid: (float,float)
            position of centroid
        length: float
            major axis
        width: float
            minor axis
        angle: float
            rotation angle wrt "up" about the centroid, clockwise, in radians
        asymmetry: float
            3rd-order moment for directionality if known
        kwargs:
            any MatPlotLib style arguments to pass to the Ellipse patch

        """
        ellipse = Ellipse(xy=centroid, width=width, height=length,
                          angle=np.degrees(angle), fill=False, **kwargs)
        self.axes.add_patch(ellipse)
        self.update()
        return ellipse

    def overlay_moments(self, momparams, **kwargs):
        """helper to overlay ellipse from a `reco.MomentParameters` structure

        Parameters
        ----------
        momparams: `reco.MomentParameters`
            structuring containing Hillas-style parameterization
        kwargs: key=value
            any style keywords to pass to matplotlib (e.g. color='red'
            or linewidth=6)
        """

        el = self.add_ellipse(centroid=(momparams.cen_x, momparams.cen_y),
                              length=momparams.length,
                              width=momparams.width, angle=momparams.psi,
                              **kwargs)
        self.axes.text(momparams.cen_x, momparams.cen_y,
                       ("({:.02f},{:.02f})\n"
                        "[w={:.02f},l={:.02f}]")
                       .format(momparams.cen_x,
                               momparams.cen_y,
                               momparams.width, momparams.length),
                       color=el.get_edgecolor())

    def _on_pick(self, event):
        """ handler for when a pixel is clicked """
        pix_id = event.ind.pop()
        xx, yy = u.Quantity(self.geom.pix_x[pix_id]).value,\
                 u.Quantity(self.geom.pix_y[pix_id]).value
        self._active_pixel.xy = (xx, yy)
        self._active_pixel.set_visible(True)
        self._active_pixel_label.set_x(xx)
        self._active_pixel_label.set_y(yy)
        self._active_pixel_label.set_text("{:003d}".format(pix_id))
        self._active_pixel_label.set_visible(True)
        self.update()
        self.on_pixel_clicked(pix_id)  # call user-function

    def on_pixel_clicked(self, pix_id):
        """virtual function to overide in sub-classes to do something special
        when a pixel is clicked
        """
        print("Clicked pixel_id {}".format(pix_id))
Пример #28
0
def patchMatrix(mat,
                xmap=None,
                ymap=None,
                ax=None,
                cMin=None,
                cMax=None,
                logScale=None,
                label=None,
                dx=1,
                **kwargs):
    """Plot previously generated (generateVecMatrix) matrix.

    Parameters
    ----------
    mat : numpy.array2d
        matrix to show
    xmap : dict {i:num}
        dict (must match A.shape[0])
    ymap : iterable
        vector for x axis (must match A.shape[0])
    ax : mpl.axis
        axis to plot, if not given a new figure is created
    cMin/cMax : float
        minimum/maximum color values
    logScale : bool
        logarithmic colour scale [min(A)>0]
    label : string
        colorbar label
    dx : float
        width of the matrix elements (by default 1)
    """
    mat = np.ma.masked_where(mat == 0.0, mat, False)
    if cMin is None:
        cMin = np.min(mat)
    if cMax is None:
        cMax = np.max(mat)
    if logScale is None:
        logScale = (cMin > 0.0)
    if logScale:
        norm = LogNorm(vmin=cMin, vmax=cMax)
    else:
        norm = Normalize(vmin=cMin, vmax=cMax)

    if 'ax' is None:
        ax = plt.subplots()[1]

    iy, ix = np.nonzero(mat)  # != 0)
    recs = []
    vals = []
    for i, _ in enumerate(ix):
        recs.append(Rectangle((ix[i] - dx / 2, iy[i] - 0.5), dx, 1))
        vals.append(mat[iy[i], ix[i]])

    pp = PatchCollection(recs)
    col = ax.add_collection(pp)
    pp.set_edgecolor(None)
    pp.set_linewidths(0.0)
    if 'cmap' in kwargs:
        pp.set_cmap(kwargs.pop('cmap'))
    if 'cMap' in kwargs:
        pp.set_cmap(kwargs.pop('cMap'))
    pp.set_norm(norm)
    pp.set_array(np.array(vals))
    pp.set_clim(cMin, cMax)
    xval = [k for k in xmap.keys()]
    ax.set_xlim(min(xval) - dx / 2, max(xval) + dx / 2)
    ax.set_ylim(len(ymap) + 0.5, -0.5)

    updateAxes_(ax)
    cbar = None
    if kwargs.pop('colorBar', True):
        ori = kwargs.pop('orientation', 'horizontal')
        cbar = pg.mplviewer.createColorBar(col,
                                           cMin=cMin,
                                           cMax=cMax,
                                           nLevs=5,
                                           label=label,
                                           orientation=ori)
    return ax, cbar
Пример #29
0
def patchMatrix(A, xmap=None, ymap=None, ax=None, cMin=None, cMax=None,
                logScale=None, label=None, dx=1, **kwargs):
    """ plot previously generated (generateVecMatrix) matrix

    Parameters
    ----------
    A : numpy.array2d
        matrix to show
    xmap : dict {i:num}
        dict (must match A.shape[0])
    ymap : iterable
        vector for x axis (must match A.shape[0])
    ax : mpl.axis
        axis to plot, if not given a new figure is created
    cMin/cMax : float
        minimum/maximum color values
    logScale : bool
        logarithmic colour scale [min(A)>0]
    label : string
        colorbar label
    """
    mat = np.ma.masked_where(A == 0.0, A, False)
    if cMin is None:
        cMin = np.min(mat)
    if cMax is None:
        cMax = np.max(mat)
    if logScale is None:
        logScale = (cMin > 0.0)
    if logScale:
        norm = LogNorm(vmin=cMin, vmax=cMax)
    else:
        norm = Normalize(vmin=cMin, vmax=cMax)
    if 'ax' is None:
        fig, ax = plt.subplots()

    iy, ix = np.nonzero(A)  # != 0)
    recs = []
    vals = []
    for i in range(len(ix)):
        recs.append(Rectangle((ix[i]-dx/2, iy[i]-0.5), dx, 1))
        vals.append(A[iy[i], ix[i]])

    pp = PatchCollection(recs)
    col = ax.add_collection(pp)
    pp.set_edgecolor(None)
    pp.set_linewidths(0.0)
    if 'cmap' in kwargs:
        pp.set_cmap(kwargs.pop('cmap'))
    pp.set_norm(norm)
    pp.set_array(np.array(vals))
    pp.set_clim(cMin, cMax)
    xval = [k for k in xmap.keys()]
    ax.set_xlim(min(xval)-dx/2, max(xval)+dx/2)
    ax.set_ylim(len(ymap)+0.5, -0.5)

    updateAxes_(ax)
    cbar = None
    if kwargs.pop('colorBar', True):
        cbar = pg.mplviewer.createColorbar(col, cMin=cMin, cMax=cMax, nLevs=5,
                                           label=label)
    return ax, cbar
Пример #30
0
def patchValMap(vals, xvec=None, yvec=None, ax=None, cMin=None, cMax=None,
                logScale=None, label=None, dx=1, dy=None, **kwargs):
    """ plot previously generated (generateVecMatrix) y map (category)

    Parameters
    ----------
    A : iterable
        to show
    xvec : dict {i:num}
        dict (must match A.shape[0])
    ymap : iterable
        vector for x axis (must match A.shape[0])
    ax : mpl.axis
        axis to plot, if not given a new figure is created
    cMin/cMax : float
        minimum/maximum color values
    logScale : bool
        logarithmic colour scale [min(A)>0]
    label : string
        colorbar label
    """
    if cMin is None:
        cMin = np.min(vals)
    if cMax is None:
        cMax = np.max(vals)
    if logScale is None:
        logScale = (cMin > 0.0)
    if logScale:
        norm = LogNorm(vmin=cMin, vmax=cMax)
    else:
        norm = Normalize(vmin=cMin, vmax=cMax)
    if 'ax' is None:
        fig, ax = plt.subplots()

    recs = []
    if dy is None:  # map y values to unique
        ymap = {xy: ii for ii, xy in enumerate(np.unique(yvec))}
        for i in range(len(vals)):
            recs.append(Rectangle((xvec[i]-dx/2, ymap[yvec[i]]-0.5), dx, 1))
    else:
        for i in range(len(vals)):
            recs.append(Rectangle((xvec[i]-dx/2, yvec[i]-dy/2), dx, dy))

    pp = PatchCollection(recs)
    col = ax.add_collection(pp)
    pp.set_edgecolor(None)
    pp.set_linewidths(0.0)
    if 'cmap' in kwargs:
        pp.set_cmap(kwargs.pop('cmap'))
    pp.set_norm(norm)
    pp.set_array(np.array(vals))
    pp.set_clim(cMin, cMax)
    ax.set_xlim(min(xvec)-dx/2, max(xvec)+dx/2)
    ax.set_ylim(len(ymap)-0.5, -0.5)

    updateAxes_(ax)
    cbar = None
    if kwargs.pop('colorBar', True):
        cbar = pg.mplviewer.createColorbar(col, cMin=cMin, cMax=cMax, nLevs=5,
                                           label=label)
    return ax, cbar, ymap
Пример #31
0
class CameraPlot(object):
    '''A Class for a camera pixel'''

    def __init__(
        self,
        telescope,
        ax,
        data=None,
        cmap='gray',
        vmin=None,
        vmax=None,
    ):
        '''
        :telescope: the telescope class for the pixel
        :data: array-like with one value for each pixel
        :cmap: a matpixellib colormap string or instance
        :vmin: minimum value of the colormap
        :vmax: maximum value of the colormap

        '''
        self.telescope = telescope
        if data is None:
            data = np.zeros(telescope.n_pixel)

        patches = []
        if telescope.pixel_shape == 'hexagon':
            for xy in zip(telescope.pixel_x, telescope.pixel_y):
                patches.append(
                    RegularPolygon(
                        xy=xy,
                        numVertices=6,
                        radius=telescope.pixel_size,
                        orientation=telescope.pixel_orientation,
                    )
                )
        self.pixel = PatchCollection(patches)
        self.pixel.set_linewidth(0)
        self.pixel.set_cmap(cmap)
        self.pixel.set_array(data)
        self.pixel.set_clim(vmin, vmax)
        self.vmin = vmin
        self.vmax = vmax
        self.ax = ax
        self.ax.add_collection(self.pixel)
        self.ax.set_xlim(
            self.telescope.pixel_x.min() - 2 * self.telescope.pixel_size,
            self.telescope.pixel_x.max() + 2 * self.telescope.pixel_size,
        )
        self.ax.set_ylim(
            self.telescope.pixel_y.min() - 2 * self.telescope.pixel_size,
            self.telescope.pixel_y.max() + 2 * self.telescope.pixel_size,
        )

    @property
    def data(self):
        return self.pixel.get_array()

    @data.setter
    def data(self, data):
        self.pixel.set_array(data)
        if not self.vmin or not self.vmax:
            self.pixel.autoscale()
        self.pixel.changed()
Пример #32
0
def patchValMap(vals, xvec=None, yvec=None, ax=None, cMin=None, cMax=None,
                logScale=None, label=None, dx=1, dy=None, **kwargs):
    """Plot previously generated (generateVecMatrix) y map (category).

    Parameters
    ----------
    vals : iterable
        Data values to show.
    xvec : dict {i:num}
        dict (must match vals.shape[0])
    ymap : iterable
        vector for x axis (must match vals.shape[0])
    ax : mpl.axis
        axis to plot, if not given a new figure is created
    cMin/cMax : float
        minimum/maximum color values
    logScale : bool
        logarithmic colour scale [min(vals)>0]
    label : string
        colorbar label
    ** kwargs:
        * circular : bool
            Plot in polar coordinates.
    """
    if cMin is None:
        cMin = np.min(vals)
    if cMax is None:
        cMax = np.max(vals)

    if logScale is None:
        logScale = (cMin > 0.0)

    norm = None
    if logScale and cMin > 0:
        norm = LogNorm(vmin=cMin, vmax=cMax)
    else:
        norm = Normalize(vmin=cMin, vmax=cMax)

    if ax is None:
        ax = plt.subplots()[1]

    recs = []

    circular = kwargs.pop('circular', False)
    if circular:
        recs = [None] * len(xvec)
        if dy is None:  # map y values to unique
            ymap = {xy: ii for ii, xy in enumerate(np.unique(yvec))}

            xyMap = {}
            for i, y in enumerate(yvec):
                if y not in xyMap:
                    xyMap[y] = []
                xyMap[y].append(i)

            # maxR = max(ymap.values())  # what's that for? not used
            dR = 1 / (len(ymap.values())+1)
            # dOff = np.pi / 2  # what's that for? not used

            for y, xIds in xyMap.items():
                r = 1. - dR*(ymap[y]+1)
                # ax.plot(r * np.cos(xvec[xIds]),
                #         r * np.sin(xvec[xIds]), 'o')

                # print(y, ymap[y])
                for i in xIds:
                    phi = xvec[i]
                    # x = r * np.cos(phi)  # what's that for? not used
                    y = r * np.sin(phi)

                    dPhi = (xvec[1] - xvec[0])

                    recs[i] = Wedge((0., 0.), r + dR/1.5,
                                    (phi - dPhi)*360/(2*np.pi),
                                    (phi + dPhi)*360/(2*np.pi),
                                    width=dR,
                                    zorder=1+r)
                    # if i < 5:
                    #     ax.text(x, y, str(i))
                    # pg.wait()
        else:
            raise("Implementme")
    else:
        if dy is None:  # map y values to unique
            ymap = {xy: ii for ii, xy in enumerate(np.unique(yvec))}
            for i in range(len(vals)):
                recs.append(Rectangle((xvec[i] - dx / 2, ymap[yvec[i]] - 0.5),
                                      dx, 1))
        else:
            for i in range(len(vals)):
                recs.append(Rectangle((xvec[i] - dx / 2, yvec[i] - dy / 2),
                                      dx, dy))
        ax.set_xlim(min(xvec) - dx / 2, max(xvec) + dx / 2)
        ax.set_ylim(len(ymap) - 0.5, -0.5)

    pp = PatchCollection(recs)
    # ax.clear()
    col = ax.add_collection(pp)
    pp.set_edgecolor(None)
    pp.set_linewidths(0.0)

    if circular:
        pp.set_edgecolor('black')
        pp.set_linewidths(0.1)

    cmap = pg.mplviewer.cmapFromName(**kwargs)
    if kwargs.pop('markOutside', False):
        cmap.set_bad('grey')
        cmap.set_under('darkgrey')
        cmap.set_over('lightgrey')
        cmap.set_bad('black')
    pp.set_cmap(cmap)

    pp.set_norm(norm)
    pp.set_array(vals)
    pp.set_clim(cMin, cMax)

    updateAxes_(ax)
    cbar = kwargs.pop('colorBar', True)
    ori = kwargs.pop('orientation', 'horizontal')
    if cbar in ['horizontal', 'vertical']:
        ori = cbar
        cbar = True

    if cbar is True:  # not for cbar=1, which is really confusing!
        cbar = pg.mplviewer.createColorBar(col, cMin=cMin, cMax=cMax,
                                           nLevs=5, label=label,
                                           orientation=ori)
    elif cbar is not False:
        # .. cbar is an already existing cbar .. so we update its values
        pg.mplviewer.updateColorBar(cbar, cMin=cMin, cMax=cMax,
                                    nLevs=5, label=label)

    updateAxes_(ax)
    return ax, cbar, ymap
Пример #33
0
class CameraDisplay:
    """
    Camera Display using matplotlib.

    Parameters
    ----------
    geometry : `~ctapipe.io.CameraGeometry`
        Definition of the Camera/Image
    image: array_like
        array of values corresponding to the pixels in the CameraGeometry.
    ax : `matplotlib.axes.Axes`
        A matplotlib axes object to plot on, or None to create a new one
    title : str (default "Camera")
        Title to put on camera plot
    norm : str or `matplotlib.color.Normalize` instance (default 'lin')
        Normalization for the color scale.
        Supported str arguments are
        - 'lin': linear scale
        - 'log': logarithmic scale (base 10)
    cmap : str or `matplotlib.colors.Colormap` (default 'hot')
        Color map to use (see `matplotlib.cm`)
    allow_pick : bool (default False)
        if True, allow user to click and select a pixel
    autoupdate : bool (default True)
        redraw automatically (otherwise need to call plt.draw())
    autoscale : bool (default True)
        rescale the vmin/vmax values when the image changes.
        This is set to False if `set_limits_*` is called to explicity
        set data limits.
    antialiased : bool  (default True)
        whether to draw in antialiased mode or not.

    Notes
    -----

    Speed:
        CameraDisplay is not intended to be very fast (matplotlib
        is not a very speed performant graphics library, it is
        intended for nice output plots). However, most of the
        slowness of CameraDisplay is in the constructor.  Once one is
        displayed, changing the image that is displayed is relatively
        fast and efficient. Therefore it is best to initialize an
        instance, and change the data, rather than generating new
        CameraDisplays.

    Pixel Implementation:
        Pixels are rendered as a
        `matplotlib.collections.PatchCollection` of Polygons (either 6
        or 4 sided).  You can access the PatchCollection directly (to
        e.g. change low-level style parameters) via
        `CameraDisplay.pixels`

    Output:
        Since CameraDisplay uses matplotlib, any display can be
        saved to any output file supported via
        plt.savefig(filename). This includes `.pdf` and `.png`.

    """
    def __init__(
        self,
        geometry,
        image=None,
        ax=None,
        title="Camera",
        norm="lin",
        cmap="hot",
        allow_pick=False,
        autoupdate=True,
        autoscale=True,
        antialiased=True,
    ):
        self.axes = ax if ax is not None else plt.gca()
        self.geom = geometry
        self.pixels = None
        self.colorbar = None
        self.autoupdate = autoupdate
        self.autoscale = autoscale
        self._active_pixel = None
        self._active_pixel_label = None

        # initialize the plot and generate the pixels as a
        # RegularPolyCollection

        patches = []

        for xx, yy, aa in zip(
                u.Quantity(self.geom.pix_x).value,
                u.Quantity(self.geom.pix_y).value,
                u.Quantity(np.array(self.geom.pix_area))):
            if self.geom.pix_type.startswith("hex"):
                rr = sqrt(aa * 2 / 3 / sqrt(3))
                poly = RegularPolygon(
                    (xx, yy),
                    6,
                    radius=rr,
                    orientation=self.geom.pix_rotation.rad,
                    fill=True,
                )
            else:
                rr = sqrt(aa)
                poly = Rectangle(
                    (xx - rr / 2., yy - rr / 2.),
                    width=rr,
                    height=rr,
                    angle=self.geom.pix_rotation.deg,
                    fill=True,
                )

            patches.append(poly)

        self.pixels = PatchCollection(patches, cmap=cmap, linewidth=0)
        self.axes.add_collection(self.pixels)

        self.pixel_highlighting = copy.copy(self.pixels)
        self.pixel_highlighting.set_facecolor('none')
        self.pixel_highlighting.set_linewidth(0)
        self.axes.add_collection(self.pixel_highlighting)

        # Set up some nice plot defaults

        self.axes.set_aspect('equal', 'datalim')
        self.axes.set_title(title)
        self.axes.set_xlabel("X position ({})".format(self.geom.pix_x.unit))
        self.axes.set_ylabel("Y position ({})".format(self.geom.pix_y.unit))
        self.axes.autoscale_view()

        # set up a patch to display when a pixel is clicked (and
        # pixel_picker is enabled):

        self._active_pixel = copy.copy(patches[0])
        self._active_pixel.set_facecolor('r')
        self._active_pixel.set_alpha(0.5)
        self._active_pixel.set_linewidth(2.0)
        self._active_pixel.set_visible(False)
        self.axes.add_patch(self._active_pixel)

        self._active_pixel_label = self.axes.text(self._active_pixel.xy[0],
                                                  self._active_pixel.xy[1],
                                                  "0",
                                                  horizontalalignment='center',
                                                  verticalalignment='center')
        self._active_pixel_label.set_visible(False)

        # enable ability to click on pixel and do something (can be
        # enabled on-the-fly later as well:

        if allow_pick:
            self.enable_pixel_picker()

        if image is not None:
            self.image = image
        else:
            self.image = np.zeros_like(self.geom.pix_id, dtype=np.float)

        self.norm = norm

    def highlight_pixels(self, pixels, color='g', linewidth=1, alpha=0.75):
        '''
        Highlight the given pixels with a colored line around them

        Parameters
        ----------
        pixels : index-like
            The pixels to highlight.
            Can either be a list or array of integers or a
            boolean mask of length number of pixels
        color: a matplotlib conform color
            the color for the pixel highlighting
        linewidth: float
            linewidth of the highlighting in points
        alpha: 0 <= alpha <= 1
            The transparency
        '''

        l = np.zeros_like(self.image)
        l[pixels] = linewidth
        self.pixel_highlighting.set_linewidth(l)
        self.pixel_highlighting.set_alpha(alpha)
        self.pixel_highlighting.set_edgecolor(color)
        self.update()

    def enable_pixel_picker(self):
        """ enable ability to click on pixels """
        self.pixels.set_picker(True)  # enable click
        self.pixels.set_pickradius(
            sqrt(u.Quantity(self.geom.pix_area[0]).value) / np.pi)
        self.pixels.set_snap(True)  # snap cursor to pixel center
        self.axes.figure.canvas.mpl_connect('pick_event', self._on_pick)

    def set_limits_minmax(self, zmin, zmax):
        """ set the color scale limits from min to max """
        self.pixels.set_clim(zmin, zmax)
        self.autoscale = False
        self.update()

    def set_limits_percent(self, percent=95):
        """ auto-scale the color range to percent of maximum """
        zmin = self.pixels.get_array().min()
        zmax = self.pixels.get_array().max()
        dz = zmax - zmin
        frac = percent / 100.0
        self.autoscale = False
        self.set_limits_minmax(zmin, zmax - (1.0 - frac) * dz)

    @property
    def norm(self):
        '''
        The norm instance of the Display

        Possible values:

        - "lin": linear scale
        - "log": log scale
        -  any matplotlib.colors.Normalize instance, e. g. PowerNorm(gamma=-2)
        '''
        return self.pixels.norm

    @norm.setter
    def norm(self, norm):

        if norm == 'lin':
            self.pixels.norm = Normalize()
        elif norm == 'log':
            self.pixels.norm = LogNorm()
            self.pixels.autoscale()  # this is to handle matplotlib bug #5424
        elif isinstance(norm, Normalize):
            self.pixels.norm = norm
        else:
            raise ValueError('Unsupported norm: {}'.format(norm))

        self.update(force=True)
        self.pixels.autoscale()

    @property
    def cmap(self):
        """
        Color map to use. Either a name or  `matplotlib.colors.ColorMap`
        instance, e.g. from `matplotlib.pyplot.cm`
        """
        return self.pixels.get_cmap()

    @cmap.setter
    def cmap(self, cmap):
        self.pixels.set_cmap(cmap)
        self.update()

    @property
    def image(self):
        """The image displayed on the camera (1D array of pixel values)"""
        return self.pixels.get_array()

    @image.setter
    def image(self, image):
        """
        Change the image displayed on the Camera.

        Parameters
        ----------
        image: array_like
            array of values corresponding to the pixels in the CameraGeometry.
        """
        image = np.asanyarray(image)
        if image.shape != self.geom.pix_x.shape:
            raise ValueError("Image has a different shape {} than the"
                             "given CameraGeometry {}".format(
                                 image.shape, self.geom.pix_x.shape))

        self.pixels.set_array(image)
        self.pixels.changed()
        if self.autoscale:
            self.pixels.autoscale()
        self.update()

    def update(self, force=False):
        """ signal a redraw if necessary """
        if self.autoupdate:
            if self.colorbar is not None:
                if force is True:
                    self.colorbar.update_bruteforce(self.pixels)
                else:
                    self.colorbar.update_normal(self.pixels)
                self.colorbar.draw_all()
            self.axes.figure.canvas.draw()

    def add_colorbar(self, **kwargs):
        """
        add a colobar to the camera plot
        kwargs are passed to `figure.colorbar(self.pixels, **kwargs)`
        See matplotlib documentation for the supported kwargs:
        http://matplotlib.org/api/figure_api.html#matplotlib.figure.Figure.colorbar
        """
        if self.colorbar is not None:
            raise ValueError(
                'There is already a colorbar attached to this CameraDisplay')
        else:
            self.colorbar = self.axes.figure.colorbar(self.pixels, **kwargs)
        self.update()

    def add_ellipse(self,
                    centroid,
                    length,
                    width,
                    angle,
                    asymmetry=0.0,
                    **kwargs):
        """
        plot an ellipse on top of the camera

        Parameters
        ----------
        centroid: (float, float)
            position of centroid
        length: float
            major axis
        width: float
            minor axis
        angle: float
            rotation angle wrt "up" about the centroid, clockwise, in radians
        asymmetry: float
            3rd-order moment for directionality if known
        kwargs:
            any MatPlotLib style arguments to pass to the Ellipse patch

        """
        ellipse = Ellipse(xy=centroid,
                          width=width,
                          height=length,
                          angle=np.degrees(angle),
                          fill=False,
                          **kwargs)
        self.axes.add_patch(ellipse)
        self.update()
        return ellipse

    def overlay_moments(self, momparams, **kwargs):
        """helper to overlay ellipse from a `reco.MomentParameters` structure

        Parameters
        ----------
        momparams: `reco.MomentParameters`
            structuring containing Hillas-style parameterization
        kwargs: key=value
            any style keywords to pass to matplotlib (e.g. color='red'
            or linewidth=6)
        """
        el = self.add_ellipse(centroid=(momparams.cen_x.value,
                                        momparams.cen_y.value),
                              length=momparams.length.value,
                              width=momparams.width.value,
                              angle=momparams.psi.to(u.rad).value,
                              **kwargs)
        self.axes.text(momparams.cen_x.value,
                       momparams.cen_y.value,
                       ("({:.02f},{:.02f})\n"
                        "[w={:.02f},l={:.02f}]").format(
                            momparams.cen_x, momparams.cen_y, momparams.width,
                            momparams.length),
                       color=el.get_edgecolor())

    def _on_pick(self, event):
        """ handler for when a pixel is clicked """
        pix_id = event.ind[-1]
        xx, yy, aa = u.Quantity(self.geom.pix_x[pix_id]).value, \
                     u.Quantity(self.geom.pix_y[pix_id]).value, \
                     u.Quantity(np.array(self.geom.pix_area)[pix_id])
        if self.geom.pix_type.startswith("hex"):
            self._active_pixel.xy = (xx, yy)
        else:
            rr = sqrt(aa)
            self._active_pixel.xy = (xx - rr / 2., yy - rr / 2.)
        self._active_pixel.set_visible(True)
        self._active_pixel_label.set_x(xx)
        self._active_pixel_label.set_y(yy)
        self._active_pixel_label.set_text("{:003d}".format(pix_id))
        self._active_pixel_label.set_visible(True)
        self.update()
        self.on_pixel_clicked(pix_id)  # call user-function

    def on_pixel_clicked(self, pix_id):
        """virtual function to overide in sub-classes to do something special
        when a pixel is clicked
        """
        print("Clicked pixel_id {}".format(pix_id))

    def show(self):
        self.axes.figure.show()
Пример #34
0
def showStitchedModels_Redundant(mods,
                                 ax=None,
                                 cmin=None,
                                 cmax=None,
                                 **kwargs):
    """Show several 1d block models as (stitched) section."""
    x = kwargs.pop('x', np.arange(len(mods)))
    topo = kwargs.pop('topo', x * 0)

    nlay = int(np.floor((len(mods[0]) - 1) / 2.)) + 1
    if cmin is None or cmax is None:
        cmin = 1e9
        cmax = 1e-9
        for model in mods:
            res = np.asarray(model)[nlay - 1:nlay * 2 - 1]
            cmin = min(cmin, min(res))
            cmax = max(cmax, max(res))

    if kwargs.pop('sameSize', True):  # all having the same width
        dx = np.ones_like(x) * np.median(np.diff(x))
    else:
        dx = np.diff(x) * 1.05
        dx = np.hstack((dx, dx[-1]))

    x1 = x - dx / 2
    if ax is None:
        fig, ax = plt.subplots()
    else:
        ax = ax
        fig = ax.figure

#    ax.plot(x, x * 0., 'k.')
    zm = kwargs.pop('zm', None)
    maxz = 0.
    if zm is not None:
        maxz = zm
    recs = []
    RES = []
    for i, mod in enumerate(mods):
        mod1 = np.asarray(mod)
        res = mod1[nlay - 1:]
        RES.extend(res)

        thk = mod1[:nlay - 1]
        thk = np.hstack((thk, thk[-1]))
        z = np.hstack((0., np.cumsum(thk)))
        if zm is not None:
            thk[-1] = zm - z[-2]
            z[-1] = zm
        else:
            maxz = max(maxz, z[-1])

        for j, _ in enumerate(thk):
            recs.append(Rectangle((x1[i], topo[i] - z[j]), dx[i], -thk[j]))

    pp = PatchCollection(recs, edgecolors=kwargs.pop('edgecolors', 'none'))
    pp.set_edgecolor(kwargs.pop('edgecolors', 'none'))
    pp.set_linewidths(0.0)
    ax.add_collection(pp)
    if 'cmap' in kwargs:
        pp.set_cmap(kwargs['cmap'])

    print(cmin, cmax)
    norm = colors.LogNorm(cmin, cmax)
    pp.set_norm(norm)
    pp.set_array(np.array(RES))
    #    pp.set_clim(cmin, cmax)
    ax.set_ylim((-maxz, max(topo)))
    ax.set_xlim((x1[0], x1[-1] + dx[-1]))

    cbar = None
    if kwargs.pop('colorBar', True):
        cbar = plt.colorbar(pp,
                            ax=ax,
                            norm=norm,
                            orientation='horizontal',
                            aspect=60)  # , ticks=[1, 3, 10, 30, 100, 300])
        if 'ticks' in kwargs:
            cbar.set_ticks(kwargs['ticks'])


#        cbar.autoscale_None()
    if ax is None:  # newly created fig+ax
        return fig, ax
    else:  # already given, better give back color bar
        return cbar
Пример #35
0
def showStitchedModels(mods, axes=None, cmin=None, cmax=None, **kwargs):
    """
        Show several 1d block models as (stitched) section.
    """
    x = kwargs.pop('x', np.arange(len(mods)))
    topo = kwargs.pop('topo', x*0)

    nlay = int(np.floor((len(mods[0]) - 1) / 2.)) + 1
    if cmin is None or cmax is None:
        cmin = 1e9
        cmax = 1e-9
        for model in mods:
            res = np.asarray(model)[nlay - 1:nlay * 2 - 1]
            cmin = min(cmin, min(res))
            cmax = max(cmax, max(res))

    if kwargs.pop('sameSize', True):  # all having the same width
        dx = np.ones_like(x)*np.median(np.diff(x))
    else:
        dx = np.diff(x) * 1.05
        dx = np.hstack((dx, dx[-1]))

    x1 = x - dx / 2
    if axes is None:
        fig, ax = plt.subplots()
    else:
        ax = axes
        fig = ax.figure

#    ax.plot(x, x * 0., 'k.')
    zm = kwargs.pop('zm', None)
    maxz = 0.
    if zm is not None:
        maxz = zm
    recs = []
    RES = []
    for i, mod in enumerate(mods):
        mod1 = np.asarray(mod)
        res = mod1[nlay - 1:]
        RES.extend(res)

        thk = mod1[:nlay - 1]
        thk = np.hstack((thk, thk[-1]))
        z = np.hstack((0., np.cumsum(thk)))
        if zm is not None:
            thk[-1] = zm - z[-2]
            z[-1] = zm
        else:
            maxz = max(maxz, z[-1])

        for j in range(len(thk)):
            recs.append(Rectangle((x1[i], topo[i]-z[j]), dx[i], -thk[j]))

    pp = PatchCollection(recs, edgecolors=kwargs.pop('edgecolors', 'none'))
    pp.set_edgecolor(kwargs.pop('edgecolors', 'none'))
    pp.set_linewidths(0.0)
    ax.add_collection(pp)
    if 'cmap' in kwargs:
        pp.set_cmap(kwargs['cmap'])

    print(cmin, cmax)
    norm = LogNorm(cmin, cmax)
    pp.set_norm(norm)
    pp.set_array(np.array(RES))
#    pp.set_clim(cmin, cmax)
    ax.set_ylim((-maxz, max(topo)))
    ax.set_xlim((x1[0], x1[-1] + dx[-1]))

    cbar = None
    if kwargs.pop('colorBar', True):
        cbar = plt.colorbar(pp, ax=ax, norm=norm, orientation='horizontal',
                            aspect=60)  # , ticks=[1, 3, 10, 30, 100, 300])
        if 'ticks' in kwargs:
            cbar.set_ticks(kwargs['ticks'])
#        cbar.autoscale_None()
    if axes is None:  # newly created fig+ax
        return fig, ax
    else:  # already given, better give back color bar
        return cbar
Пример #36
0
class CameraDisplay:

    """
    Camera Display using matplotlib.

    Parameters
    ----------
    geometry : `~ctapipe.instrument.CameraGeometry`
        Definition of the Camera/Image
    image: array_like
        array of values corresponding to the pixels in the CameraGeometry.
    ax : `matplotlib.axes.Axes`
        A matplotlib axes object to plot on, or None to create a new one
    title : str (default "Camera")
        Title to put on camera plot
    norm : str or `matplotlib.color.Normalize` instance (default 'lin')
        Normalization for the color scale.
        Supported str arguments are
        - 'lin': linear scale
        - 'log': logarithmic scale (base 10)
    cmap : str or `matplotlib.colors.Colormap` (default 'hot')
        Color map to use (see `matplotlib.cm`)
    allow_pick : bool (default False)
        if True, allow user to click and select a pixel
    autoupdate : bool (default True)
        redraw automatically (otherwise need to call plt.draw())
    autoscale : bool (default True)
        rescale the vmin/vmax values when the image changes.
        This is set to False if `set_limits_*` is called to explicity
        set data limits.
    antialiased : bool  (default True)
        whether to draw in antialiased mode or not.

    Notes
    -----

    Speed:
        CameraDisplay is not intended to be very fast (matplotlib
        is not a very speed performant graphics library, it is
        intended for nice output plots). However, most of the
        slowness of CameraDisplay is in the constructor.  Once one is
        displayed, changing the image that is displayed is relatively
        fast and efficient. Therefore it is best to initialize an
        instance, and change the data, rather than generating new
        CameraDisplays.

    Pixel Implementation:
        Pixels are rendered as a
        `matplotlib.collections.PatchCollection` of Polygons (either 6
        or 4 sided).  You can access the PatchCollection directly (to
        e.g. change low-level style parameters) via
        `CameraDisplay.pixels`

    Output:
        Since CameraDisplay uses matplotlib, any display can be
        saved to any output file supported via
        plt.savefig(filename). This includes `.pdf` and `.png`.

    """

    def __init__(
            self,
            geometry,
            image=None,
            ax=None,
            title=None,
            norm="lin",
            cmap=None,
            allow_pick=False,
            autoupdate=True,
            autoscale=True,
            antialiased=True,
            ):
        self.axes = ax if ax is not None else plt.gca()
        self.geom = geometry
        self.pixels = None
        self.colorbar = None
        self.autoupdate = autoupdate
        self.autoscale = autoscale
        self._active_pixel = None
        self._active_pixel_label = None

        if title is None:
            title = geometry.cam_id

        # initialize the plot and generate the pixels as a
        # RegularPolyCollection

        patches = []

        if not hasattr(self.geom, "mask"):
            self.geom.mask = np.ones_like(self.geom.pix_x.value, dtype=bool)

        for xx, yy, aa in zip(
            u.Quantity(self.geom.pix_x[self.geom.mask]).value,
            u.Quantity(self.geom.pix_y[self.geom.mask]).value,
            u.Quantity(np.array(self.geom.pix_area)[self.geom.mask]).value):

            if self.geom.pix_type.startswith("hex"):
                rr = sqrt(aa * 2 / 3 / sqrt(3)) + 2*PIXEL_EPSILON
                poly = RegularPolygon(
                    (xx, yy), 6, radius=rr,
                    orientation=self.geom.pix_rotation.rad,
                    fill=True,
                )
            else:
                rr = sqrt(aa) + PIXEL_EPSILON
                poly = Rectangle(
                    (xx-rr/2., yy-rr/2.),
                    width=rr,
                    height=rr,
                    angle=self.geom.pix_rotation.deg,
                    fill=True,
                )

            patches.append(poly)

        self.pixels = PatchCollection(patches, cmap=cmap, linewidth=0)
        self.axes.add_collection(self.pixels)

        self.pixel_highlighting = copy.copy(self.pixels)
        self.pixel_highlighting.set_facecolor('none')
        self.pixel_highlighting.set_linewidth(0)
        self.axes.add_collection(self.pixel_highlighting)

        # Set up some nice plot defaults

        self.axes.set_aspect('equal', 'datalim')
        self.axes.set_title(title)
        self.axes.set_xlabel("X position ({})".format(self.geom.pix_x.unit))
        self.axes.set_ylabel("Y position ({})".format(self.geom.pix_y.unit))
        self.axes.autoscale_view()

        # set up a patch to display when a pixel is clicked (and
        # pixel_picker is enabled):

        self._active_pixel = copy.copy(patches[0])
        self._active_pixel.set_facecolor('r')
        self._active_pixel.set_alpha(0.5)
        self._active_pixel.set_linewidth(2.0)
        self._active_pixel.set_visible(False)
        self.axes.add_patch(self._active_pixel)

        self._active_pixel_label = self.axes.text(self._active_pixel.xy[0],
                                                  self._active_pixel.xy[1],
                                                  "0",
                                                  horizontalalignment='center',
                                                  verticalalignment='center')
        self._active_pixel_label.set_visible(False)

        # enable ability to click on pixel and do something (can be
        # enabled on-the-fly later as well:

        if allow_pick:
            self.enable_pixel_picker()

        if image is not None:
            self.image = image
        else:
            self.image = np.zeros_like(self.geom.pix_id, dtype=np.float)

        self.norm = norm

    def highlight_pixels(self, pixels, color='g', linewidth=1, alpha=0.75):
        '''
        Highlight the given pixels with a colored line around them

        Parameters
        ----------
        pixels : index-like
            The pixels to highlight.
            Can either be a list or array of integers or a
            boolean mask of length number of pixels
        color: a matplotlib conform color
            the color for the pixel highlighting
        linewidth: float
            linewidth of the highlighting in points
        alpha: 0 <= alpha <= 1
            The transparency
        '''

        l = np.zeros_like(self.image)
        l[pixels] = linewidth
        self.pixel_highlighting.set_linewidth(l)
        self.pixel_highlighting.set_alpha(alpha)
        self.pixel_highlighting.set_edgecolor(color)
        self._update()

    def enable_pixel_picker(self):
        """ enable ability to click on pixels """
        self.pixels.set_picker(True)  # enable click
        self.pixels.set_pickradius(sqrt(u.Quantity(self.geom.pix_area[0])
                                        .value) / np.pi)
        self.pixels.set_snap(True)  # snap cursor to pixel center
        self.axes.figure.canvas.mpl_connect('pick_event', self._on_pick)

    def set_limits_minmax(self, zmin, zmax):
        """ set the color scale limits from min to max """
        self.pixels.set_clim(zmin, zmax)
        self.autoscale = False
        self._update()

    def set_limits_percent(self, percent=95):
        """ auto-scale the color range to percent of maximum """
        zmin = self.pixels.get_array().min()
        zmax = self.pixels.get_array().max()
        dz = zmax - zmin
        frac = percent / 100.0
        self.autoscale = False
        self.set_limits_minmax(zmin, zmax - (1.0 - frac) * dz)

    @property
    def norm(self):
        '''
        The norm instance of the Display

        Possible values:

        - "lin": linear scale
        - "log": log scale (cannot have negative values)
        - "symlog": symmetric log scale (negative values are ok)
        -  any matplotlib.colors.Normalize instance, e. g. PowerNorm(gamma=-2)
        '''
        return self.pixels.norm

    @norm.setter
    def norm(self, norm):

        if norm == 'lin':
            self.pixels.norm = Normalize()
        elif norm == 'log':
            self.pixels.norm = LogNorm()
            self.pixels.autoscale()  # this is to handle matplotlib bug #5424
        elif norm == 'symlog':
            self.pixels.norm = SymLogNorm(linthresh=1.0)
            self.pixels.autoscale()
        elif isinstance(norm, Normalize):
            self.pixels.norm = norm
        else:
            raise ValueError("Unsupported norm: '{}', options are 'lin',"
                             "'log','symlog', or a matplotlib Normalize object"
                             .format(norm))

        self.update(force=True)
        self.pixels.autoscale()

    @property
    def cmap(self):
        """
        Color map to use. Either a name or  `matplotlib.colors.ColorMap`
        instance, e.g. from `matplotlib.pyplot.cm`
        """
        return self.pixels.get_cmap()

    @cmap.setter
    def cmap(self, cmap):
        self.pixels.set_cmap(cmap)
        self._update()

    @property
    def image(self):
        """The image displayed on the camera (1D array of pixel values)"""
        return self.pixels.get_array()

    @image.setter
    def image(self, image):
        """
        Change the image displayed on the Camera.

        Parameters
        ----------
        image: array_like
            array of values corresponding to the pixels in the CameraGeometry.
        """
        image = np.asanyarray(image)
        if image.shape != self.geom.pix_x.shape:
            raise ValueError(
                "Image has a different shape {} than the "
                "given CameraGeometry {}"
                .format(image.shape, self.geom.pix_x.shape)
            )

        self.pixels.set_array(image[self.geom.mask])
        self.pixels.changed()
        if self.autoscale:
            self.pixels.autoscale()
        self._update()

    def _update(self, force=False):
        """ signal a redraw if autoupdate is turned on """
        if self.autoupdate:
            self.update(force)

    def update(self, force=False):
        """ redraw the display now """
        self.axes.figure.canvas.draw()
        if self.colorbar is not None:
            if force is True:
                self.colorbar.update_bruteforce(self.pixels)
            else:
                self.colorbar.update_normal(self.pixels)
            self.colorbar.draw_all()

    def add_colorbar(self, **kwargs):
        """
        add a colobar to the camera plot
        kwargs are passed to `figure.colorbar(self.pixels, **kwargs)`
        See matplotlib documentation for the supported kwargs:
        http://matplotlib.org/api/figure_api.html#matplotlib.figure.Figure.colorbar
        """
        if self.colorbar is not None:
            raise ValueError(
                'There is already a colorbar attached to this CameraDisplay'
            )
        else:
            self.colorbar = self.axes.figure.colorbar(self.pixels, **kwargs)
        self.update()

    def add_ellipse(self, centroid, length, width, angle, asymmetry=0.0,
                    **kwargs):
        """
        plot an ellipse on top of the camera

        Parameters
        ----------
        centroid: (float, float)
            position of centroid
        length: float
            major axis
        width: float
            minor axis
        angle: float
            rotation angle wrt x-axis about the centroid, anticlockwise, in radians
        asymmetry: float
            3rd-order moment for directionality if known
        kwargs:
            any MatPlotLib style arguments to pass to the Ellipse patch

        """
        ellipse = Ellipse(xy=centroid, width=length, height=width,
                          angle=np.degrees(angle), fill=False, **kwargs)
        self.axes.add_patch(ellipse)
        self.update()
        return ellipse

    def overlay_moments(self, momparams, with_label=True, **kwargs):
        """helper to overlay ellipse from a `reco.MomentParameters` structure

        Parameters
        ----------
        momparams: `reco.MomentParameters`
            structuring containing Hillas-style parameterization
        kwargs: key=value
            any style keywords to pass to matplotlib (e.g. color='red'
            or linewidth=6)
        """

        # strip off any units
        cen_x = u.Quantity(momparams.cen_x).value
        cen_y = u.Quantity(momparams.cen_y).value
        length = u.Quantity(momparams.length).value
        width = u.Quantity(momparams.width).value


        el = self.add_ellipse(centroid=(cen_x, cen_y),
                              length=length*2,
                              width=width*2, angle=momparams.psi.rad,
                              **kwargs)
        if with_label:
            self.axes.text(cen_x, cen_y,
                           ("({:.02f},{:.02f})\n"
                            "[w={:.02f},l={:.02f}]")
                           .format(momparams.cen_x,
                                   momparams.cen_y,
                                   momparams.width, momparams.length),
                           color=el.get_edgecolor())

    def _on_pick(self, event):
        """ handler for when a pixel is clicked """
        pix_id = event.ind[-1]
        xx, yy, aa = u.Quantity(self.geom.pix_x[pix_id]).value, \
                     u.Quantity(self.geom.pix_y[pix_id]).value, \
                     u.Quantity(np.array(self.geom.pix_area)[pix_id])
        if self.geom.pix_type.startswith("hex"):
            self._active_pixel.xy = (xx, yy)
        else:
            rr = sqrt(aa)
            self._active_pixel.xy = (xx - rr / 2., yy - rr / 2.)
        self._active_pixel.set_visible(True)
        self._active_pixel_label.set_x(xx)
        self._active_pixel_label.set_y(yy)
        self._active_pixel_label.set_text("{:003d}".format(pix_id))
        self._active_pixel_label.set_visible(True)
        self._update()
        self.on_pixel_clicked(pix_id)  # call user-function

    def on_pixel_clicked(self, pix_id):
        """virtual function to overide in sub-classes to do something special
        when a pixel is clicked
        """
        print("Clicked pixel_id {}".format(pix_id))

    def show(self):
        self.axes.figure.show()
Пример #37
0
def GridStrain(pos, disp, k, par, plotpar, plotst):
    '''
	GridStrain computes the infinitesimal strain of a network
	of stations with displacements in x (east) and y (north).
	Strain in z is assumed to be zero (plane strain)

	USE: cent,eps,ome,pstrain,rotc = GridStrain(pos,disp,k,par,plotpar,plotst)

	pos = nstations x 2 matrix with x (east) and y (north)
		positions of stations in meters
	disp = nstations x 2 matrix with x (east) and y (north)
		displacements of stations in meters
	k = Type of computation: Delaunay (k = 0), nearest
		neighbor (k = 1), or distance weighted (k = 2)
	par = Parameters for nearest neighbor or distance
		weighted computation. If Delaunay (k = 0), enter
		a scalar corresponding to the minimum internal
		angle of a triangle valid for computation.
		If nearest neighbor (k = 1), input a 1 x 3 vector
		with grid spacing, number of nearest neighbors,
		and maximum distance to neighbors. If distance
		weighted (k = 2), input a 1 x 2 vector with grid
		spacing and distance weighting factor alpha
	plotpar = Parameter to color the cells: Max elongation
		(plotpar = 0), minimum elongation
		(plotpar = 1), rotation (plotpar = 2),
		or dilatation (plotpar = 3)
	plotst = A flag to plot the stations (1) or not (0)
	cent = ncells x 2 matrix with x and y positions of cells
		centroids
	eps = 3 x 3 x ncells array	with strain tensors of
		the cells
	ome = 3 x 3 x ncells array with rotation tensors of
		the cells
	pstrain = 3 x 3 x ncells array with magnitude and
		orientation of principal strains of
		the cells
	rotc = ncells x 3 matrix with rotation components
		of cells

	NOTE: Input/Output angles are in radians. Output
		azimuths are given with respect to North
		pos, disp, grid spacing, max. distance to
		neighbors, and alpha should be in meters
	
	GridStrain uses functions lscov and InfStrain

	Python function translated from the Matlab function
	GridStrain in Allmendinger et al. (2012)
	'''
    pi = np.pi
    # If Delaunay
    if k == 0:
        # Indexes of triangles vertices
        # Use function Delaunay
        tri = Delaunay(pos)
        inds = tri.simplices
        # Number of cells
        ncells = np.size(inds, 0)
        # Number of stations per cell = 3
        nstat = 3
        # Centers of cells
        cent = np.zeros((ncells, 2))
        for i in range(0, ncells):
            # Triangle vertices
            v1x = pos[inds[i, 0], 0]
            v2x = pos[inds[i, 1], 0]
            v3x = pos[inds[i, 2], 0]
            v1y = pos[inds[i, 0], 1]
            v2y = pos[inds[i, 1], 1]
            v3y = pos[inds[i, 2], 1]
            # Center of cell
            cent[i, 0] = (v1x + v2x + v3x) / 3.0
            cent[i, 1] = (v1y + v2y + v3y) / 3.0
            # Triangle internal angles
            s1 = np.sqrt((v3x - v2x)**2 + (v3y - v2y)**2)
            s2 = np.sqrt((v1x - v3x)**2 + (v1y - v3y)**2)
            s3 = np.sqrt((v2x - v1x)**2 + (v2y - v1y)**2)
            a1 = np.arccos((v2x-v1x)*(v3x-v1x)/(s3*s2)+\
               (v2y-v1y)*(v3y-v1y)/(s3*s2))
            a2 = np.arccos((v3x-v2x)*(v1x-v2x)/(s1*s3)+\
               (v3y-v2y)*(v1y-v2y)/(s1*s3))
            a3 = np.arccos((v2x-v3x)*(v1x-v3x)/(s1*s2)+\
               (v2y-v3y)*(v1y-v3y)/(s1*s2))
            # If any of the internal angles is less than
            # specified minimum, invalidate triangle
            if a1 < par or a2 < par or a3 < par:
                inds[i, :] = np.zeros(3)
    # If nearest neighbor or distance weighted
    else:
        # Construct grid
        xmin = min(pos[:, 0])
        xmax = max(pos[:, 0])
        ymin = min(pos[:, 1])
        ymax = max(pos[:, 1])
        cellsx = int(np.ceil((xmax - xmin) / par[0]))
        cellsy = int(np.ceil((ymax - ymin) / par[0]))
        xgrid = np.arange(xmin, (xmin + (cellsx + 1) * par[0]), par[0])
        ygrid = np.arange(ymin, (ymin + (cellsy + 1) * par[0]), par[0])
        XX, YY = np.meshgrid(xgrid, ygrid)
        # Number of cells
        ncells = cellsx * cellsy
        # Number of stations per cell (nstat) and
        # other parameters
        # If nearest neighbor
        if k == 1:
            nstat = par[1]  # max neighbors
            sqmd = par[2]**2  # max squared distance
        # If distance weighted
        elif k == 2:
            nstat = np.size(pos, 0)  # all stations
            dalpha = 2.0 * par[1] * par[1]  # 2*alpha*alpha
        # Cells' centers
        cent = np.zeros((ncells, 2))
        count = 0
        for i in range(0, cellsy):
            for j in range(0, cellsx):
                cent[count, 0] = (XX[i, j] + XX[i, j + 1]) / 2.0
                cent[count, 1] = (YY[i, j] + YY[i + 1, j]) / 2.0
                count += 1
        # Initialize stations indexes for cells to -1
        inds = np.ones((ncells, nstat), dtype=int) * -1
        # Initialize weight matrix for distance weighted
        wv = np.zeros((ncells, nstat * 2))
        # For all cells set stations indexes
        for i in range(0, ncells):
            # Initialize sq distances to -1.0
            sds = np.ones(nstat) * -1.0
            # For all stations
            for j in range(0, np.size(pos, 0)):
                # Sq distance from cell center to station
                dx = cent[i, 0] - pos[j, 0]
                dy = cent[i, 1] - pos[j, 1]
                sd = dx**2 + dy**2
                # If nearest neighbor
                if k == 1:
                    # If within the max sq distance
                    if sd <= sqmd:
                        minsd = min(sds)
                        mini = np.argmin(sds)
                        # If less than max neighbors
                        if minsd == -1.0:
                            sds[mini] = sd
                            inds[i, mini] = j
                        # If max neighbors
                        else:
                            # If sq distance is less
                            # than neighbors max sq distance
                            maxsd = max(sds)
                            maxi = np.argmax(sds)
                            if sd < maxsd:
                                sds[maxi] = sd
                                inds[i, maxi] = j
                # If distance weighted
                elif k == 2:
                    # All stations indexes
                    inds[i, :] = np.arange(nstat)
                    # Eq. 8.27: Weight factor
                    weight = np.exp(-sd / dalpha)
                    wv[i, j * 2] = weight
                    wv[i, j * 2 + 1] = weight

    # Initialize arrays
    y = np.zeros(nstat * 2)
    M = np.zeros((nstat * 2, 6))
    e = np.zeros((3, 3))
    eps = np.zeros((3, 3, ncells))
    ome = np.zeros((3, 3, ncells))
    pstrain = np.zeros((3, 3, ncells))
    rotc = np.zeros((ncells, 3))

    # For each cell
    for i in range(0, ncells):
        # If required minimum number of stations
        if min(inds[i, :]) >= 0:
            # Eq. 8.24: Displacements column vector y
            # and design matrix M. X1 = North, X2 = East
            for j in range(0, nstat):
                ic = inds[i, j]
                y[j * 2] = disp[ic, 1]
                y[j * 2 + 1] = disp[ic, 0]
                M[j * 2, :] = [1., 0., pos[ic, 1], pos[ic, 0], 0., 0.]
                M[j * 2 + 1, :] = [0., 1., 0., 0., pos[ic, 1], pos[ic, 0]]
            # Eqs. 8.25-8.26: Find x using function lscov
            # If Delaunay or nearest neighbor
            if k == 0 or k == 1:
                x = lscov(M, y)
            # If distance weighted
            elif k == 2:
                x = lscov(M, y, wv[i, :])
            # Displacement gradient tensor
            for j in range(0, 2):
                e[j, 0] = x[j * 2 + 2]
                e[j, 1] = x[j * 2 + 3]
            # Compute strain
            eps[:,:,i],ome[:,:,i],pstrain[:,:,i],\
             rotc[i,:],_ = InfStrain(e)

    # Variable to plot
    # If maximum principal strain
    if plotpar == 0:
        vp = pstrain[0, 0, :]
        lcb = "emax"
    # If minimum principal strain
    elif plotpar == 1:
        vp = pstrain[2, 0, :]
        lcb = "emin"
    # If rotation:
    # For plane strain, rotation = rotc(3)
    elif plotpar == 2:
        vp = rotc[:, 2] * 180 / pi
        lcb = "Rotation (deg)"
    # If dilatation
    elif plotpar == 3:
        vp = pstrain[0, 0, :] + pstrain[1, 0, :] + pstrain[2, 0, :]
        lcb = "dilatation"

    # Make a figure
    fig, ax = plt.subplots()
    fig.set_size_inches(15.0, 7.5)

    # Patches and colors for cells
    patches = []
    colors = []

    # Fill cells patches and colors
    # If Delaunay
    if k == 0:
        for i in range(0, ncells):
            # If minimum number of stations
            if min(inds[i, :]) >= 0:
                xpyp = [[pos[inds[i,0],0],pos[inds[i,0],1]],\
                  [pos[inds[i,1],0],pos[inds[i,1],1]],\
                  [pos[inds[i,2],0],pos[inds[i,2],1]]]
                # length in km
                xpyp = np.divide(xpyp, 1e3)
                polygon = Polygon(xpyp, True)
                patches.append(polygon)
                colors.append(vp[i])
    # If nearest neighbor or distance weighted
    if k == 1 or k == 2:
        count = 0
        for i in range(0, cellsy):
            for j in range(0, cellsx):
                # If minimum number of stations
                if min(inds[count, :]) >= 0:
                    xpyp = [[XX[i,j],YY[i,j]],[XX[i,j+1],YY[i,j+1]],\
                     [XX[i+1,j+1],YY[i+1,j+1]],[XX[i+1,j],YY[i+1,j]]]
                    # length in km
                    xpyp = np.divide(xpyp, 1e3)
                    polygon = Polygon(xpyp, True)
                    patches.append(polygon)
                    colors.append(vp[count])
                count += 1

    # Collect cells patches
    pcoll = PatchCollection(patches)
    # Cells colors
    pcoll.set_array(np.array(colors))
    # Color map is blue to red
    pcoll.set_cmap('bwr')
    # Positive values are red, negative are
    # blue and zero is white
    vmin = min(vp)
    vmax = max(vp)
    norm = mcolors.TwoSlopeNorm(vmin=vmin, vcenter=0.0, vmax=vmax)
    pcoll.set_norm(norm)

    # Draw cells
    ax.add_collection(pcoll)

    # Plot stations
    if plotst == 1:
        plt.plot(pos[:, 0] * 1e-3, pos[:, 1] * 1e-3, 'k.', markersize=2)

    # Axes
    plt.axis('equal')
    plt.xlabel('x (km)')
    plt.ylabel('y (km)')

    # Color bar with nice ticks
    intv = (vmax - vmin) * 0.25
    ticks = [vmin, vmin + intv, vmin + 2 * intv, vmin + 3 * intv, vmax]
    lticks = ['{:.2e}'.format(ticks[0]),\
      '{:.2e}'.format(ticks[1]),'{:.2e}'.format(ticks[2]),\
      '{:.2e}'.format(ticks[3]),'{:.2e}'.format(ticks[4])]
    cbar = fig.colorbar(pcoll, label=lcb, ticks=ticks)
    cbar.ax.set_yticklabels(lticks)

    # Show plot
    plt.show()

    return cent, eps, ome, pstrain, rotc
Пример #38
0
def create_bus_symbol_collection(coords,
                                 buses=None,
                                 size=5,
                                 marker="o",
                                 patch_type="circle",
                                 colors=None,
                                 z=None,
                                 cmap=None,
                                 norm=None,
                                 infofunc=None,
                                 picker=False,
                                 net=None,
                                 **kwargs):
    infos = []

    if 'height' in kwargs and 'width' in kwargs:
        height, width = kwargs['height'], kwargs['width']
    else:
        height, width = size, size

    def figmaker(x, y, i):
        if patch_type == "circle":
            if colors:
                fig = Circle((x, y), size, color=colors[i], **kwargs)
            else:
                fig = Circle((x, y), size, **kwargs)
        elif patch_type == 'ellipse':
            angle = kwargs['angle'] if 'angle' in kwargs else 0
            if colors:
                fig = Ellipse((x, y),
                              width=width,
                              height=height,
                              color=colors[i],
                              **kwargs)
            else:
                fig = Ellipse((x, y),
                              width=width,
                              height=height,
                              angle=angle,
                              **kwargs)
        elif patch_type == "rect":
            if colors:
                fig = Rectangle([x - width, y - height],
                                2 * width,
                                2 * height,
                                color=colors[i],
                                **kwargs)
            else:
                fig = Rectangle([x - width, y - height], 2 * width, 2 * height,
                                **kwargs)
        elif patch_type.startswith("poly"):
            edges = int(patch_type[4:])
            if colors:
                fig = RegularPolygon([x, y],
                                     numVertices=edges,
                                     radius=size,
                                     color=colors[i],
                                     **kwargs)
            else:
                fig = RegularPolygon([x, y],
                                     numVertices=edges,
                                     radius=size,
                                     **kwargs)
        else:
            logger.error(
                "Wrong patchtype. Please choose a correct patch type.")
        if infofunc:
            infos.append(infofunc(buses[i]))
        return fig

    patches = [
        figmaker(x, y, i) for i, (x, y) in enumerate(coords) if x != np.nan
    ]
    pc = PatchCollection(patches, match_original=True, picker=picker)
    pc.bus_indices = np.array(buses)
    if cmap:
        pc.set_cmap(cmap)
        pc.set_norm(norm)
        if z is None and net:
            z = net.res_bus.vm_pu.loc[buses]
        else:
            logger.warning("z is None and no net is provided")
        pc.set_array(np.array(z))
        pc.has_colormap = True
        pc.cbar_title = "Bus Voltage [pu]"

    pc.patch_type = patch_type
    pc.size = size
    if 'orientation' in kwargs:
        pc.orientation = kwargs['orientation']
    if "zorder" in kwargs:
        pc.set_zorder(kwargs["zorder"])
    pc.info = infos
    return pc
Пример #39
0
def plot_polygon_collection(ax, geoms, values=None, color=None,
                            cmap=None, vmin=None, vmax=None, **kwargs):
    """
    Plots a collection of Polygon and MultiPolygon geometries to `ax`

    Parameters
    ----------

    ax : matplotlib.axes.Axes
        where shapes will be plotted

    geoms : a sequence of `N` Polygons and/or MultiPolygons (can be mixed)

    values : a sequence of `N` values, optional
        Values will be mapped to colors using vmin/vmax/cmap. They should
        have 1:1 correspondence with the geometries (not their components).
        Otherwise follows `color` / `facecolor` kwargs.

    edgecolor : single color or sequence of `N` colors
        Color for the edge of the polygons

    facecolor : single color or sequence of `N` colors
        Color to fill the polygons. Cannot be used together with `values`.

    color : single color or sequence of `N` colors
        Sets both `edgecolor` and `facecolor`

    **kwargs
        Additional keyword arguments passed to the collection

    Returns
    -------

    collection : matplotlib.collections.Collection that was plotted
    """
    from descartes.patch import PolygonPatch
    from matplotlib.collections import PatchCollection

    geoms, values = _flatten_multi_geoms(geoms, values)
    if None in values:
        values = None

    # PatchCollection does not accept some kwargs.
    if 'markersize' in kwargs:
        del kwargs['markersize']

    # color=None overwrites specified facecolor/edgecolor with default color
    if color is not None:
        kwargs['color'] = color

    collection = PatchCollection([PolygonPatch(poly) for poly in geoms],
                                 **kwargs)

    if values is not None:
        collection.set_array(np.asarray(values))
        collection.set_cmap(cmap)
        collection.set_clim(vmin, vmax)

    ax.add_collection(collection, autolim=True)
    ax.autoscale_view()
    return collection
Пример #40
0
def patchValMap(vals,
                xvec=None,
                yvec=None,
                ax=None,
                cMin=None,
                cMax=None,
                logScale=None,
                label=None,
                dx=1,
                dy=None,
                **kwargs):
    """Plot previously generated (generateVecMatrix) y map (category).

    Parameters
    ----------
    vals : iterable
        Data values to show.
    xvec : dict {i:num}
        dict (must match vals.shape[0])
    ymap : iterable
        vector for x axis (must match vals.shape[0])
    ax : mpl.axis
        axis to plot, if not given a new figure is created
    cMin/cMax : float
        minimum/maximum color values
    logScale : bool
        logarithmic colour scale [min(vals)>0]
    label : string
        colorbar label
    ** kwargs:
        * circular : bool
            Plot in polar coordinates.
    """
    if cMin is None:
        cMin = np.min(vals)
    if cMax is None:
        cMax = np.max(vals)

    if logScale is None:
        logScale = (cMin > 0.0)

    norm = None
    if logScale and cMin > 0:
        norm = LogNorm(vmin=cMin, vmax=cMax)
    else:
        norm = Normalize(vmin=cMin, vmax=cMax)

    if ax is None:
        ax = plt.subplots()[1]

    recs = []

    circular = kwargs.pop('circular', False)
    if circular:
        recs = [None] * len(xvec)
        if dy is None:  # map y values to unique
            ymap = {xy: ii for ii, xy in enumerate(np.unique(yvec))}

            xyMap = {}
            for i, y in enumerate(yvec):
                if y not in xyMap:
                    xyMap[y] = []
                xyMap[y].append(i)

            maxR = max(ymap.values())  # what's that for? not used
            dR = 1 / (len(ymap.values()) + 1)

            dOff = np.pi / 2  # what's that for? not used

            for y, xIds in xyMap.items():
                r = 1. - dR * (ymap[y] + 1)
                # ax.plot(r * np.cos(xvec[xIds]),
                #         r * np.sin(xvec[xIds]), 'o')

                # print(y, ymap[y])
                for i in xIds:
                    phi = xvec[i]
                    x = r * np.cos(phi)  # what's that for? not used
                    y = r * np.sin(phi)

                    dPhi = (xvec[1] - xvec[0])

                    recs[i] = Wedge((0., 0.),
                                    r + dR / 1.5,
                                    (phi - dPhi) * 360 / (2 * np.pi),
                                    (phi + dPhi) * 360 / (2 * np.pi),
                                    width=dR,
                                    zorder=1 + r)
                    # if i < 5:
                    #     ax.text(x, y, str(i))
                    # pg.wait()
        else:
            raise ("Implementme")
    else:
        if dy is None:  # map y values to unique
            ymap = {xy: ii for ii, xy in enumerate(np.unique(yvec))}
            for i in range(len(vals)):
                recs.append(
                    Rectangle((xvec[i] - dx / 2, ymap[yvec[i]] - 0.5), dx, 1))
        else:
            for i in range(len(vals)):
                recs.append(
                    Rectangle((xvec[i] - dx / 2, yvec[i] - dy / 2), dx, dy))
        ax.set_xlim(min(xvec) - dx / 2, max(xvec) + dx / 2)
        ax.set_ylim(len(ymap) - 0.5, -0.5)

    pp = PatchCollection(recs)
    # ax.clear()
    col = ax.add_collection(pp)
    pp.set_edgecolor(None)
    pp.set_linewidths(0.0)

    if circular:
        pp.set_edgecolor('black')
        pp.set_linewidths(0.1)

    cmap = pg.mplviewer.cmapFromName(**kwargs)
    if kwargs.pop('markOutside', False):
        cmap.set_bad('grey')
        cmap.set_under('darkgrey')
        cmap.set_over('lightgrey')
        cmap.set_bad('black')
    pp.set_cmap(cmap)

    pp.set_norm(norm)
    pp.set_array(vals)
    pp.set_clim(cMin, cMax)

    updateAxes_(ax)
    cbar = kwargs.pop('colorBar', True)
    ori = kwargs.pop('orientation', 'horizontal')
    if cbar in ['horizontal', 'vertical']:
        ori = cbar
        cbar = True

    if cbar is True:  # not for cbar=1, which is really confusing!
        cbar = pg.mplviewer.createColorBar(col,
                                           cMin=cMin,
                                           cMax=cMax,
                                           nLevs=5,
                                           label=label,
                                           orientation=ori)
    elif cbar is not False:
        # .. cbar is an already existing cbar .. so we update its values
        pg.mplviewer.updateColorBar(cbar,
                                    cMin=cMin,
                                    cMax=cMax,
                                    nLevs=5,
                                    label=label)

    updateAxes_(ax)
    return ax, cbar, ymap
Пример #41
0
def factcamera(self,
               data,
               pixelcoords=None,
               cmap='gray',
               vmin=None,
               vmax=None,
               pixelset=None,
               pixelsetcolour='g',
               linewidth=None,
               intersectcolour='b',
               picker=True,
               ):
    """
    Attributes
    ----------

    data     : array like with shape 1440
        the data you want to plot into the pixels
    pixelset : boolean array with shape 1440
        the pixels where pixelset is True are marked with 'pixelsetcolour'
        [default: None]
    pixelsetcolour : a matplotlib conform colour representation
        the colour for the pixels in 'pixelset',
        [default: green]
    pixelcoords : the coordinates for the pixels in form [x-values, y-values]
        if None, the package resource is used
        [default: None]
    cmap : str or matplotlib colormap instance
        the colormap to use for plotting the 'dataset'
        [default: gray]
    vmin : float
        the minimum for the colorbar, if None min(dataset[event]) is used
        [default: None]
    vmax : float
        the maximum for the colorbar, if None max(dataset[event]) is used
        [default: None]
    picker: bool
        if True then the the pixel are made clickable to show information
    """

    self.set_aspect('equal')

    if picker is True:
        fig = self.get_figure()
        fig.canvas.mpl_connect("pick_event", onpick)

    # if the axes limit is still (0,1) assume new axes
    if self.get_xlim() == (0, 1) and self.get_ylim() == (0, 1):
        self.set_xlim(-200, 200)
        self.set_ylim(-200, 200)

    if pixelcoords is None:
        pixel_x, pixel_y = get_pixel_coords()
    else:
        pixel_x, pixel_y = pixelcoords

    if vmin is None:
        vmin = np.min(data)
    if vmax is None:
        vmax = np.max(data)

    edgecolors = np.array(1440*["k"])

    if pixelset is None:
        pixelset = np.zeros(1440, dtype=np.bool)

    _pixelset = np.array(pixelset)
    if _pixelset.ndim == 1:
        if _pixelset.shape != (1440,):
            pixelset = np.zeros(1440, dtype=np.bool)
            pixelset[_pixelset] = True
        else:
            pixelset = np.array(_pixelset, dtype=np.bool)
        edgecolors[pixelset] = pixelsetcolour
    elif _pixelset.ndim == 2:
        for pixelset, colour in zip(_pixelset, pixelsetcolour):
            edgecolors[pixelset] = colour
        intersect = np.logical_and(_pixelset[0], _pixelset[1])
        edgecolors[intersect] = intersectcolour

    else:
        raise ValueError(
            """pixelset needs to be one of:
            1. list of pixelids
            2. 1d bool array with shape (1440,)
            3. 2d bool array with shape (2, 1440)
            """
        )


    patches = []
    for x, y, ec in zip(pixel_x, pixel_y, edgecolors):
        patches.append(
            RegularPolygon(
                xy=(x, y),
                numVertices=6,
                radius=0.95*9.5/np.sqrt(3),
                orientation=0.,   # in radians
            )
        )

    if linewidth is None:
        linewidth = calc_linewidth(self)

    collection = PatchCollection(patches, picker=0)
    collection.set_linewidth(linewidth)
    collection.set_edgecolors(edgecolors)
    collection.set_cmap(cmap)
    collection.set_array(data)
    collection.set_clim(vmin, vmax)

    self.add_collection(collection)
    return collection
Пример #42
0
def _plot_polygon_collection(ax,
                             geoms,
                             values=None,
                             color=None,
                             cmap=None,
                             vmin=None,
                             vmax=None,
                             **kwargs):
    """
    Plots a collection of Polygon and MultiPolygon geometries to `ax`

    Parameters
    ----------
    ax : matplotlib.axes.Axes
        where shapes will be plotted
    geoms : a sequence of `N` Polygons and/or MultiPolygons (can be mixed)

    values : a sequence of `N` values, optional
        Values will be mapped to colors using vmin/vmax/cmap. They should
        have 1:1 correspondence with the geometries (not their components).
        Otherwise follows `color` / `facecolor` kwargs.
    edgecolor : single color or sequence of `N` colors
        Color for the edge of the polygons
    facecolor : single color or sequence of `N` colors
        Color to fill the polygons. Cannot be used together with `values`.
    color : single color or sequence of `N` colors
        Sets both `edgecolor` and `facecolor`
    **kwargs
        Additional keyword arguments passed to the collection

    Returns
    -------
    collection : matplotlib.collections.Collection that was plotted
    """
    from matplotlib.collections import PatchCollection

    geoms, multiindex = _flatten_multi_geoms(geoms)
    if values is not None:
        values = np.take(values, multiindex, axis=0)

    # PatchCollection does not accept some kwargs.
    kwargs = {
        att: value
        for att, value in kwargs.items()
        if att not in ["markersize", "marker"]
    }

    # Add to kwargs for easier checking below.
    if color is not None:
        kwargs["color"] = color

    _expand_kwargs(kwargs, multiindex)

    collection = PatchCollection(
        [_PolygonPatch(poly) for poly in geoms if not poly.is_empty], **kwargs)

    if values is not None:
        collection.set_array(np.asarray(values))
        collection.set_cmap(cmap)
        if "norm" not in kwargs:
            collection.set_clim(vmin, vmax)

    ax.add_collection(collection, autolim=True)
    ax.autoscale_view()
    return collection
Пример #43
0
def plot_polygon_collection(ax, geoms, colors_or_values, plot_values,
                            vmin=None, vmax=None, cmap=None,
                            edgecolor='black', alpha=0.5, linewidth=1.0, **kwargs):
    """
    Plots a collection of Polygon and MultiPolygon geometries to `ax`

    Parameters
    ----------

    ax : matplotlib.axes.Axes
        where shapes will be plotted

    geoms : a sequence of `N` Polygons and/or MultiPolygons (can be mixed)

    colors_or_values : a sequence of `N` values or RGBA tuples
        It should have 1:1 correspondence with the geometries (not their components).

    plot_values : bool
        If True, `colors_or_values` is interpreted as a list of values, and will
        be mapped to colors using vmin/vmax/cmap (which become required).
        Otherwise `colors_or_values` is interpreted as a list of colors.

    Returns
    -------

    collection : matplotlib.collections.Collection that was plotted
    """

    from descartes.patch import PolygonPatch
    from matplotlib.collections import PatchCollection

    components, component_colors_or_values = _flatten_multi_geoms(
        geoms, colors_or_values)

    # PatchCollection does not accept some kwargs.
    if 'markersize' in kwargs:
        del kwargs['markersize']
    collection = PatchCollection([PolygonPatch(poly) for poly in components],
                                 linewidth=linewidth, edgecolor=edgecolor,
                                 alpha=alpha, **kwargs)

    if plot_values:
        collection.set_array(np.array(component_colors_or_values))
        collection.set_cmap(cmap)
        collection.set_clim(vmin, vmax)
    else:
        # set_color magically sets the correct combination of facecolor and
        # edgecolor, based on collection type.
        collection.set_color(component_colors_or_values)

        # If the user set facecolor and/or edgecolor explicitly, the previous
        # call to set_color might have overridden it (remember, the 'color' may
        # have come from plot_series, not from the user). The user should be
        # able to override matplotlib's default behavior, by setting them again
        # after set_color.
        if 'facecolor' in kwargs:
            collection.set_facecolor(kwargs['facecolor'])
        if edgecolor:
            collection.set_edgecolor(edgecolor)

    ax.add_collection(collection, autolim=True)
    ax.autoscale_view()
    return collection