Example #1
0
def custom_plot(image, box=None, polygons=None):
    #target.extra_fields['masks'].polygons è una lista in cui ogni elemento ha un .polygons
    # che è una lista di tensor

    fig, ax = plt.subplots(1)
    ax.imshow(image)

    if box is not None:
        for bb in box:
            rect = Rectangle((int(bb[0]), int(bb[1])),
                             int(bb[2]),
                             int(bb[3]),
                             linewidth=1,
                             edgecolor='r',
                             facecolor='none')
            ax.add_patch(rect)

    if polygons is not None:
        patches = []
        for p in polygons:
            for p2 in p.polygons:
                polygon = Polygon(p2.numpy().reshape((-1, 2)), False)
                patches.append(polygon)
        p = PatchCollection(patches, alpha=0.4)
        p.set_linewidth(2.0)
        p.set_edgecolor('r')
        ax.add_collection(p)

    plt.show()
Example #2
0
def create_pixels(lons,lats,widths,heights,alphas,color,label):
	"""
	Plot of pixels using centers (lons,lats), with sizes (widhts,heights), angle alphas, and color color.

	:param lons: array of longitude coordinates at the center of the pixels
	:param lats: array of latitude coordinates at the center of the pixels
	:param widths: array of widhts of the pixels
	:param heights: array of heights of the pixels
	:param alphas: array of angles of the pixels
	:param color: tuple with RGB color values
	:return col: collection of rectangles with the pixels

	Developed in Python 2.7.15 :: Anaconda 4.5.10, on MACINTOSH.
	Angel Farguell ([email protected]) 2018-12-28
	"""

	# Create pixels
	pixels=[]
	for x, y, h, w, a in zip(lons, lats, heights, widths, alphas):
		xpos = x - w/2 # The x position will be half the width from the center
		ypos = y - h/2 # same for the y position, but with height
		rect = Rectangle( (xpos, ypos), w, h, a) # Create a rectangle
		pixels.append(rect) # Add the rectangle patch to our list

	# Create a collection from the rectangles
	col = PatchCollection(pixels)
	# set the alpha for all rectangles
	col.set_alpha(0.5)
	# Set the colors using the colormap
	col.set_facecolor( [color]*len(lons) )
	# No lines
	col.set_linewidth( 0 )

	return col
Example #3
0
def get_annotations(tiles_w, image_size, indices, coordinates):
	patches = []
	colors = []
	for index in range(canvas.shape[0]):
		x = index % tiles_w
		y = int(np.floor(index / tiles_w))

		tile = int(indices[index])
		if tile == -1:
			continue
		else:
			(lat, lon) = coordinates[tile]
			if np.isnan(lat) or np.isnan(lon):
				continue
			fc = lonlat2rgba(lon, lat)
			rect = mpatches.Rectangle((x * image_size, y * image_size), image_size, image_size)
			patches.append(rect)
			colors.append(fc)
			#image[((y + 1) * image_size, x * image_size):(x + 1) * image_size] = canvas[index]
	#colors = 100 * np.random.rand(len(patches))
	collection = PatchCollection(patches, alpha=0.35)
	collection.set_facecolors(colors)
	collection.set_edgecolors(colors)
	collection.set_linewidth(0.1)
	#collection.set_array(np.array(colors))
	return collection
Example #4
0
	def draw(self, ax, colour='k', alpha=1., linestyle='-', linewidth=1., 
		markers=None, facecolor='none', dashes=(1, 1), zorder=0):
		"""
		Draw the polygon on ax
		"""
		# Add the last point
		ptstoplot = self.verts.tolist()
		ptstoplot.append(ptstoplot[0])
		ptstoplot = np.array(ptstoplot)
		if facecolor == 'none':
			try:
				if linestyle == '--':
					ax.plot(ptstoplot[:, 0], ptstoplot[:, 1], c=colour, alpha=alpha,
						ls=linestyle, dashes=dashes, lw=linewidth, marker=markers, zorder=zorder)
				else:
					ax.plot(ptstoplot[:, 0], ptstoplot[:, 1], c=colour, alpha=alpha,
						ls=linestyle, lw=linewidth, marker=markers, zorder=zorder)
			except IndexError:
				pass
		else:
			patches = []
			filled_pol = mp.Polygon(self.verts)
			patches.append(filled_pol)
			collection = PatchCollection(patches, facecolors=facecolor)
			ax.add_collection(collection)
			collection.set_alpha(alpha)
			collection.set_edgecolor(colour)
			collection.set_linewidth(linewidth)
			collection.set_linestyle(linestyle)
Example #5
0
def mark_pixel(pixels, color='g', ax=None, linewidth=None):
    ''' surrounds pixels given by pixels with a border '''
    pixel_x, pixel_y = get_pixel_coords()

    if ax is None:
        ax = plt.gca()

    patches = []
    for xy in zip(pixel_x[pixels], pixel_y[pixels]):
        patches.append(
            RegularPolygon(
                xy=xy,
                numVertices=6,
                radius=9.5 / np.sqrt(3),
                orientation=0.,  # in radians
                fill=False,
            ))

    if linewidth is None:
        linewidth = calc_linewidth(ax=ax)

    collection = PatchCollection(patches, picker=0)
    collection.set_linewidth(linewidth)
    collection.set_edgecolors(color)
    collection.set_facecolor('none')

    ax.add_collection(collection)

    plt.draw_if_interactive()
    return collection
Example #6
0
    def add_circles(self, ax, centers, radis):
        circles = []
        for c, r in zip(centers, radis):
            circles.append(patches.Circle(tuple(c), r))

        patch_collection = PatchCollection(circles)
        patch_collection.set_facecolor("none")
        patch_collection.set_edgecolor("blue")
        patch_collection.set_linewidth(1.5)
        patch_collection.set_linestyle("dashed")
        ax.add_collection(patch_collection)
        print "added %d circles" % len(circles)
Example #7
0
    def plotpatchcollection(self, mypatches, mycolors=[], mylw=[]):
        self.canvas.figure.clf()
        ax = self.canvas.figure.subplots()

        p = PatchCollection(mypatches)  # , alpha=0.4)
        p.set_facecolor(tuple(mycolors))
        p.set_linewidth(mylw)

        ax.add_collection(p)
        ax.autoscale(enable=True, axis="both", tight=None)

        self.canvas.draw()
Example #8
0
def get_mpas_patch_collection(nVertices,
                              vertexDegree,
                              interiorVertex,
                              cellsOnVertex,
                              xCell,
                              yCell,
                              mpasArray,
                              cmap,
                              vmin,
                              vmax,
                              limitPatches=False,
                              rasterizePatches=False):

    patches = []
    colours = []

    minval = 1.0e30
    maxval = -1.0e30

    nPatches = 0
    for iVertex in range(0, nVertices):

        if (interiorVertex[iVertex] == 1 and
            (math.fabs(mpasArray[iVertex]) > 1e-3 or not limitPatches)):

            polygonVertices = []

            for iVertexDegree in range(0, vertexDegree):

                iCell = cellsOnVertex[iVertex, iVertexDegree] - 1

                polygonVertices.append((xCell[iCell], yCell[iCell]))

            polygon = Polygon(polygonVertices)
            patches.append(polygon)

            colours.append(mpasArray[iVertex])

            minval = min(minval, mpasArray[iVertex])
            maxval = max(maxval, mpasArray[iVertex])

            nPatches = nPatches + 1

    print("nPatches: ", nPatches, limitPatches)

    patchCollection = PatchCollection(patches,
                                      cmap=cmap,
                                      rasterized=rasterizePatches)
    patchCollection.set_array(np.array(colours))
    patchCollection.set_linewidth(0)
    patchCollection.set_clim(vmin=vmin, vmax=vmax)

    return patchCollection, minval, maxval
Example #9
0
def draw_bboxes(bboxes, ax=None, color='red', linewidth=1, **kw):
    if ax is None:
        ax = plt.gca()
    patches = [
        mpatches.Rectangle((i[1], i[0]), i[3] - i[1], i[2] - i[0])
        for i in bboxes
    ]
    boxcoll = PatchCollection(patches, **kw)
    boxcoll.set_facecolor('none')
    boxcoll.set_edgecolor(color)
    boxcoll.set_linewidth(linewidth)
    ax.collections = []
    ax.add_collection(boxcoll)
Example #10
0
def get_shape_collections(data: Dict):
    shapes = []

    for points in data.values():
        shapes.append(
            Polygon(np.array([points['lons'], points['lats']]).T, closed=True))

    collection = PatchCollection(shapes)
    collection.set_facecolor('#eeeeee')
    collection.set_edgecolor('black')
    collection.set_linewidth(0.2)

    return collection
Example #11
0
def VoronoiPlot(points: Sequence,
                values: Sequence,
                vmin: float = None,
                vmax: float = None,
                cmap=None):
    """ plot the voronoi regions of the poins with the given colormap """
    from matplotlib.patches import Polygon
    from matplotlib.collections import PatchCollection
    from scipy.spatial import Voronoi, voronoi_plot_2d
    from matplotlib import cm

    if cmap is None:
        cmap = cm.get_cmap('viridis')

    vor = Voronoi(points)

    # %%
    patches = []
    dist_list = []
    excluded_indices = []
    for index, p in enumerate(points):
        # print(index)
        reg = vor.regions[vor.point_region[index]]
        if -1 in reg:
            # plt.plot(p[0], p[1], 'ok', alpha=0.3, ms=1)
            excluded_indices.append(index)
            continue
        distances = np.linalg.norm(np.array([vor.vertices[i]
                                             for i in reg]) - p,
                                   axis=1)
        if np.max(distances) > 2:
            # plt.plot(p[0], p[1], 'ok', alpha=0.3, ms=1)
            excluded_indices.append(index)
            continue
        region = np.array([vor.vertices[i] for i in reg])
        polygon = Polygon(region, True)
        patches.append(polygon)
        dists = values[index]
        dist_list.append(dists)
        # plt.plot(p[0], p[1], 'ok', alpha=0.3, ms=1)

    p = PatchCollection(patches, cmap=cmap)
    p.set_clim([vmin, vmax])
    p.set_array(np.array(dist_list))
    p.set_linewidth(10)

    plt.gca().add_collection(p)
    plt.xticks([])
    plt.yticks([])
    return p, excluded_indices
Example #12
0
    def zoneLines(self, edgecolour='black'):        #was 'red'
        """
        Set boundary colour for defined ESRI shapes
        edgecolour -- HTML colour name for boundary
        """

        pc2 = PatchCollection(self.patches, match_original=True)
        pc2.set_facecolor('none')
        pc2.set_edgecolor(edgecolour)
        pc2.set_alpha(0.5) #5.0
        pc2.set_linewidth(0.5)
        pc2.set_zorder(25) # 500

        sq2 = self.ax.add_collection(pc2)
