Esempio n. 1
0
    def plot_old(self, plot_points=False, mark_peaks=0):
        ''' Plot the points on the sphere with their values '''

        from scipy import rand
        import matplotlib.colors as colors
        #from mpl_toolkits.mplot3d import Axes3D
        import mpl_toolkits.mplot3d as a3
        import matplotlib.pyplot as plt

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

        if plot_points:
            ax.scatter(self.x, self.y, self.z, c='b', marker='o')

        if mark_peaks > 0:

            id = self.find_peaks(k=mark_peaks)
            s = 1.05
            ax.scatter(s * self.x[id],
                       s * self.y[id],
                       s * self.z[id],
                       c='k',
                       marker='o')

        voronoi = sp.SphericalVoronoi(self.cartesian.T)
        voronoi.sort_vertices_of_regions()

        if self.values is not None:

            col_max = self.values.max()
            col_min = self.values.min()

            if col_min != col_max:
                col_map = (self.values - col_min) / (col_max - col_min)
            else:
                col_map = self.values / col_max

        else:

            col_map = np.zeros(self.n_points)

        cmap = plt.get_cmap('coolwarm')

        # plot the walls
        for v_ind, col in zip(voronoi.regions, col_map):
            triangle = a3.art3d.Poly3DCollection([voronoi.vertices[v_ind]],
                                                 alpha=1.,
                                                 linewidth=0.0)
            triangle.set_color(cmap(col))
            triangle.set_edgecolor('k')
            ax.add_collection3d(triangle)

        ax.set_xlabel('X')
        ax.set_ylabel('Y')
        ax.set_zlabel('Z')
        ax.set_xlim([-1, 1])
        ax.set_ylim([-1, 1])
        ax.set_zlim([-1, 1])
Esempio n. 2
0
    def get_area_weights(self, balance_axes: bool = True):
        """return the weight of each point associated with the unit cell size

        Args:
            balance_axes (bool): Flag determining whether the weights should be
                chosen such that the weighted average of all points is the
                zero vector

        Returns:
            :class:`~numpy.ndarray`: The weight associated with each point
        """
        from scipy import spatial

        points_flat = self.points.reshape(-1, self.dim)
        if self.dim == 1:
            assert points_flat.shape == (2, 1)
            weights = np.array([0.5, 0.5])

        elif self.dim == 2:
            # get angles
            φ = np.arctan2(points_flat[:, 1], points_flat[:, 0])
            idx = np.argsort(φ)
            s0 = φ[idx[0]] + 2 * π - φ[idx[-1]]
            sizes = np.r_[s0, np.diff(φ[idx]), s0]
            weights = (sizes[1:] + sizes[:-1]) / 2
            weights /= 2 * π

        elif self.dim == 3:
            # calculate weights using spherical voronoi construction
            voronoi = spatial.SphericalVoronoi(points_flat)
            voronoi.sort_vertices_of_regions()

            weight_vals = [
                get_spherical_polygon_area(voronoi.vertices[ix])
                for ix in voronoi.regions
            ]
            weights = np.array(weight_vals, dtype=np.double)
            weights /= surface_from_radius(1, dim=self.dim)

        else:
            raise NotImplementedError()

        if balance_axes:
            weights /= weights.sum()  # normalize weights
            # adjust weights such that all distances are weighted equally, i.e.,
            # the weighted sum of all shell vectors should vanish. Additionally,
            # the sum of all weights needs to be one. To satisfy these
            # constraints simultaneously, the weights are adjusted minimally
            # (in a least square sense).
            matrix = np.c_[points_flat, np.ones(len(points_flat))]
            vector = -weights @ matrix + np.r_[np.zeros(self.dim), 1]
            weights += np.linalg.lstsq(matrix.T, vector, rcond=None)[0]

        return weights.reshape(self.points.shape[:-1])
Esempio n. 3
0
def test_spherical_voronoi():
    """ test spatial.SphericalVoronoi """
    # random points on the sphere
    ps = np.random.random((32, 3)) - 0.5
    ps /= np.linalg.norm(ps, axis=1)[:, None]

    voronoi = spatial.SphericalVoronoi(ps)
    voronoi.sort_vertices_of_regions()

    total = sum(
        spherical.get_spherical_polygon_area(voronoi.vertices[reg])
        for reg in voronoi.regions)
    assert total == pytest.approx(4 * np.pi)
Esempio n. 4
0
    def plot_voronoi_cells(self, facecmap: Optional[str] = 'Blues_r',
                           ncols: int = 20, edgecolor: str = '#32519D', cell_centers: bool = True,
                           markercolor: str = 'k', markersize: float = 2, linewidths=1, alpha: float = 0.9,
                           seed: int = 0):
        r"""
       Plots the tessellation defined by the set's Voronoi decomposition.

       Parameters
       ----------
       facecmap: Optional[str]
           Color map to be used for random coloring the tessellation faces.
       ncols: int
           Number of colors in the color map.
       edgecolor: str
           Color of the cell edges.
       cell_centers: bool
           Whether or not the cell centers are displayed.
       markercolor: str
           Color of the cell centers.
       markersize: float
           Size of the cell centers.
       linewidths: float
           Width of the cell edges.
       alpha: float
           Transparency of the cell faces.
       seed: int
           Seed for random coloring reproducibility.

       Warnings
       --------
       This method can be **very slow** for large point sets (>10'000 points)!
       """
        voronoi = sp.SphericalVoronoi(self.vec.transpose(), radius=1)
        voronoi.sort_vertices_of_regions()
        vertices = [[voronoi.vertices[region]] for region in voronoi.regions]
        self._plot_spherical_polygons(vertices, facecmap=facecmap, ncols=ncols, edgecolor=edgecolor,
                                      cell_centers=cell_centers, markercolor=markercolor, markersize=markersize,
                                      linewidths=linewidths, alpha=alpha, seed=seed)
Esempio n. 5
0
    def plot_old(self, plot_points=False, mark_peaks=0):
        """Plot the points on the sphere with their values"""

        from scipy import rand

        try:
            import matplotlib.colors as colors

            # from mpl_toolkits.mplot3d import Axes3D
            import mpl_toolkits.mplot3d as a3
            import matplotlib.pyplot as plt
        except ImportError:
            import warnings

            warnings.warn("Matplotlib is required for plotting")
            return

        fig = plt.figure()
        ax = fig.add_subplot(111, projection="3d")

        if plot_points:
            ax.scatter(self.x, self.y, self.z, c="b", marker="o")

        if mark_peaks > 0:

            id = self.find_peaks(k=mark_peaks)
            s = 1.05
            ax.scatter(s * self.x[id],
                       s * self.y[id],
                       s * self.z[id],
                       c="k",
                       marker="o")

        voronoi = sp.SphericalVoronoi(self.cartesian.T)
        voronoi.sort_vertices_of_regions()

        if self.values is not None:

            col_max = self.values.max()
            col_min = self.values.min()

            if col_min != col_max:
                col_map = (self.values - col_min) / (col_max - col_min)
            else:
                col_map = self.values / col_max

        else:

            col_map = np.zeros(self.n_points)

        cmap = plt.get_cmap("coolwarm")

        # plot the walls
        for v_ind, col in zip(voronoi.regions, col_map):
            triangle = a3.art3d.Poly3DCollection([voronoi.vertices[v_ind]],
                                                 alpha=1.0,
                                                 linewidth=0.0)
            triangle.set_color(cmap(col))
            triangle.set_edgecolor("k")
            ax.add_collection3d(triangle)

        ax.set_xlabel("X")
        ax.set_ylabel("Y")
        ax.set_zlabel("Z")
        ax.set_xlim([-1, 1])
        ax.set_ylim([-1, 1])
        ax.set_zlim([-1, 1])