def plot_trajectory_ellipse(frame, varx="attr_VARX", vary="attr_VARY", covxy="attr_COVXY", opacity_factor=1):
    """
    Draw the trajectory and uncertainty ellipses around teach point.
    1) Scatter of points 
    2) Trajectory lines
    3) Ellipses 
    :param frame: Trajectory
    :param opacity_factor: all opacity values are multiplied by this. Useful when used to plot multiple Trajectories in
     an overlay plot.
    :return: axis
    """
    ellipses = []    
    segments = []
    start_point = None

    for i, pnt in frame.iterrows():  
        # The ellipse
        U, s, V = np.linalg.svd(np.array([[pnt[varx], pnt[covxy]], 
                                          [pnt[covxy], pnt[vary]]]), full_matrices=True)
        w, h = s**.5 
        theta = np.arctan(V[1][0]/V[0][0])   # == np.arccos(-V[0][0])              
        ellipse = {"xy":pnt[list(frame.geo_cols)].values, "width":w, "height":h, "angle":theta}
        ellipses.append(Ellipse(**ellipse))
        
        # The line segment
        x, y = pnt[list(frame.geo_cols)][:2]
        if start_point:           
            segments.append([start_point, (x, y)])
        start_point = (x, y)

    ax = plt.gca()
    ellipses = PatchCollection(ellipses)
    ellipses.set_facecolor('none')
    ellipses.set_color("green")
    ellipses.set_linewidth(2)
    ellipses.set_alpha(.4*opacity_factor)
    ax.add_collection(ellipses)

    frame.plot(kind="scatter", x=frame.geo_cols[0], y=frame.geo_cols[1], marker=".", ax=plt.gca(), alpha=opacity_factor)

    lines = LineCollection(segments)
    lines.set_color("gray")
    lines.set_linewidth(1)
    lines.set_alpha(.2*opacity_factor)
    ax.add_collection(lines)
    return ax
Example #14
0
def get_mpas_patch_collection(nVertices, vertexDegree, cellsOnVertex, xCell,
                              yCell, zCell, latVertex, mpasArray, cmap, vmin,
                              vmax, minX, maxX, minY, maxY):

    minval = 1.0e30
    maxval = -1.0e30

    patches = []
    colours = []
    for iVertex in range(0, nVertices):

        if (math.fabs(latVertex[iVertex]) > math.radians(20.0)):

            useVertex = False
            polygonVertices = []
            for iCellOnVertex in range(0, vertexDegree[iVertex]):

                iCell = cellsOnVertex[iVertex, iCellOnVertex]
                x, y, z = ortho_projection(xCell[iCell], yCell[iCell],
                                           zCell[iCell])

                if (x >= minX and x <= maxX and \
                    y >= minY and y <= maxY and \
                    z > 0.0):
                    useVertex = True

                polygonVertices.append((x, y))

            # create patch and add to collection
            if (useVertex):
                polygon = Polygon(polygonVertices)
                patches.append(polygon)

                colours.append(mpasArray[iVertex])

                minval = min(minval, mpasArray[iVertex])
                maxval = max(maxval, mpasArray[iVertex])

    patchCollection = PatchCollection(patches, cmap=cmap, rasterized=True)
    patchCollection.set_array(np.array(colours))
    patchCollection.set_linewidth(0)

    patchCollection.set_clim(vmin=vmin, vmax=vmax)

    return patchCollection, minval, maxval
Example #15
0
    def zoneColour(self, colours):
        """
        Set display colours for defined ESRI shapes
        colours -- list containing HTML colour names
        """

        self.colours = colours

        if not (isinstance(self.colours, list)):
            raise Exception('Invalid list of zone colours')

        pc = PatchCollection(self.patches, match_original=True)
        pc.set_facecolor(self.colours)
        pc.set_edgecolor('none')
        pc.set_alpha(0.5)
        pc.set_linewidth(0.5)
        pc.set_zorder(20)

        sq = self.ax.add_collection(pc)
def get_mpas_patch_collection(nVertices, vertexDegree, cellsOnVertex, xCell,
                              yCell, zCell, latVertex, mpasArray, cmap, vmin,
                              vmax, minX, maxX, minY, maxY):

    patches = []
    colours = []

    minval = 1.0e30
    maxval = -1.0e30

    for iVertex in range(0, nVertices):

        if (latVertex[iVertex] > math.radians(20.0)):

            polygonVertices = []

            useVertex = False
            for iCellOnVertex in range(0, vertexDegree[iVertex]):

                iCell = cellsOnVertex[iVertex, iCellOnVertex]

                polygonVertices.append((xCell[iCell], yCell[iCell]))

                if (xCell[iCell] >= minX and xCell[iCell] <= maxX and \
                    yCell[iCell] >= minY and yCell[iCell] <= maxY):
                    useVertex = True

            if (useVertex):
                polygon = Polygon(polygonVertices)
                patches.append(polygon)

                colours.append(mpasArray[iVertex])

                minval = min(minval, mpasArray[iVertex])
                maxval = max(maxval, mpasArray[iVertex])

    patchCollection = PatchCollection(patches, cmap=cmap, rasterized=True)
    patchCollection.set_array(np.array(colours))
    patchCollection.set_linewidth(0)

    patchCollection.set_clim(vmin=vmin, vmax=vmax)

    return patchCollection, minval, maxval
Example #17
0
def _render_matplotlib(vertices, faces, face_color, borders, new_figure):
    """
    Render the data in matplotlib: This is segmented to allow for openGL renderer

    Input:
        vertices (np.ndarray)
            Array of vertices
        faces (nd.array)
            Array of Faces
        face_color (nd.array)
            RGBA array of color and alpha of all vertices
        new_figure (bool)
            Create new Figure or render in currrent axis? 
    """
    patches = []
    for i in range(faces.shape[0]):
        polygon = Polygon(vertices[faces[i],0:2], True)
        patches.append(polygon)
    p = PatchCollection(patches)
    p.set_facecolor(face_color)
    p.set_linewidth(0.0)

    # Get the current axis and plot it
    if new_figure:
        fig = plt.figure(figsize=(7,7))
    ax = plt.gca()
    ax.add_collection(p)
    xrang = [np.nanmin(vertices[:,0]),np.nanmax(vertices[:,0])]
    yrang = [np.nanmin(vertices[:,1]),np.nanmax(vertices[:,1])]

    ax.set_xlim(xrang[0],xrang[1])
    ax.set_ylim(yrang[0],yrang[1])
    ax.axis('equal')
    ax.axis('off')

    if borders is not None:
        ax.plot(borders[:,0],borders[:,1],color='k',
                marker='.', linestyle=None,
                markersize=2,linewidth=0)
    return ax
Example #18
0
def get_mpas_patch_collection(nCells, nEdgesOnCell, verticesOnCell, xVertex,
                              yVertex, zVertex, mpasArray, cmap):

    patches = []
    colours = []

    minval = 1.0e30
    maxval = -1.0e30

    for iCell in range(0, nCells):

        polygonVertices = []

        lUse = True

        for iVertexOnCell in range(0, nEdgesOnCell[iCell]):

            iVertex = verticesOnCell[iCell, iVertexOnCell] - 1

            polygonVertices.append((xVertex[iVertex], zVertex[iVertex]))

            if (yVertex[iVertex] < 0.0):
                lUse = False

        if (lUse):

            polygon = Polygon(polygonVertices)
            patches.append(polygon)

            colours.append(mpasArray[iCell])

            minval = min(minval, mpasArray[iCell])
            maxval = max(maxval, mpasArray[iCell])

    patchCollection = PatchCollection(patches, cmap=cmap, rasterized=False)
    patchCollection.set_array(np.array(colours))
    patchCollection.set_linewidth(0)
    patchCollection.set_clim(vmin=0.0, vmax=1.0)

    return patchCollection, minval, maxval
Example #19
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()
Example #20
0
class ArrayDisplay:
    """
    Display a top-town view of a telescope array
    """
    def __init__(self,
                 telx,
                 tely,
                 tel_type=None,
                 radius=20,
                 axes=None,
                 title="Array",
                 autoupdate=True):

        if tel_type is None:
            tel_type = np.ones(len(telx))
        patches = [
            Rectangle(xy=(x - radius / 2, y - radius / 2),
                      width=radius,
                      height=radius,
                      fill=False) for x, y in zip(telx, tely)
        ]

        self.autoupdate = autoupdate
        self.telescopes = PatchCollection(patches, match_original=True)
        self.telescopes.set_clim(1, 9)
        rgb = matplotlib.cm.Set1((tel_type - 1) / 9)
        self.telescopes.set_edgecolor(rgb)
        self.telescopes.set_linewidth(2.0)

        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.axes_hillas = axes if axes is not None else plt.gca()

    @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()

    def add_ellipse(self, centroid, length, width, angle, **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=True,
                          **kwargs)
        self.axes.add_patch(ellipse)
        return ellipse

    def add_polygon(self, centroid, radius, nsides=3, **kwargs):
        """
        plot a polygon on top of the camera

        Parameters
        ----------
        centroid: (float, float)
            position of centroid
        radius: float
            radius
        nsides: int
            Number of points on polygon
        kwargs:
            any MatPlotLib style arguments to pass to the RegularPolygon patch

        """
        polygon = RegularPolygon(xy=centroid,
                                 radius=radius,
                                 numVertices=nsides,
                                 **kwargs)
        self.axes.add_patch(polygon)
        return polygon

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

        Parameters
        ----------
        momparams: `reco.MomentParameters`
            structuring containing Hillas-style parameterization
        tel_position: list
            (x, y) positions of each telescope
        scale_fac: float
            scaling factor to apply to width and length when overlaying moments
        kwargs: key=value
            any style keywords to pass to matplotlib (e.g. color='red'
            or linewidth=6)
        """
        # strip off any units
        ellipse_list = list()
        size_list = list()
        i = 0
        for h in momparams:

            length = u.Quantity(momparams[h].length).value * scale_fac
            width = u.Quantity(momparams[h].width).value * scale_fac
            size_list.append(u.Quantity(momparams[h].size).value)
            tel_x = u.Quantity(tel_position[0][i]).value
            tel_y = u.Quantity(tel_position[1][i]).value
            i += 1

            ellipse = Ellipse(xy=(tel_x, tel_y),
                              width=length,
                              height=width,
                              angle=np.degrees(momparams[h].psi.rad))
            ellipse_list.append(ellipse)

        patches = PatchCollection(ellipse_list, **kwargs)
        patches.set_clim(0, 1000)  # Set ellipse colour based on image size
        patches.set_array(np.asarray(size_list))
        self.axes_hillas.add_collection(patches)

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

        Parameters
        ----------
        momparams: `reco.MomentParameters`
            structuring containing Hillas-style parameterization
        tel_position: list
            (x, y) positions of each telescope
        kwargs: key=value
            any style keywords to pass to matplotlib (e.g. color='red'
            or linewidth=6)
        """
        # strip off any units
        line_list = list()
        size_list = list()
        i = 0
        for h in momparams:
            tel_x = u.Quantity(tel_position[0][i]).value
            tel_y = u.Quantity(tel_position[1][i]).value
            psi = u.Quantity(momparams[h].psi).value
            x_sc = [tel_x - np.cos(psi) * 10000, tel_x + np.cos(psi) * 10000]
            y_sc = [tel_y - np.sin(psi) * 10000, tel_y + np.sin(psi) * 10000]

            i += 1
            self.axes_hillas.add_line(
                Line2D(x_sc, y_sc, linestyle='dashed', color='black'))
Example #21
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
Example #22
0
def plot_multifolder_old(folder_list, Zlist, pointing, ap):
    rw = 0.5
    rh = 0.1
    numfree = 1334 - 5 - 1

    minchi = np.inf
    maxchi = 0
    for f in folder_list:
        stepfile = glob("{:}/P{:}_*{:02n}_steps.dat".format(f, pointing, ap))[0]
        print stepfile
        chi = np.loadtxt(stepfile, usecols=(12,), unpack=True)
        chi = chi[chi == chi]
        upperlim = np.median(chi) + 1.3 * np.min(chi)
        if chi[-1] < minchi:
            minchi = chi[-1]
        if upperlim > maxchi:
            maxchi = upperlim

    fig = plt.figure()
    grid = ImageGrid(
        fig, 111, nrows_ncols=(1, 1), cbar_mode="each", cbar_location="top", cbar_pad="1%", axes_class=None
    )
    ax = grid[0]

    ax.set_xlabel("$Z/Z_{\odot}$")
    ax.set_ylabel("MLWA")
    goodage = []
    bigZ = np.zeros(len(folder_list))
    for z, f in enumerate(folder_list):

        stepfile = glob("{:}/P{:}_*{:02n}_steps.dat".format(f, pointing, ap))[0]
        print stepfile
        MLWA, chi = np.loadtxt(stepfile, usecols=(6, 12), unpack=True)
        idx = chi == chi
        chi = chi[idx]
        MLWA = MLWA[idx]
        idx = MLWA == MLWA
        chi = chi[idx]
        MLWA = MLWA[idx]

        #        good = np.where(chi < 80)
        #        chi = chi[good]
        #        MLWA = MLWA[good]
        chi -= minchi
        patches = []
        for i in range(MLWA.size):
            #            patches.append(Circle((z,MLWA[i]),radius=0.1,linewidth=0))
            width = rw * ((minchi + 5000) / (chi[i] + 5000))
            #            width = rw * (minchi/chi[i])
            patches.append(Rectangle((z - width / 2, MLWA[i] - rh / 2), width, rh))

        collection = PatchCollection(
            np.array(patches)[::-1],
            cmap=plt.get_cmap("gnuplot"),
            norm=matplotlib.colors.Normalize(vmin=minchi, vmax=maxchi),
        )
        collection.set_alpha(0.7)
        collection.set_linewidth(0.0)
        collection.set_array(chi[::-1])
        ax.add_collection(collection)

        #        ax.axhline(y=MLWA[-1],color='k',ls=':',alpha=0.6)
        ax.hlines(MLWA[-1], z - 0.3, z + 0.3, color="g", lw=2)
        prob = 1 - ss.chi2.cdf(chi[-1] * numfree, numfree)
        if prob >= 0.68:
            goodage.append(MLWA[-1])
            bigZ[z] = 1

        ax.text(z + 0.5, MLWA[-1], "{:4.2f}\n{:4.2f}".format(prob, chi[-1]), fontsize=10)

    collection.set_alpha(1.0)
    cbar = ax.cax.colorbar(collection)

    ci = [68.27, 50.0, 80.0, 40.0]
    dc = [4.72, 3.36, 5.99, 2.75]

    # for (c, d) in zip(ci, dc):
    #     ax.cax.axvline(x = np.log10(d), color='g')
    #     ax.cax.text(np.log10(d) - 0.03, 2, '{}'.format(c),
    #                 transform=ax.cax.transData,
    #                 fontsize=8)

    collection.set_alpha(0.1)
    cbar.set_label_text(r"$\Delta\chi^2_{\nu}$")

    ax.set_xlim(-1, len(Zlist) + 1)
    ax.set_ylim(0, 12)
    ax.set_xticks(np.arange(len(Zlist)))
    ax.set_xticklabels(Zlist)
    #    fig.show()

    return fig, np.mean(goodage), np.std(goodage), bigZ
Example #23
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()
Example #24
0
    def draw(self,
             ax,
             draw_polygons=True,
             colour='k',
             line_alpha=1.,
             fill_alpha=1.,
             linestyle='-',
             linewidth=1.,
             markers=None,
             values=None,
             precompv=None,
             vmin=None,
             vmax=None,
             title=None,
             cmap=None,
             cblabel=None,
             logscale=False,
             allowed_cbticklabels=(None, ),
             extend='neither',
             zorder=0):
        """
		Draw the diagram
		"""

        drawvalues = values is not None

        if drawvalues:
            patches = []
            colours = np.zeros(self.nc)

        for i, pol in self.polygons.items():

            # Colours and filled polygons
            if drawvalues:
                filled_pol = mp.Polygon(self.cellverts[i])
                patches.append(filled_pol)
                if values == 'areas':
                    colours[i] = pol.area
                if values == 'inv_areas':
                    colours[i] = 1. / self.free_areas[i]
                if values == 'free_areas':
                    colours[i] = self.free_areas[i]
                if values == 'precomputed':
                    if logscale:
                        colours[i] = np.abs(precompv[i])
                    else:
                        colours[i] = precompv[i]

                # Colour for the polygon contours
                if colour == 'same_as_facecolors':
                    pc_ = colours[i]
            else:
                pc_ = colour

            # Draw the polygon
            if draw_polygons:
                pol.draw(ax=ax,
                         colour=pc_,
                         alpha=line_alpha,
                         linestyle=linestyle,
                         linewidth=linewidth,
                         markers=markers,
                         zorder=zorder)

        # Line colours
        if drawvalues:
            if vmin is None:
                vmin = colours.min()
            if vmax is None:
                vmax = colours.max()
            if logscale:
                vmin = np.abs(vmin)
                vmax = np.abs(vmax)
                norm = LogNorm(vmin=vmin, vmax=vmax)
            else:
                norm = Normalize(vmin=vmin, vmax=vmax)
            m = plt.cm.ScalarMappable(norm=norm, cmap=cmap)
            line_colours = m.to_rgba(colours)
            print(line_colours)

        if drawvalues:

            collection = PatchCollection(patches, cmap=cmap, norm=norm)
            ax.add_collection(collection)
            collection.set_alpha(fill_alpha)
            collection.set_array(colours)
            if logscale:
                collection.set_clim(vmin=vmin, vmax=vmax)
            else:
                collection.set_clim(vmin=0., vmax=vmax)
            if colour == 'same_as_facecolors':
                collection.set_edgecolors(line_colours)
            else:
                collection.set_edgecolor(colour)
            collection.set_linewidth(linewidth)

        if values == 'precomputed':

            collection.set_clim(vmin=vmin, vmax=vmax)

            # Color bar
            if logscale:
                l_f = LogFormatter(10, labelOnlyBase=False)
                cb = plt.colorbar(collection,
                                  ax=ax,
                                  orientation='vertical',
                                  format=l_f,
                                  extend=extend)
                # Set minor ticks
                # We need to nomalize the tick locations so that they're in the range from 0-1...
                # minorticks = p.norm(np.arange(1, 10, 2))
                # Minimum and maximum exponents
                min_exp = int(np.log10(min(vmin, vmax)))
                max_exp = int(np.log10(max(vmin, vmax))) + 1
                # Ticks for the colorbar in case it's logscale
                minorticks = 10.**np.arange(min_exp, max_exp + 1, 1)
                minorticks_ = minorticks.tolist()
                for i in range(2, 10, 1):
                    minorticks_ = minorticks_ + (float(i) *
                                                 minorticks).tolist()
                minorticks_.sort()
                minorticks = np.array(minorticks_)
                minorticks = minorticks[np.where(minorticks >= vmin)]
                minorticks = minorticks[np.where(minorticks <= vmax)]
                print(minorticks)
                cb.set_ticks(minorticks)
                cb.set_ticklabels([
                    str(int(x)) if x in allowed_cbticklabels else ''
                    for x in minorticks
                ])
            else:
                cb = plt.colorbar(collection,
                                  ax=ax,
                                  orientation='vertical',
                                  extend=extend)
            cb.set_label(cblabel)
        if title is not None:
            ax.set_title(title)

        ax.set_xlabel(r'$\rm x$ ($\rm \mu m$)')
        ax.set_ylabel(r'$\rm y$ ($\rm \mu m$)')
Example #25
0
        color = 'y'
    elif zone == 'C':
        color = 'c'
    elif zone == 'M':
        color = 'darkmagenta'
    elif zone == 'O':
        color = 'ivory'
    elif zone == 'P':
        color = 'forestgreen'

    patches = [mplPolygon(np.array(shape), True)]
    pc = PatchCollection(patches)
    pc.set_alpha(.7)
    pc.set_facecolor(color)
    pc.set_zorder(2)
    pc.set_linewidth(.1)
    pc.set_edgecolor('k')
    ax.add_collection(pc)

#####################################################################
#				Add Roads shapefile to map 							#
#####################################################################
map.readshapefile('RoadCenterlines/RoadCenterlines_2',
                  'RoadCenterlines_2',
                  linewidth=.2)

#####################################################################
#						TRY CODE HERE 								#
#####################################################################