def plot_groups(equal_area_points, bin_values, fig=None, filename=None, grid_resolution=0.2,
                color_range=None, cmap='hot', reverse=True, pen='0.1p,gray50', transparency=0, **kwargs):

    """
    Generate a visual representation of spatially binned data generated by 'groupby_healpix'.
    The result can either be added to a pygmt figure or saved to a GIS file (with the file
    type taken from the filename extension of the optional 'filename' parameter, e.g. shp, gmt, geojson) 
    """

    points = pygplates.MultiPointOnSphere(zip(equal_area_points.latitude,equal_area_points.longitude)).to_xyz_array() 

    radius = 1
    center = np.array([0, 0, 0])
    sv = spatial.SphericalVoronoi(points, radius, center)
    sv.sort_vertices_of_regions()

    polygon_features = []
    for region,zval in zip(sv.regions,bin_values):
        polygon = np.vstack((sv.vertices[region],sv.vertices[region][0,:]))
        polygon_feature = pygplates.Feature()
        polygon_feature.set_geometry(pygplates.PolygonOnSphere(polygon))
        polygon_feature.set_shapefile_attribute('zval', zval)
        polygon_features.append(polygon_feature)

    if filename:
        return_file = True
        pygplates.FeatureCollection(polygon_features).write(filename)

    else:
        return_file = False
        plot_file = tempfile.NamedTemporaryFile(delete=False, suffix='.gmt')
        plot_file.close()
        filename = plot_file.name
        pygplates.FeatureCollection(polygon_features).write(filename)

    if fig:
        grid_lon, grid_lat = np.meshgrid(np.arange(-180.,180.,grid_resolution),np.arange(-90.,90.,grid_resolution))
    
        d,l = sampleOnSphere(np.radians(equal_area_points.longitude),
                            np.radians(equal_area_points.latitude),
                            np.array(bin_values),
                            np.radians(grid_lon).ravel(),
                            np.radians(grid_lat).ravel(),
                            k=1)
        grid_z = np.array(bin_values)[l].reshape(grid_lon.shape)
        
        #spherical_triangulation = stripy.sTriangulation(lons=np.radians(equal_area_points.longitude), lats=np.radians(equal_area_points.latitude))
        #grid_z,_ = spherical_triangulation.interpolate_nearest(np.radians(grid_lon).ravel(), np.radians(grid_lat).ravel(), np.array(bin_values))

        ds = xr.DataArray(grid_z.reshape(grid_lon.shape), coords=[('lat',grid_lat[:,0]), ('lon',grid_lon[0,:])], name='z')

        #pygmt.config(COLOR_FOREGROUND='white', COLOR_BACKGROUND='black')
        if not color_range:
            color_range = (np.nanmin(bin_values), np.nanmax(bin_values))
            reverse = True
        pygmt.makecpt(cmap=cmap, series='{:f}/{:f}'.format(color_range[0],color_range[1]), 
                      reverse=reverse, background='o')

        # This line would allow the polygons to be plotted directly with a colormap, but tends to crash when 
        # healpix of N=32 or greater is input
        #fig.plot(data=filename, pen=pen, color='+z', cmap=True, a='Z=zval', close=True, **kwargs)
        fig.grdimage(ds, transparency=transparency, cmap=True, nan_transparent=True)
        fig.plot(data=filename, pen=pen, transparency=transparency, close=True, **kwargs)


    if not return_file:
        os.unlink(plot_file.name)