c = fiona.open('ZoningDistrict/ZoningDistrict_test_2.shp')
Example #26
0
    def plotter(self, mesh=True):
        """
        Plots solution and overlays mesh
        """
        #        approx=self.nodal_values()

        xy = np.array([self.x[:], self.y[:]]).T
        patches = []
        for coords in xy[self.con_array[:]]:
            quad = Polygon(coords, facecolor='none', fill=False)
            patches.append(quad)

        n = 50
        X, Y = np.meshgrid(np.linspace(min(self.x), max(self.x), n),
                           np.linspace(min(self.y), max(self.y), n))
        #        X=X.ravel(); Y=Y.ravel()
        #        Z=np.zeros(n**2)
        #        print(X,Y)
        #        for i in range(n**2):
        #            print(self.approx_function(X[i],Y[i]),i)
        #            Z[i]=self.approx_function(X[i],Y[i])
        #        f=scipy.interpolate.interp2d(self.x,self.y,self.approx)
        #        Z=f(np.linspace(min(self.x),max(self.x),n),np.linspace(min(self.y),max(self.y),n))
        #        X=X.reshape((n,n)); Y=Y.reshape((n,n)); Z=Z.reshape((n,n))
        Z = scipy.interpolate.griddata((self.x, self.y), self.approx, (X, Y))
        ticks = np.linspace(min(self.approx), max(self.approx), 5)
        #        return (X,Y,Z.astype('float'))
        fig, ax = plt.subplots()

        cs = ax.contourf(X,
                         Y,
                         Z,
                         cmap="coolwarm",
                         levels=np.linspace(min(self.approx), max(self.approx),
                                            30))
        cbar = fig.colorbar(cs, ax=ax, ticks=ticks)

        p = PatchCollection(patches, match_original=True)
        p.set_linewidth(0.1)

        if mesh == False:

            p.set_linewidth(0)

        plt.xticks(np.linspace(-400, 400, 5))
        plt.yticks(np.linspace(-400, 400, 5))
        ax.add_collection(p)
        ax.set_aspect('equal')
        ax.set_xlim([-400, 400])
        ax.set_ylim([-400, 400])
        props = dict(boxstyle='square', facecolor='white', alpha=1.)
        plt.gcf().subplots_adjust(bottom=0.15)
        plt.text(0.5,
                 0.9,
                 'Degrees of freedom= %s' % len(self.F),
                 ha='center',
                 va='center',
                 transform=ax.transAxes,
                 bbox=props,
                 fontsize=14)
        plt.xlabel('x [m]', fontsize=18)
        plt.ylabel('y [m]', fontsize=18)
        plt.tick_params(labelsize=18)
        cbar.ax.tick_params(labelsize=18)
        cbar.set_label('Pressure [MPa]', labelpad=10, size=18)

        return plt
Example #27
0
             polygon = Polygon(np.array([x, y]).transpose(),
                               True,
                               color='gray')
             patches_polygon.append(polygon)
     pcc = PatchCollection(patches_circle, match_original=False)
     pcp = PatchCollection(patches_polygon, match_original=False)
     if args.collision_status:
         pcc.set_color('#85878b')
         pcp.set_color('#85878b')
         pcc.set_alpha(0.3)
         pcp.set_alpha(0.3)
         pcc.set_linestyle('dashed')
         pcp.set_linestyle('dashed')
         pcc.set_edgecolor('#73cdc9')
         pcp.set_edgecolor('#73cdc9')
         pcc.set_linewidth(0.4)
         pcp.set_linewidth(0.4)
         pcc.set_joinstyle('round')
         pcp.set_joinstyle('round')
     else:
         pcc.set_color('gray')
         pcp.set_color('gray')
     ax.add_collection(pcc)
     ax.add_collection(pcp)
 if args.safety_certificate:
     xyrs = []
     for line in open(args.safety_certificate, 'r').readlines():
         l = line.strip()
         if not l:
             continue
         xyrs.append([float(x) for x in l.split(' ')])
Example #28
0
def plot_multiZ(prefix, minval=0, maxval=200, bluefree=702):

    fraclist = np.array([0.005, 0.02, 0.2, 0.4, 1, 2.5])
    rw = 0.5
    rh = 0.05

    minchi = np.inf
    for z in range(fraclist.size):

        stepfile = "{}_Z{:04}_steps.dat".format(prefix, int(fraclist[z] * 1000))
        blueChi = np.loadtxt(stepfile, usecols=(17,), unpack=True)
        blueChi *= bluefree
        if blueChi[-1] < minchi:
            minchi = blueChi[-1]

    fig = plt.figure()
    grid = ImageGrid(
        fig, 111, nrows_ncols=(1, 1), cbar_mode="each", cbar_location="top", cbar_pad="1%", axes_class=None
    )
    ax = grid[0]

    ax.set_xlabel("$Z/Z_{\odot}$")
    ax.set_ylabel("MLWA")
    for z in range(fraclist.size):

        stepfile = "{}_Z{:04}_steps.dat".format(prefix, int(fraclist[z] * 1000))
        MLWA, TAUV, Chi, blueChi = np.loadtxt(stepfile, usecols=(12, 13, 15, 17), unpack=True)
        blueChi *= bluefree

        #        good = np.where(blueChi < 80)
        #        blueChi = blueChi[good]
        #        MLWA = MLWA[good]
        blueChi -= minchi
        patches = []
        print np.log10(blueChi.min()), np.log10(blueChi.max())
        for i in range(MLWA.size):
            #            patches.append(Circle((z,MLWA[i]),radius=0.1,linewidth=0))
            width = rw * ((minchi + 5000) / (blueChi[i] + 5000))
            #            width = rw * (minchi/blueChi[i])
            patches.append(Rectangle((z - width / 2, MLWA[i] - rh / 2), width, rh))

        collection = PatchCollection(
            np.array(patches)[::-1],
            cmap=plt.get_cmap("gnuplot"),
            norm=matplotlib.colors.Normalize(vmin=minval, vmax=maxval),
        )
        collection.set_alpha(0.1)
        collection.set_linewidth(0.0)
        collection.set_array(np.log10(blueChi)[::-1])
        ax.add_collection(collection)

        #        ax.axhline(y=MLWA[-1],color='k',ls=':',alpha=0.6)
        ax.hlines(MLWA[-1], z - 0.5, z + 0.5, color="g", lw=2)
        ax.text(
            z + 0.5,
            MLWA[-1],
            "{:5.2f}%, {:4.1f}".format(100 - 100 * ss.chi2.cdf(blueChi[-1], bluefree + 5), blueChi[-1]),
        )

    collection.set_alpha(1.0)
    cbar = ax.cax.colorbar(collection)

    ci = [68.27, 50.0, 80.0, 40.0]
    dc = [4.72, 3.36, 5.99, 2.75]

    # for (c, d) in zip(ci, dc):
    #     ax.cax.axvline(x = np.log10(d), color='g')
    #     ax.cax.text(np.log10(d) - 0.03, 2, '{}'.format(c),
    #                 transform=ax.cax.transData,
    #                 fontsize=8)

    collection.set_alpha(0.1)
    cbar.set_label_text("Log( $\Delta\chi^2_{\mathrm{blue}}$ )")

    ax.set_xlim(-1, fraclist.size + 1)
    ax.set_ylim(0, 12)
    ax.set_xticks(np.arange(fraclist.size))
    ax.set_xticklabels(fraclist)
    fig.show()

    return fig
Example #29
0
#ax.set_xlim(-(seg_bar_height+1.25), (seg_bar_height+1.25))
#ax.set_ylim(-(seg_bar_height+1.25), (seg_bar_height+1.25))
chrom_set = set()
for i in path:
    chrom_set.add(segSeqD[i[0]][0])

sorted_chrom = sorted(chrom_set, key=lambda x: x.rsplit("chr")[-1])
sorted_chrom_colors = [chromosome_colors[x] for x in sorted_chrom]
legend_patches = []
for chrom, color in zip(sorted_chrom, sorted_chrom_colors):
    legend_patches.append(mpatches.Patch(color=color, label=chrom))

# plt.legend(handles=legend_patches,fontsize=8,loc=3,bbox_to_anchor=(-.3,.15))
plt.legend(
    handles=legend_patches, fontsize=10,
    bbox_to_anchor=(0,
                    0))  # bbox_to_anchor=(0,-1.5))#,bbox_to_anchor=(.09,-1.5))

p = PatchCollection(patches)
p.set_facecolor(f_color_v)
p.set_edgecolor(e_color_v)
p.set_linewidth(lw_v)
ax.add_collection(p)
ax.set_aspect(1.0)
plt.axis('off')
plt.savefig(fname + '.png', dpi=600)
plt.savefig(fname + '.pdf', format='pdf')

plt.close()
print("finished")
Example #30
0
#! /home/kshan/anaconda2/bin/python

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.path as mpath
import matplotlib.lines as mlines
import matplotlib.patches as mpatches
from matplotlib.collections import PatchCollection

fig, ax = plt.subplots()
patches = []
colors = ["red"]
collection = PatchCollection(patches, alpha=1)
collection.set_color(colors)
collection.set_edgecolor("black")
collection.set_linewidth(1)
ax.add_collection(collection)