Esempio n. 7
0
def Do_Voronoi(x,
               file_prefix,
               rad=1.,
               do_plot=0,
               FTYPE='jpg',
               MATDPI=80,
               FS=10,
               DO_hold_image=0,
               BMS=(0, 0)):
    '''Enter x array (and possibly a radius, whose default value is 1).
We'll use that and its negative projection to do voronoi calculations.
What could be more fun?

    '''

    X = np.concatenate((x, -x))  # the fully monty
    lx, ly = np.shape(X)
    #vor = vu.Voronoi_Sphere_Surface(X, rad)
    vor = spsp.SphericalVoronoi(X, rad)
    vor.sort_vertices_of_regions()
    vor_regs = make_voronoi_region_dict(vor)
    vor_areas = calculate_all_polygon_areas(vor_regs)

    if do_plot:

        Amean = np.mean(vor_areas)
        Astd = np.std(vor_areas)
        Amin = np.min(vor_areas)
        Amax = np.max(vor_areas)
        vor_areas_norm = np.array(vor_areas) - Amean
        vor_areas_perc = 100. * vor_areas_norm / Amean
        if Astd:
            vor_areas_norm /= Astd
        print "++ Polygon area mean and std: (%.5f, %.5f)" % (Amean, Astd)

        tcolors = [
            (0, 0, 205),  # MediumBlue
            (65, 105, 225),  # RoyalBlue
            (135, 206, 250),  # sky blue
            (224, 255, 255),  # light cyan
            (255, 255, 255),  # white
            (255, 255, 255),  # white
            (245, 245, 150),  # sooomething
            (255, 215, 0),  # Gold
            (255, 69, 0),  # OrangeRed
            (220, 20, 60),  # crimson
        ]

        test_cmap = make_cmap(tcolors, bit=True, Nsegs=len(tcolors))

        mm = plt.cm.ScalarMappable(cmap=test_cmap)  #plt.cm.RdBu)#BrBG_r)
        col_range = [-100, 100]
        mm.set_array(col_range)
        mm.set_clim(vmin=col_range[0], vmax=col_range[1])

        # plot
        fig = plt.figure()
        overall_size = 6.
        fig.set_size_inches(overall_size * 9. / 8., overall_size)
        for bb in range(2):
            for cc in range(2):
                idx = 2 * bb + cc
                ax = fig.add_subplot('22' + str(idx + 1), projection='3d')

                for ii in range(len(vor_regs)):
                    ireg = np.array(vor_regs[ii])

                    #col_wt = Convert_Z_to_BandColor(vor_areas_norm[ii])

                    hsv = np.array(
                        csys.rgb_to_hsv(abs(X[ii, 0]), abs(X[ii, 1]),
                                        abs(X[ii, 2])))
                    #hsv[1] = 1-abs(vor_areas_perc[ii]) #1-abs(np.tanh(vor_areas_norm[ii]))
                    hsv[2] = 0.75  #1
                    my_rgb = csys.hsv_to_rgb(hsv[0], hsv[1], hsv[2])

                    #print hsv

                    asdf = mm.to_rgba(vor_areas_perc[ii])
                    '''asdf2 = np.zeros(4)
                    asdf2[:3] = abs(X[ii])
                    asdf2[3] = abs(col_wt)
                    '''

                    #fill in the Voronoi region (polygon) that contains the
                    #generator:
                    polygon = Poly3DCollection([ireg], alpha=1)  #1.0)
                    polygon.set_color(
                        asdf
                    )  #[0,0,0])# my_rgb)#mm.to_rgba(vor_areas_norm[ii]))#my_rgb) #random_color)
                    polygon.set_linewidth(1)
                    polygon.set_edgecolor(
                        my_rgb
                    )  #np.array([0,0,0])) #*(1-abs(vor_areas_perc[ii])))
                    #[0,0,0])#clr.rgb2hex(abs(X[ii]))) #0,0,0]))
                    #textt = Text3D( x = np.mean(voronoi_region[:,0]), \
                    #                y = np.mean(voronoi_region[:,1]), \
                    #              z = np.mean(voronoi_region[:,2]), \
                    #              s = str(ii))
                    ax.add_collection3d(polygon)

                ax.set_xlim3d(aar[0] * 0.7, aar[1] * 0.7)
                ax.set_ylim3d(aar[0] * 0.7, aar[1] * 0.7)
                ax.set_zlim3d(aar[0] * 0.7, aar[1] * 0.7)
                ax.set_xticks([])
                ax.set_xticklabels([''] * len(aar))
                ax.set_yticks([])
                ax.set_yticklabels([''] * len(aar))
                ax.set_zticks([])
                ax.set_zticklabels([''] * len(aar))
                ax.view_init(azim=axview[idx][0], elev=axview[idx][1])
                plt.tick_params(axis='both', which='major', labelsize=10)

                arr_a = Arrow3D(px[idx][0],
                                px[idx][1],
                                px[idx][2],
                                mutation_scale=40,
                                lw=2,
                                arrowstyle="-|>",
                                color="r")
                arr_b = Arrow3D(py[idx][0],
                                py[idx][1],
                                py[idx][2],
                                mutation_scale=40,
                                lw=2,
                                arrowstyle="-|>",
                                color="g")
                arr_c = Arrow3D(pz[idx][0],
                                pz[idx][1],
                                pz[idx][2],
                                mutation_scale=40,
                                lw=2,
                                arrowstyle="-|>",
                                color="b")
                ax.text2D(x=0.2,
                          y=0.9,
                          s=axview_lab[idx],
                          fontsize=FS + 2,
                          horizontalalignment='center',
                          verticalalignment='center',
                          fontdict=None,
                          withdash=False,
                          transform=ax.transAxes)
                plt.tight_layout(h_pad=-2, w_pad=-2)

                ax.add_artist(arr_a)
                ax.add_artist(arr_b)
                ax.add_artist(arr_c)
                #ax.w_xaxis.line.set_lw(0.)
                #ax.w_yaxis.line.set_lw(0.)
                #ax.w_zaxis.line.set_lw(0.)
                ax.set_axis_off()

        if BMS[0] > 10:
            info_textT = "$b$-val: %.0f $\pm$ %.0f" \
                         % (BMS[0], BMS[1])
        else:
            info_textT = "$b$-val: %.2f $\pm$ %.2f" \
                         % (BMS[0], BMS[1])

        info_textB = "\nArea\n(mean, SD) = (%.4f, %.4f)" \
                     % (Amean, Astd)
        info_textB+= "\n(min, max) = (%.4f, %.4f)" \
                     % (Amin, Amax)

        colbar = fig.add_axes([0.82, 0.31, 0.05, 0.35])
        clb = fig.colorbar(mm, cax=colbar)
        clb.ax.set_title('$\mathsf{\Delta A \%}$', fontsize=FS)
        clb.ax.tick_params(labelsize=FS)

        #plt.colorbar(im_tmpX, cax=colbar, cmap=plt.cm.RdBu )

        fig.subplots_adjust(bottom=0.04, top=0.94, right=0.8)
        fig.text(x=0.4,
                 y=0.08,
                 s=info_textB,
                 horizontalalignment='center',
                 verticalalignment='center',
                 fontsize=FS)
        fig.text(x=0.4,
                 y=0.95,
                 s=info_textT,
                 horizontalalignment='center',
                 verticalalignment='center',
                 fontsize=FS)

        plt.ion()
        plt.show()
        name_out = file_prefix + "_VOR"
        name_out_full = name_out + '.' + FTYPE
        plt.savefig(name_out_full, dpi=MATDPI)
        if DO_hold_image:
            raw_input()
        else:
            plt.close("all")

    std_area = np.std(vor_areas)
    mean_area = np.mean(vor_areas)
    max_area = np.max(vor_areas)
    min_area = np.min(vor_areas)

    theor_area = 4 * np.pi * rad * rad / float(lx)

    print "\t ratio stdev/mean is  : %.4f" % (std_area / mean_area)
    print "\t max of the area is   : %.4f" % max_area
    print "\t min of the area is   : %.4f" % min_area
    print "\t mean of the area is  : %.4f" % mean_area
    print "\t stdev of the area is : %.4f" % std_area
    print "\t Theoretical area is  : %.4f" % theor_area

    return vor_areas, mean_area, std_area, max_area, min_area, \
        vor, vor_regs