plt.plot((13.96, 8.05175), (7.93333, 7.34158), color='r')
plt.plot((13.96, 19.754), (7.93333, 7.2273), color='r')
plt.plot((8.05175, 8.87409), (7.34158, 4.66392), color='g')
plt.plot((8.05175, 9.09689), (7.34158, 9.79644), color='g')
plt.plot((19.754, 18.3777), (7.2273, 5.10356), color='g')
plt.plot((19.754, 19.7798), (7.2273, 10.7015), color='g')
plt.plot((6.1265, 9.30722), (3.40278, 3.47205), color='m')
plt.plot((8.87409, 9.30722), (4.66392, 3.47205), color='m')
plt.plot((8.87409, 9.17591), (4.66392, 5.9871), color='m')
plt.plot((12.3072, 9.17591), (6.10582, 5.9871), color='m')
plt.plot((7.46506, 10.1029), (9.78961, 9.17742), color='m')
plt.plot((9.09689, 10.1029), (9.79644, 9.17742), color='m')
plt.plot((9.09689, 8.6289), (9.79644, 10.9534), color='m')
Example #31
0
class ArrayDisplay:
    """
    Display a top-town view of a telescope array.

    This can be used in two ways: by default, you get a display of all
    telescopes in the subarray, colored by telescope type, however you can
    also color the telescopes by a value (like trigger pattern, or some other
    scalar per-telescope parameter). To set the color value, simply set the
    ``value`` attribute, and the fill color will be updated with the value. You
    might want to set the border color to zero to avoid confusion between the
    telescope type color and the value color (
    ``array_disp.telescope.set_linewidth(0)``)

    To display a vector field over the telescope positions, e.g. for
    reconstruction, call `set_vector_uv()` to set cartesian vectors,
    or `set_vector_rho_phi()` to set polar coordinate vectors.
    These both take an array of length N_tels, or a single value.


    Parameters
    ----------
    subarray: ctapipe.instrument.SubarrayDescription
        the array layout to display
    axes: matplotlib.axes.Axes
        matplotlib axes to plot on, or None to use current one
    title: str
        title of array plot
    tel_scale: float
        scaling between telescope mirror radius in m to displayed size
    autoupdate: bool
        redraw when the input changes
    radius: Union[float, list, None]
        set telescope radius to value, list/array of values. If None, radius
        is taken from the telescope's mirror size.
    """
    def __init__(
            self,
            subarray,
            axes=None,
            autoupdate=True,
            tel_scale=2.0,
            alpha=0.7,
            title=None,
            radius=None,
            frame=GroundFrame(),
    ):

        self.frame = frame
        self.subarray = subarray
        self.axes = axes or plt.gca()

        # get the telescope positions. If a new frame is set, this will
        # transform to the new frame.
        self.tel_coords = subarray.tel_coords.transform_to(frame).cartesian
        self.unit = self.tel_coords.x.unit

        # set up colors per telescope type
        tel_types = [str(tel) for tel in subarray.tels.values()]
        if radius is None:
            # set radius to the mirror radius (so big tels appear big)
            radius = [
                np.sqrt(tel.optics.mirror_area.to("m2").value) * tel_scale
                for tel in subarray.tel.values()
            ]

            self.radii = radius
        else:
            self.radii = np.ones(len(tel_types)) * radius

        if title is None:
            title = subarray.name

        # get default matplotlib color cycle (depends on the current style)
        color_cycle = cycle(plt.rcParams["axes.prop_cycle"].by_key()["color"])

        # map a color to each telescope type:
        tel_type_to_color = {}
        for tel_type in list(set(tel_types)):
            tel_type_to_color[tel_type] = next(color_cycle)

        tel_color = [tel_type_to_color[ttype] for ttype in tel_types]

        patches = []
        for x, y, r, c in zip(
                list(self.tel_coords.x.to_value("m")),
                list(self.tel_coords.y.to_value("m")),
                list(radius),
                tel_color,
        ):
            patches.append(
                Circle(xy=(x, y), radius=r, fill=True, color=c, alpha=alpha))

        # build the legend:
        legend_elements = []
        for ttype in list(set(tel_types)):
            color = tel_type_to_color[ttype]
            legend_elements.append(
                Line2D(
                    [0],
                    [0],
                    marker="o",
                    color=color,
                    label=ttype,
                    markersize=10,
                    alpha=alpha,
                    linewidth=0,
                ))
        self.axes.legend(handles=legend_elements)

        self.add_radial_grid()

        # create the plot
        self.tel_colors = tel_color
        self.autoupdate = autoupdate
        self.telescopes = PatchCollection(patches, match_original=True)
        self.telescopes.set_linewidth(2.0)

        self.axes.add_collection(self.telescopes)
        self.axes.set_aspect(1.0)
        self.axes.set_title(title)
        xunit = self.tel_coords.x.unit.to_string("latex")
        yunit = self.tel_coords.y.unit.to_string("latex")
        xname, yname, _ = frame.get_representation_component_names().keys()
        self.axes.set_xlabel(f"{xname} [{xunit}] $\\rightarrow$")
        self.axes.set_ylabel(f"{yname} [{yunit}] $\\rightarrow$")
        self._labels = []
        self._quiver = None
        self.axes.autoscale_view()

    @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(np.ma.masked_invalid(values))
        self._update()

    def add_radial_grid(self, spacing=100 * u.m):
        """add some dotted rings for distance estimation. The number of rings
        is estimated automatically from the spacing and the array footprint.

        Parameters
        ----------
        spacing: Quantity
            spacing between rings

        """

        n_circles = np.round(
            (np.sqrt(self.subarray.footprint / np.pi) / spacing).to_value(""),
            0,
        )
        circle_radii = np.arange(1, n_circles + 2, 1) * spacing.to_value(
            self.unit)
        circle_patches = PatchCollection(
            [
                Circle(
                    xy=(0, 0),
                    radius=r,
                    fill=False,
                    fc="none",
                    linestyle="dotted",
                    color="gray",
                    alpha=0.1,
                    lw=1,
                ) for r in circle_radii
            ],
            color="#eeeeee",
            ls="dotted",
            fc="none",
            lw=3,
        )

        self.axes.add_collection(circle_patches)

    def set_vector_uv(self, uu, vv, c=None, **kwargs):
        """sets the vector field U,V and color for all telescopes

        Parameters
        ----------
        uu: array[num_tels]
            x-component of direction vector
        vv: array[num_tels]
            y-component of direction vector
        c: color or list of colors
            vector color for each telescope (or one for all)
        kwargs:
            extra args passed to plt.quiver(), ignored on subsequent updates
        """
        coords = self.tel_coords
        uu = u.Quantity(uu).to_value("m")
        vv = u.Quantity(vv).to_value("m")
        N = len(coords.x)

        # matplotlib since 3.2 does not allow scalars anymore
        # if quiver was already created with a certain number of arrows
        if np.isscalar(uu):
            uu = np.full(N, uu)
        if np.isscalar(vv):
            vv = np.full(N, vv)

        # passing in None for C does not work, we need to provide
        # a variadic number of arguments
        args = [coords.x.to_value("m"), coords.y.to_value("m"), uu, vv]

        if c is None:
            # use colors by telescope type if the user did not provide any
            kwargs["color"] = kwargs.get("color", self.tel_colors)
        else:
            # same as above, enable use of scalar to set all values at once
            if np.isscalar(c):
                c = np.full(N, c)
            args.append(c)

        if self._quiver is None:
            self._quiver = self.axes.quiver(*args,
                                            scale_units="xy",
                                            angles="xy",
                                            scale=1,
                                            **kwargs)
        else:
            self._quiver.set_UVC(uu, vv, c)

    def set_vector_rho_phi(self, rho, phi, c=None, **kwargs):
        """sets the vector field using R, Phi for each telescope

        Parameters
        ----------
        rho: float or array[float]
            vector magnitude for each telescope
        phi: array[Angle]
            vector angle for each telescope
        c: color or list of colors
            vector color for each telescope (or one for all)
        """
        phi = Angle(phi).rad
        uu, vv = polar_to_cart(rho, phi)
        self.set_vector_uv(uu, vv, c=c, **kwargs)

    def set_vector_hillas(self, hillas_dict, core_dict, length, time_gradient,
                          angle_offset):
        """
        Function to set the vector angle and length from a set of Hillas parameters.

        In order to proper use the arrow on the ground, also a dictionary with the time
        gradients for the different telescopes is needed. If the gradient is 0 the arrow
        is not plotted on the ground, whereas if the value of the gradient is negative,
        the arrow is rotated by 180 degrees (Angle(angle_offset) not added).

        This plotting behaviour has been tested with the timing_parameters function
        in ctapipe/image.

        Parameters
        ----------
        hillas_dict: Dict[int, HillasParametersContainer]
            mapping of tel_id to Hillas parameters
        core_dict : Dict[int, CoreParameters]
            mapping of tel_id to CoreParametersContainer
        length: Float
            length of the arrow (in meters)
        time_gradient: Dict[int, value of time gradient (no units)]
            dictionary for value of the time gradient for each telescope
        angle_offset: Float
            This should be the ``event.pointing.array_azimuth`` parameter

        """

        # rot_angle_ellipse is psi parameter in HillasParametersContainer
        rho = np.zeros(self.subarray.num_tels) * u.m
        rot_angle_ellipse = np.zeros(self.subarray.num_tels) * u.deg

        for tel_id, params in hillas_dict.items():

            idx = self.subarray.tel_indices[tel_id]
            rho[idx] = u.Quantity(length, u.m)

            psi = core_dict[tel_id]

            if time_gradient[tel_id] > 0.01:
                angle_offset = Angle(angle_offset)
                rot_angle_ellipse[idx] = psi + angle_offset + 180 * u.deg
            elif time_gradient[tel_id] < -0.01:
                rot_angle_ellipse[idx] = psi + angle_offset
            else:
                rho[idx] = 0 * u.m

        self.set_vector_rho_phi(rho=rho, phi=rot_angle_ellipse)

    def set_line_hillas(self, hillas_dict, core_dict, range, **kwargs):
        """
        Plot the telescope-wise direction of the shower as a segment.

        Each segment will be centered with a point on the telescope position
        and will be 2*range long.

        Parameters
        ----------
        hillas_dict: Dict[int, HillasParametersContainer]
            mapping of tel_id to Hillas parameters
        core_dict : Dict[int, CoreParameters]
            mapping of tel_id to CoreParametersContainer
        range: float
            half of the length of the segments to be plotted (in meters)
        """

        coords = self.tel_coords
        c = self.tel_colors

        r = np.array([-range, range])

        for tel_id, params in hillas_dict.items():
            idx = self.subarray.tel_indices[tel_id]
            x_0 = coords[idx].x.to_value(u.m)
            y_0 = coords[idx].y.to_value(u.m)

            psi = core_dict[tel_id]

            x = x_0 + np.cos(psi).value * r
            y = y_0 + np.sin(psi).value * r
            self.axes.plot(x, y, color=c[idx], **kwargs)
            self.axes.scatter(x_0, y_0, color=c[idx])

    def add_labels(self):
        px = self.tel_coords.x.to_value("m")
        py = self.tel_coords.y.to_value("m")
        for tel, x, y, r in zip(self.subarray.tels, px, py, self.radii):
            name = str(tel)
            lab = self.axes.text(
                x,
                y - r * 1.8,
                name,
                fontsize=8,
                clip_on=True,
                horizontalalignment="center",
                verticalalignment="top",
            )
            self._labels.append(lab)

    def remove_labels(self):
        for lab in self._labels:
            lab.remove()
        self._labels = []

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

    def background_contour(self, x, y, background, **kwargs):
        """
        Draw image contours in background of the display, useful when likelihood fitting

        Parameters
        ----------
        x: ndarray
            array of image X coordinates
        y: ndarray
            array of image Y coordinates
        background: ndarray
            Array of image to use in background
        kwargs: key=value
            any style keywords to pass to matplotlib
        """

        # use zorder to ensure the contours appear under the telescopes.
        self.axes.contour(x, y, background, zorder=0, **kwargs)
Example #32
0
# for i in range(1,24):
#     chrom_set.add("chr" + str(i))

sorted_chrom = sorted(chrom_set,key=lambda x:int(x.rsplit("chr")[-1]))
sorted_chrom_colors = [chromosome_colors[x] for x in sorted_chrom]
legend_patches = []
for chrom,color in zip(sorted_chrom,sorted_chrom_colors):
    legend_patches.append(mpatches.Patch(color=color,label=chrom))

plt.legend(handles=legend_patches,fontsize=8,loc=3,bbox_to_anchor=(-.3,.15))

p = PatchCollection(patches)
p.set_facecolor(f_color_v)
p.set_edgecolor(e_color_v)
p.set_linewidth(lw_v)
ax.add_collection(p)
ax.set_aspect(1.0)
plt.axis('off')
plt.savefig(fname + '.png',dpi=600)
plt.savefig(fname + '.pdf',format='pdf')

plt.close()
print "done plotting bionano"

#handles basic (non-bionano case)
if args.feature_labels:
    #make a separate figure
    plt.clf()
    fig, ax = plt.subplots()
    patches = []
Example #33
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
Example #34
0
class ArrayDisplay:
    """
    Display a top-town view of a telescope array.

    This can be used in two ways: by default, you get a display of all
    telescopes in the subarray, colored by telescope type, however you can
    also color the telescopes by a value (like trigger pattern, or some other
    scalar per-telescope parameter). To set the color value, simply set the
    `value` attribute, and the fill color will be updated with the value. You
    might want to set the border color to zero to avoid confusion between the
    telescope type color and the value color (
    `array_disp.telescope.set_linewidth(0)`)

    To display a vector field over the telescope positions, e.g. for
    reconstruction, call `set_uv()` to set cartesian vectors, or `set_r_phi()`
    to set polar coordinate vectors.  These both take an array of length
    N_tels, or a single value.


    Parameters
    ----------
    subarray: ctapipe.instrument.SubarrayDescription
        the array layout to display
    axes: matplotlib.axes.Axes
        matplotlib axes to plot on, or None to use current one
    title: str
        title of array plot
    tel_scale: float
        scaling between telescope mirror radius in m to displayed size
    autoupdate: bool
        redraw when the input changes
    radius: Union[float, list, None]
        set telescope radius to value, list/array of values. If None, radius
        is taken from the telescope's mirror size.
    """

    def __init__(self, subarray, axes=None, autoupdate=True,
                 tel_scale=2.0, alpha=0.7, title=None,
                 radius=None, frame=GroundFrame()):

        self.frame = frame
        self.subarray = subarray

        # get the telescope positions. If a new frame is set, this will
        # transform to the new frame.
        self.tel_coords = subarray.tel_coords.transform_to(frame)

        # set up colors per telescope type
        tel_types = [str(tel) for tel in subarray.tels.values()]
        if radius is None:
            # set radius to the mirror radius (so big tels appear big)
            radius = [np.sqrt(tel.optics.mirror_area.to("m2").value) * tel_scale
                      for tel in subarray.tel.values()]

        if title is None:
            title = subarray.name

        # get default matplotlib color cycle (depends on the current style)
        color_cycle = cycle(plt.rcParams['axes.prop_cycle'].by_key()['color'])

        # map a color to each telescope type:
        tel_type_to_color = {}
        for tel_type in list(set(tel_types)):
            tel_type_to_color[tel_type] = next(color_cycle)

        tel_color = [tel_type_to_color[ttype] for ttype in tel_types]

        patches = []
        for x, y, r, c in zip(list(self.tel_coords.x.value),
                              list(self.tel_coords.y.value),
                              list(radius),
                              tel_color):
            patches.append(
                Circle(
                    xy=(x, y),
                    radius=r,
                    fill=True,
                    color=c,
                    alpha=alpha,
                )
            )

        # build the legend:
        legend_elements = []
        for ttype in list(set(tel_types)):
            color = tel_type_to_color[ttype]
            legend_elements.append(
                Line2D([0], [0], marker='o', color=color,
                       label=ttype, markersize=10, alpha=alpha,
                       linewidth=0)
            )
        plt.legend(handles=legend_elements)

        self.tel_colors = tel_color
        self.autoupdate = autoupdate
        self.telescopes = PatchCollection(patches, match_original=True)
        self.telescopes.set_linewidth(2.0)

        self.axes = axes or plt.gca()
        self.axes.add_collection(self.telescopes)
        self.axes.set_aspect(1.0)
        self.axes.set_title(title)
        self._labels = []
        self._quiver = None
        self.axes.autoscale_view()

    @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 set_vector_uv(self, u, v, c=None, **kwargs):
        """ sets the vector field U,V and color for all telescopes

        Parameters
        ----------
        u: array[num_tels]
            x-component of direction vector
        v: array[num_tels]
            y-component of direction vector
        c: color or list of colors
            vector color for each telescope (or one for all)
        kwargs:
            extra args passed to plt.quiver(), ignored on subsequent updates
        """
        if c is None:
            c = self.tel_colors

        if self._quiver is None:
            coords = self.tel_coords
            self._quiver = self.axes.quiver(
                coords.x, coords.y,
                u, v,
                color=c,
                scale_units='xy',
                angles='xy',
                scale=1,
                **kwargs
            )
        else:
            self._quiver.set_UVC(u, v)

    def set_vector_rho_phi(self, rho, phi, c=None, **kwargs):
        """sets the vector field using R, Phi for each telescope

        Parameters
        ----------
        rho: float or array[float]
            vector magnitude for each telescope
        phi: array[Angle]
            vector angle for each telescope
        c: color or list of colors
            vector color for each telescope (or one for all)
        """
        phi = Angle(phi).rad
        u, v = polar_to_cart(rho, phi)
        self.set_vector_uv(u, v, c=c, **kwargs)

    def set_vector_hillas(self, hillas_dict, length, time_gradient, angle_offset):
        """
        Function to set the vector angle and length from a set of Hillas parameters.

        In order to proper use the arrow on the ground, also a dictionary with the time
        gradients for the different telescopes is needed. If the gradient is 0 the arrow
        is not plotted on the ground, whereas if the value of the gradient is negative,
        the arrow is rotated by 180 degrees (Angle(angle_offset) not added).

        This plotting behaviour has been tested with the timing_parameters function
        in ctapipe/image.

        Parameters
        ----------
        hillas_dict: Dict[int, HillasParametersContainer]
            mapping of tel_id to Hillas parameters
        length: Float
            length of the arrow (in meters)
        time_gradient: Dict[int, value of time gradient (no units)]
            dictionary for value of the time gradient for each telescope
        angle_offset: Float
            This should be the event.mcheader.run_array_direction[0] parameter

        """

        # rot_angle_ellipse is psi parameter in HillasParametersContainer
        rho = np.zeros(self.subarray.num_tels) * u.m
        rot_angle_ellipse = np.zeros(self.subarray.num_tels) * u.deg

        for tel_id, params in hillas_dict.items():
            idx = self.subarray.tel_indices[tel_id]
            rho[idx] = length * u.m

            if time_gradient[tel_id] > 0.01:
                params.psi = Angle(params.psi)
                angle_offset = Angle(angle_offset)
                rot_angle_ellipse[idx] = params.psi + angle_offset + 180 * u.deg
            elif time_gradient[tel_id] < -0.01:
                rot_angle_ellipse[idx] = params.psi + angle_offset
            else:
                rho[idx] = 0 * u.m

        self.set_vector_rho_phi(rho=rho, phi=rot_angle_ellipse)

    def set_line_hillas(self, hillas_dict, range, **kwargs):
        """
        Function to plot a segment of length 2*range for each telescope from a set of Hillas parameters.
        The segment is centered on the telescope position.
        A point is added at each telescope position for better visualization.

        Parameters
        ----------
        hillas_dict: Dict[int, HillasParametersContainer]
            mapping of tel_id to Hillas parameters
        range: float
            half of the length of the segments to be plotted (in meters)
        """

        coords = self.tel_coords
        c = self.tel_colors

        for tel_id, params in hillas_dict.items():
            idx = self.subarray.tel_indices[tel_id]
            x_0 = coords[idx].x.value
            y_0 = coords[idx].y.value
            m = np.tan(Angle(params.psi))
            x = x_0 + np.linspace(-range, range, 50)
            y = y_0 + m * (x - x_0)
            distance = np.sqrt((x - x_0) ** 2 + (y - y_0) ** 2)
            mask = np.ma.masked_where(distance < range, distance).mask
            self.axes.plot(x[mask], y[mask], color=c[idx], **kwargs)
            self.axes.scatter(x_0, y_0, color=c[idx])

    def add_labels(self):
        px = self.tel_coords.x.value
        py = self.tel_coords.y.value
        for tel, x, y in zip(self.subarray.tels, px, py):
            name = str(tel)
            lab = self.axes.text(x, y, name, fontsize=8, clip_on=True)
            self._labels.append(lab)

    def remove_labels(self):
        for lab in self._labels:
            lab.remove()
        self._labels = []

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

    def background_contour(self, x, y, background, **kwargs):
        """
        Draw image contours in background of the display, useful when likelihood fitting

        Parameters
        ----------
        x: ndarray
            array of image X coordinates
        y: ndarray
            array of image Y coordinates
        background: ndarray
            Array of image to use in background
        kwargs: key=value
            any style keywords to pass to matplotlib
        """

        # use zorder to ensure the contours appear under the telescopes.
        self.axes.contour(x, y, background, zorder=0, **kwargs)
Example #35
0
def s_mu_tpcf_patches(tpcf, s_bins, mu_bins, cmap=cm.cool, vmin=None, vmax=None):
    """
    Return a collection of patches that can be used to plot the tpcf in s and mu bins.
    
    Parameters
    ----------
    tcpf : np.array
        numpy array with dimension len(s_bins) by len(mu_bins).
        This is the output of tpcf_s_mu()
    
    s_bins : np.array
        numpy array of shape (num_s_bin_edges, ) storing the :math:`s`
        boundaries defining the bins in which pairs are counted.
    
    mu_bins : np.array
        numpy array of shape (num_mu_bin_edges, ) storing the
        :math:`\cos(\theta_{\rm LOS})` boundaries defining the bins in
        which pairs are counted. All values must be between [0,1].
    
    cmap : matplotlib.colors.LinearSegmentedColormap object
        color map to use for coloring the patches
    
    vmin : float
        minimum value of tpcf used to normalize luminance data. Default is min(tpcf).
    
    vmax : float
        maximum value of tpcf used to normalize luminance data. Default is max(tpcf).
    
    Returns
    -------
    p : matplotlib.collections.PatchCollection object
        collection of patches
    
    Example
    -------
    For demonstration purposes we create a randomly distributed set of points within a
    periodic cube of length 250 Mpc/h.
    
    >>> Npts = 100
    >>> Lbox = 250.
    >>> x = np.random.uniform(0, Lbox, Npts)
    >>> y = np.random.uniform(0, Lbox, Npts)
    >>> z = np.random.uniform(0, Lbox, Npts)
    
    We transform our *x, y, z* points into the array shape used by the pair-counter by
    taking the transpose of the result of `numpy.vstack`. This boilerplate transformation
    is used throughout the `~halotools.mock_observables` sub-package:
    
    >>> sample1 = np.vstack((x,y,z)).T
    
    First, we calculate the correlation function using
    `~halotools.mock_observables.s_mu_tpcf`.
    
    >>> from halotools.mock_observables import s_mu_tpcf
    >>> s_bins  = np.linspace(0.01, 25, 10)
    >>> mu_bins = np.linspace(0, 1, 15)
    >>> xi_s_mu = s_mu_tpcf(sample1, s_bins, mu_bins, period=Lbox)
    
    Get a collection of patches taht represent the tpcf in s and mu bins:
    
    >>> p = s_mu_tpcf_patches(xi_s_mu, s_bins, mu_bins)
    
    Now, you can plot the tpcf:
    
    >>> fig, ax = plt.subplots()
    >>> ax.add_collection(p)
    >>> ax.set_xlim([0,25])
    >>> ax.set_ylim([0,25])
    >>> plt.show()
    """
    
    #normalize tpcf
    if vmin is None:
        min_tpcf = 1.0*np.min(tpcf)
    else:
        min_tpcf = vmin
        
    if vmax is None:
        max_tpcf = 1.0*np.max(tpcf)
    else:
        max_tpcf = vmax
    
    #set values over and under the vmin and vmax values
    mask = (tpcf>max_tpcf)
    tpcf[mask] = max_tpcf
    mask = (tpcf<min_tpcf)
    tpcf[mask] = min_tpcf
    
    #create lists to store wedges and color
    wedges = []
    colors=[]
    
    #set center of wedges to be the origin
    center = (0.0,0.0)
    
    #convert to degrees
    theta_bins = np.degrees(np.arccos(mu_bins))
    
    #change convention to start theta=0.0 on the positive x-axis
    #instead of the positive y-axis as is the theta_LOS convention
    theta_bins = 90.0 - theta_bins
    
    #loop over s bins
    for i, (s_low, s_high) in enumerate(zip(s_bins[:-1], s_bins[1:])):
        
        #loop over mu_bins
        for j, (theta_high, theta_low) in enumerate(zip(theta_bins[:-1], theta_bins[1:])): 
            
            #set radial extent
            r = s_high
            dr = s_high-s_low
            #set angular extent
            theta1 = theta_high
            theta2 = theta_low
            #set color
            c = 1.0*(tpcf[i,j]-min_tpcf)/max_tpcf
            
            #store wedges
            colors.append(c)
            wedges.append(Wedge(center, r, theta1, theta2, width=dr))
    
    #create a collection of patches
    p = PatchCollection(wedges, cmap=cmap)
    colors = np.array(colors)
    p.set_array(colors)
    p.set_linewidth(0.0)
    
    return p
Example #36
0
class ArrayDisplay:

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

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

        if tel_type is None:
            tel_type = np.ones(len(telx))
        patches = [Rectangle(xy=(x-radius/2, y-radius/2), width=radius, height=radius, fill=False)
                   for x, y in zip(telx, tely)]

        self.autoupdate = autoupdate
        self.telescopes = PatchCollection(patches, match_original=True)
        self.telescopes.set_clim(1, 9)
        rgb = matplotlib.cm.Set1((tel_type-1)/9)
        self.telescopes.set_edgecolor(rgb)
        self.telescopes.set_linewidth(2.0)

        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.axes_hillas = axes if axes is not None else plt.gca()


    @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()

    def add_ellipse(self, centroid, length, width, angle, **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=True,  **kwargs)
        self.axes.add_patch(ellipse)
        return ellipse

    def add_polygon(self, centroid, radius, nsides=3, **kwargs):
        """
        plot a polygon on top of the camera

        Parameters
        ----------
        centroid: (float, float)
            position of centroid
        radius: float
            radius
        nsides: int
            Number of points on polygon
        kwargs:
            any MatPlotLib style arguments to pass to the RegularPolygon patch

        """
        polygon = RegularPolygon(xy=centroid, radius=radius, numVertices=nsides, **kwargs)
        self.axes.add_patch(polygon)
        return polygon

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

        Parameters
        ----------
        momparams: `reco.MomentParameters`
            structuring containing Hillas-style parameterization
        tel_position: list
            (x, y) positions of each telescope
        scale_fac: float
            scaling factor to apply to width and length when overlaying moments
        kwargs: key=value
            any style keywords to pass to matplotlib (e.g. color='red'
            or linewidth=6)
        """
        # strip off any units
        ellipse_list = list()
        size_list = list()
        i = 0
        for h in momparams:

            length = u.Quantity(momparams[h].length).value * scale_fac
            width = u.Quantity(momparams[h].width).value * scale_fac
            size_list.append(u.Quantity(momparams[h].size).value)
            tel_x = u.Quantity(tel_position[0][i]).value
            tel_y = u.Quantity(tel_position[1][i]).value
            i += 1

            ellipse = Ellipse(xy=(tel_x,tel_y), width=length, height=width,
                              angle=np.degrees(momparams[h].psi.rad))
            ellipse_list.append(ellipse)

        patches = PatchCollection(ellipse_list, **kwargs)
        patches.set_clim(0, 1000) # Set ellipse colour based on image size
        patches.set_array(np.asarray(size_list))
        self.axes_hillas.add_collection(patches)

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

        Parameters
        ----------
        momparams: `reco.MomentParameters`
            structuring containing Hillas-style parameterization
        tel_position: list
            (x, y) positions of each telescope
        kwargs: key=value
            any style keywords to pass to matplotlib (e.g. color='red'
            or linewidth=6)
        """
        # strip off any units
        i = 0
        for h in momparams:
            tel_x = u.Quantity(tel_position[0][i]).value
            tel_y = u.Quantity(tel_position[1][i]).value
            psi = u.Quantity(momparams[h].psi).value
            x_sc = [tel_x - np.cos(psi) * 10000, tel_x + np.cos(psi) * 10000]
            y_sc = [tel_y - np.sin(psi) * 10000, tel_y + np.sin(psi) * 10000]

            i += 1
            self.axes_hillas.add_line(Line2D(x_sc, y_sc, linestyle='dashed', color='black'))
import sys
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.patches import Polygon
from matplotlib.collections import PatchCollection

if __name__ == '__main__':
    data = np.genfromtxt("polygon.txt", delimiter=',')
    triangle_indices = np.genfromtxt("triangle_indices.txt", delimiter=',')
    triangle_indices = triangle_indices.astype(int)
    fig, ax = plt.subplots()
    patches = []
    # Plot polygon
    convex_polygon = Polygon(data, closed=True)
    patches.append(convex_polygon)

    # Plot triangle vertices
    for i in range(np.size(triangle_indices, 0)):
        triangle = Polygon(data[triangle_indices[i, :]], closed=True)
        patches.append(triangle)
    polygons = PatchCollection(patches, alpha=0.4)
    polygons.set_facecolor('red')
    polygons.set_edgecolor('green')
    polygons.set_linewidth(2)
    ax.add_collection(polygons)
    ax.autoscale_view()
    plt.show()
Example #38
0
class ArrayDisplay:
    """
    Display a top-town view of a telescope array.

    This can be used in two ways: by default, you get a display of all
    telescopes in the subarray, colored by telescope type, however you can
    also color the telescopes by a value (like trigger pattern, or some other
    scalar per-telescope parameter). To set the color value, simply set the
    `value` attribute, and the fill color will be updated with the value. You
    might want to set the border color to zero to avoid confusion between the
    telescope type color and the value color (
    `array_disp.telescope.set_linewidth(0)`)

    To display a vector field over the telescope positions, e.g. for
    reconstruction, call `set_uv()` to set cartesian vectors, or `set_r_phi()`
    to set polar coordinate vectors.  These both take an array of length
    N_tels, or a single value.


    Parameters
    ----------
    subarray: ctapipe.instrument.SubarrayDescription
        the array layout to display
    axes: matplotlib.axes.Axes
        matplotlib axes to plot on, or None to use current one
    title: str
        title of array plot
    tel_scale: float
        scaling between telescope mirror radius in m to displayed size
    autoupdate: bool
        redraw when the input changes
    radius: Union[float, list, None]
        set telescope radius to value, list/array of values. If None, radius
        is taken from the telescope's mirror size.
    """
    def __init__(self,
                 subarray,
                 axes=None,
                 autoupdate=True,
                 tel_scale=2.0,
                 alpha=0.7,
                 title=None,
                 radius=None,
                 frame=GroundFrame()):

        self.frame = frame
        self.subarray = subarray

        # get the telescope positions. If a new frame is set, this will
        # transform to the new frame.
        self.tel_coords = subarray.tel_coords.transform_to(frame)

        # set up colors per telescope type
        tel_types = [str(tel) for tel in subarray.tels.values()]
        if radius is None:
            # set radius to the mirror radius (so big tels appear big)
            radius = [
                np.sqrt(tel.optics.mirror_area.to("m2").value) * tel_scale
                for tel in subarray.tel.values()
            ]

        if title is None:
            title = subarray.name

        # get default matplotlib color cycle (depends on the current style)
        color_cycle = cycle(plt.rcParams['axes.prop_cycle'].by_key()['color'])

        # map a color to each telescope type:
        tel_type_to_color = {}
        for tel_type in list(set(tel_types)):
            tel_type_to_color[tel_type] = next(color_cycle)

        tel_color = [tel_type_to_color[ttype] for ttype in tel_types]

        patches = []
        for x, y, r, c in zip(list(self.tel_coords.x.value),
                              list(self.tel_coords.y.value), list(radius),
                              tel_color):
            patches.append(
                Circle(
                    xy=(x, y),
                    radius=r,
                    fill=True,
                    color=c,
                    alpha=alpha,
                ))

        # build the legend:
        legend_elements = []
        for ttype in list(set(tel_types)):
            color = tel_type_to_color[ttype]
            legend_elements.append(
                Line2D([0], [0],
                       marker='o',
                       color=color,
                       label=ttype,
                       markersize=10,
                       alpha=alpha,
                       linewidth=0))
        plt.legend(handles=legend_elements)

        self.tel_colors = tel_color
        self.autoupdate = autoupdate
        self.telescopes = PatchCollection(patches, match_original=True)
        self.telescopes.set_linewidth(2.0)

        self.axes = axes or plt.gca()
        self.axes.add_collection(self.telescopes)
        self.axes.set_aspect(1.0)
        self.axes.set_title(title)
        self._labels = []
        self._quiver = None
        self.axes.autoscale_view()

    @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 set_vector_uv(self, u, v, c=None, **kwargs):
        """ sets the vector field U,V and color for all telescopes

        Parameters
        ----------
        u: array[num_tels]
            x-component of direction vector
        v: array[num_tels]
            y-component of direction vector
        kwargs:
            extra args passed to plt.quiver(), ignored on subsequent updates
        """
        if c is None:
            c = self.tel_colors

        if self._quiver is None:
            coords = self.tel_coords
            self._quiver = self.axes.quiver(coords.x,
                                            coords.y,
                                            u,
                                            v,
                                            color=c,
                                            **kwargs)
        else:
            self._quiver.set_UVC(u, v)

    def set_vector_rho_phi(self, rho, phi, c=None, **kwargs):
        """sets the vector field using R, Phi for each telescope

        Parameters
        ----------
        rho: float or array[float]
            vector magnitude for each telescope
        phi: array[Angle]
            vector angle for each telescope
        c: color or list of colors
            vector color for each telescope (or one for all)
        """
        phi = Angle(phi).rad
        u, v = polar_to_cart(rho, phi)
        self.set_vector_uv(u, v, c=c, **kwargs)

    def set_vector_hillas(self, hillas_dict, angle_offset=180 * u.deg):
        """
        helper function to set the vector angle and length from a set of
        Hillas parameters.

        Parameters
        ----------
        hillas_dict: Dict[int, HillasParametersContainer]
            mapping of tel_id to Hillas parameters
        """

        rho = np.zeros(self.subarray.num_tels) * u.m
        phi = np.zeros(self.subarray.num_tels) * u.deg

        for tel_id, params in hillas_dict.items():
            idx = self.subarray.tel_indices[tel_id]
            rho[idx] = 1.0 * u.m  # params.length
            phi[idx] = Angle(params.phi) + Angle(angle_offset)

        self.set_vector_rho_phi(rho=rho, phi=phi)

    def add_labels(self):
        px = self.tel_coords.x.value
        py = self.tel_coords.y.value
        for tel, x, y in zip(self.subarray.tels, px, py):
            name = str(tel)
            lab = self.axes.text(x, y, name, fontsize=8)
            self._labels.append(lab)

    def remove_labels(self):
        for lab in self._labels:
            lab.remove()
        self._labels = []

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

    def background_contour(self, x, y, background, **kwargs):
        """
        Draw image contours in background of the display, useful when likelihood fitting

        Parameters
        ----------
        x: ndarray
            array of image X coordinates
        y: ndarray
            array of image Y coordinates
        background: ndarray
            Array of image to use in background
        kwargs: key=value
            any style keywords to pass to matplotlib
        """

        # use zorder to ensure the contours appear under the telescopes.
        self.axes.contour(x, y, background, zorder=0, **kwargs)
Example #39
0
class ArrayDisplay:
    """
    Display a top-town view of a telescope array.

    This can be used in two ways: by default, you get a display of all
    telescopes in the subarray, colored by telescope type, however you can
    also color the telescopes by a value (like trigger pattern, or some other
    scalar per-telescope parameter). To set the color value, simply set the
    `value` attribute, and the fill color will be updated with the value. You
    might want to set the border color to zero to avoid confusion between the
    telescope type color and the value color (
    `array_disp.telescope.set_linewidth(0)`)

    To display a vector field over the telescope positions, e.g. for
    reconstruction, call `set_uv()` to set cartesian vectors, or `set_r_phi()`
    to set polar coordinate vectors.  These both take an array of length
    N_tels, or a single value.


    Parameters
    ----------
    subarray: ctapipe.instrument.SubarrayDescription
        the array layout to display
    axes: matplotlib.axes.Axes
        matplotlib axes to plot on, or None to use current one
    title: str
        title of array plot
    tel_scale: float
        scaling between telescope mirror radius in m to displayed size
    autoupdate: bool
        redraw when the input changes
    radius: Union[float, list, None]
        set telescope radius to value, list/array of values. If None, radius
        is taken from the telescope's mirror size.
    """
    def __init__(self,
                 subarray,
                 axes=None,
                 autoupdate=True,
                 tel_scale=2.0,
                 alpha=0.7,
                 title=None,
                 radius=None,
                 frame=GroundFrame()):

        self.frame = frame
        self.subarray = subarray

        # get the telescope positions. If a new frame is set, this will
        # transform to the new frame.
        self.tel_coords = subarray.tel_coords.transform_to(frame)

        # set up colors per telescope type
        tel_types = [str(tel) for tel in subarray.tels.values()]
        if radius is None:
            # set radius to the mirror radius (so big tels appear big)
            radius = [
                np.sqrt(tel.optics.mirror_area.to("m2").value) * tel_scale
                for tel in subarray.tel.values()
            ]

        if title is None:
            title = subarray.name

        # get default matplotlib color cycle (depends on the current style)
        color_cycle = cycle(plt.rcParams['axes.prop_cycle'].by_key()['color'])

        # map a color to each telescope type:
        tel_type_to_color = {}
        for tel_type in list(set(tel_types)):
            tel_type_to_color[tel_type] = next(color_cycle)

        tel_color = [tel_type_to_color[ttype] for ttype in tel_types]

        patches = []
        for x, y, r, c in zip(list(self.tel_coords.x.value),
                              list(self.tel_coords.y.value), list(radius),
                              tel_color):
            patches.append(
                Circle(
                    xy=(x, y),
                    radius=r,
                    fill=True,
                    color=c,
                    alpha=alpha,
                ))

        # build the legend:
        legend_elements = []
        for ttype in list(set(tel_types)):
            color = tel_type_to_color[ttype]
            legend_elements.append(
                Line2D([0], [0],
                       marker='o',
                       color=color,
                       label=ttype,
                       markersize=10,
                       alpha=alpha,
                       linewidth=0))
        plt.legend(handles=legend_elements)

        self.tel_colors = tel_color
        self.autoupdate = autoupdate
        self.telescopes = PatchCollection(patches, match_original=True)
        self.telescopes.set_linewidth(2.0)

        self.axes = axes or plt.gca()
        self.axes.add_collection(self.telescopes)
        self.axes.set_aspect(1.0)
        self.axes.set_title(title)
        self._labels = []
        self._quiver = None
        self.axes.autoscale_view()

    @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 set_vector_uv(self, u, v, c=None, **kwargs):
        """ sets the vector field U,V and color for all telescopes

        Parameters
        ----------
        u: array[num_tels]
            x-component of direction vector
        v: array[num_tels]
            y-component of direction vector
        c: color or list of colors
            vector color for each telescope (or one for all)
        kwargs:
            extra args passed to plt.quiver(), ignored on subsequent updates
        """
        if c is None:
            c = self.tel_colors

        if self._quiver is None:
            coords = self.tel_coords
            self._quiver = self.axes.quiver(coords.x,
                                            coords.y,
                                            u,
                                            v,
                                            color=c,
                                            scale_units='xy',
                                            angles='xy',
                                            scale=1,
                                            **kwargs)
        else:
            self._quiver.set_UVC(u, v)

    def set_vector_rho_phi(self, rho, phi, c=None, **kwargs):
        """sets the vector field using R, Phi for each telescope

        Parameters
        ----------
        rho: float or array[float]
            vector magnitude for each telescope
        phi: array[Angle]
            vector angle for each telescope
        c: color or list of colors
            vector color for each telescope (or one for all)
        """
        phi = Angle(phi).rad
        u, v = polar_to_cart(rho, phi)
        self.set_vector_uv(u, v, c=c, **kwargs)

    def set_vector_hillas(self, hillas_dict, length, time_gradient,
                          angle_offset):
        """
        Function to set the vector angle and length from a set of Hillas parameters.

        In order to proper use the arrow on the ground, also a dictionary with the time
        gradients for the different telescopes is needed. If the gradient is 0 the arrow
        is not plotted on the ground, whereas if the value of the gradient is negative,
        the arrow is rotated by 180 degrees (Angle(angle_offset) not added).

        This plotting behaviour has been tested with the timing_parameters function
        in ctapipe/image.

        Parameters
        ----------
        hillas_dict: Dict[int, HillasParametersContainer]
            mapping of tel_id to Hillas parameters
        length: Float
            length of the arrow (in meters)
        time_gradient: Dict[int, value of time gradient (no units)]
            dictionary for value of the time gradient for each telescope
        angle_offset: Float
            This should be the event.mcheader.run_array_direction[0] parameter

        """

        # rot_angle_ellipse is psi parameter in HillasParametersContainer
        rho = np.zeros(self.subarray.num_tels) * u.m
        rot_angle_ellipse = np.zeros(self.subarray.num_tels) * u.deg

        for tel_id, params in hillas_dict.items():
            idx = self.subarray.tel_indices[tel_id]
            rho[idx] = length * u.m

            if time_gradient[tel_id] > 0.01:
                params.psi = Angle(params.psi)
                angle_offset = Angle(angle_offset)
                rot_angle_ellipse[
                    idx] = params.psi + angle_offset + 180 * u.deg
            elif time_gradient[tel_id] < -0.01:
                rot_angle_ellipse[idx] = params.psi + angle_offset
            else:
                rho[idx] = 0 * u.m

        self.set_vector_rho_phi(rho=rho, phi=rot_angle_ellipse)

    def set_line_hillas(self, hillas_dict, range, **kwargs):
        """
        Function to plot a segment of length 2*range for each telescope from a set of Hillas parameters.
        The segment is centered on the telescope position.
        A point is added at each telescope position for better visualization.

        Parameters
        ----------
        hillas_dict: Dict[int, HillasParametersContainer]
            mapping of tel_id to Hillas parameters
        range: float
            half of the length of the segments to be plotted (in meters)
        """

        coords = self.tel_coords
        c = self.tel_colors

        for tel_id, params in hillas_dict.items():
            idx = self.subarray.tel_indices[tel_id]
            x_0 = coords[idx].x.value
            y_0 = coords[idx].y.value
            m = np.tan(Angle(params.psi))
            x = x_0 + np.linspace(-range, range, 50)
            y = y_0 + m * (x - x_0)
            distance = np.sqrt((x - x_0)**2 + (y - y_0)**2)
            mask = np.ma.masked_where(distance < range, distance).mask
            self.axes.plot(x[mask], y[mask], color=c[idx], **kwargs)
            self.axes.scatter(x_0, y_0, color=c[idx])

    def add_labels(self):
        px = self.tel_coords.x.value
        py = self.tel_coords.y.value
        for tel, x, y in zip(self.subarray.tels, px, py):
            name = str(tel)
            lab = self.axes.text(x, y, name, fontsize=8, clip_on=True)
            self._labels.append(lab)

    def remove_labels(self):
        for lab in self._labels:
            lab.remove()
        self._labels = []

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

    def background_contour(self, x, y, background, **kwargs):
        """
        Draw image contours in background of the display, useful when likelihood fitting

        Parameters
        ----------
        x: ndarray
            array of image X coordinates
        y: ndarray
            array of image Y coordinates
        background: ndarray
            Array of image to use in background
        kwargs: key=value
            any style keywords to pass to matplotlib
        """

        # use zorder to ensure the contours appear under the telescopes.
        self.axes.contour(x, y, background, zorder=0, **kwargs)