Exemplo n.º 1
0
    def plot_field(self, field):
        """ Map the given field.

        Parameters:
        -----------
        field : 1D array TOCHECK
            Field to plot.

        """

        if self.mask is not None:
            field = np.ma.masked_where(field <= self.mask, field)

        # Update array values if the plot has already been initialised
        if self.tripcolor_plot:
            field = field[self.masked_tris].mean(axis=1)
            self.tripcolor_plot.set_array(field)
            return

        # Create tripcolor plot
        x, y = self.m(self.lon, self.lat)
        self.tri = Triangulation(x, y, self.triangles)
        self.masked_tris = self.tri.get_masked_triangles()
        field = field[self.masked_tris].mean(axis=1)
        self.tripcolor_plot = self.axes.tripcolor(self.tri,
                                                  field,
                                                  vmin=self.vmin,
                                                  vmax=self.vmax,
                                                  cmap=self.cmap,
                                                  edgecolors=self.edgecolors,
                                                  zorder=1,
                                                  norm=self.norm)

        # Overlay the grid
        # self.axes.triplot(self.tri, zorder=2)

        # Overlay stations in the first instance
        if self.stations is not None:
            mx, my = self.m(self.stations[0, :], self.stations[1, :])
            self.axes.scatter(mx,
                              my,
                              marker='*',
                              c='k',
                              s=self.s_stations,
                              edgecolors='none',
                              zorder=4)

        # Add colorbar scaled to axis width
        divider = make_axes_locatable(self.axes)
        cax = divider.append_axes("right", size="5%", pad=0.05)
        self.cbar = self.figure.colorbar(self.tripcolor_plot,
                                         cax=cax,
                                         extend=self.extend)
        self.cbar.ax.tick_params(labelsize=self.fs)
        if self.cb_label:
            self.cbar.set_label(self.cb_label)

        return
Exemplo n.º 2
0
def generate_mesh(nodes):
    from  matplotlib.tri.triangulation import Triangulation
    from numpy import array
    x = []; y = []
    for nid in sorted(nodes.keys()):
        x_, y_ = nodes[nid]
        x.append(x_)
        y.append(y_)
    t = Triangulation(x, y)
    return array(x), array(y), t.triangles
Exemplo n.º 3
0
    def _refine_triangulation_once(triangulation, ancestors=None):
        """
        This function refines a matplotlib.tri *triangulation* by splitting
        each triangle into 4 child-masked_triangles built on the edges midside
        nodes.
        The masked triangles, if present, are also splitted but their children
        returned masked.

        If *ancestors* is not provided, returns only a new triangulation:
        child_triangulation.

        If the array-like key table *ancestor* is given, it shall be of shape
        (ntri,) where ntri is the number of *triangulation* masked_triangles.
        In this case, the function returns
        (child_triangulation, child_ancestors)
        child_ancestors is defined so that the 4 child masked_triangles share
        the same index as their father: child_ancestors.shape = (4 * ntri,).

        """
        x = triangulation.x
        y = triangulation.y

        #    According to tri.triangulation doc:
        #         neighbors[i,j] is the triangle that is the neighbor
        #         to the edge from point index masked_triangles[i,j] to point
        #         index masked_triangles[i,(j+1)%3].
        neighbors = triangulation.neighbors
        triangles = triangulation.triangles
        npts = np.shape(x)[0]
        ntri = np.shape(triangles)[0]
        if ancestors is not None:
            ancestors = np.asarray(ancestors)
            if np.shape(ancestors) != (ntri,):
                raise ValueError(
                    "Incompatible shapes provide for triangulation"
                    ".masked_triangles and ancestors: {0} and {1}".format(
                        np.shape(triangles), np.shape(ancestors)))

        # Initiating tables refi_x and refi_y of the refined triangulation
        # points
        # hint: each apex is shared by 2 masked_triangles except the borders.
        borders = np.sum(neighbors == -1)
        added_pts = (3*ntri + borders) / 2
        refi_npts = npts + added_pts
        refi_x = np.zeros(refi_npts)
        refi_y = np.zeros(refi_npts)

        # First part of refi_x, refi_y is just the initial points
        refi_x[:npts] = x
        refi_y[:npts] = y

        # Second part contains the edge midside nodes.
        # Each edge belongs to 1 triangle (if border edge) or is shared by 2
        # masked_triangles (interior edge).
        # We first build 2 * ntri arrays of edge starting nodes (edge_elems,
        # edge_apexes) ; we then extract only the masters to avoid overlaps.
        # The so-called 'master' is the triangle with biggest index
        # The 'slave' is the triangle with lower index
        # (can be -1 if border edge)
        # For slave and master we will identify the apex pointing to the edge
        # start
        edge_elems = np.ravel(np.vstack([np.arange(ntri, dtype=np.int32),
                                         np.arange(ntri, dtype=np.int32),
                                         np.arange(ntri, dtype=np.int32)]))
        edge_apexes = np.ravel(np.vstack([np.zeros(ntri, dtype=np.int32),
                                          np.ones(ntri, dtype=np.int32),
                                          np.ones(ntri, dtype=np.int32)*2]))
        edge_neighbors = neighbors[edge_elems, edge_apexes]
        mask_masters = (edge_elems > edge_neighbors)

        # Identifying the "masters" and adding to refi_x, refi_y vec
        masters = edge_elems[mask_masters]
        apex_masters = edge_apexes[mask_masters]
        x_add = (x[triangles[masters, apex_masters]] +
                 x[triangles[masters, (apex_masters+1) % 3]]) * 0.5
        y_add = (y[triangles[masters, apex_masters]] +
                 y[triangles[masters, (apex_masters+1) % 3]]) * 0.5
        refi_x[npts:] = x_add
        refi_y[npts:] = y_add

        # Building the new masked_triangles ; each old masked_triangles hosts
        # 4 new masked_triangles
        # there are 6 pts to identify per 'old' triangle, 3 new_pt_corner and
        # 3 new_pt_midside
        new_pt_corner = triangles

        # What is the index in refi_x, refi_y of point at middle of apex iapex
        #  of elem ielem ?
        # If ielem is the apex master: simple count, given the way refi_x was
        #  built.
        # If ielem is the apex slave: yet we do not know ; but we will soon
        # using the neighbors table.
        new_pt_midside = np.empty([ntri, 3], dtype=np.int32)
        cum_sum = npts
        for imid in range(3):
            mask_st_loc = (imid == apex_masters)
            n_masters_loc = np.sum(mask_st_loc)
            elem_masters_loc = masters[mask_st_loc]
            new_pt_midside[:, imid][elem_masters_loc] = np.arange(
                n_masters_loc, dtype=np.int32) + cum_sum
            cum_sum += n_masters_loc

        # Now dealing with slave elems.
        # for each slave element we identify the master and then the inode
        # onces slave_masters is indentified, slave_masters_apex is such that:
        # neighbors[slaves_masters, slave_masters_apex] == slaves
        mask_slaves = np.logical_not(mask_masters)
        slaves = edge_elems[mask_slaves]
        slaves_masters = edge_neighbors[mask_slaves]
        diff_table = np.abs(neighbors[slaves_masters, :] -
                            np.outer(slaves, np.ones(3, dtype=np.int32)))
        slave_masters_apex = np.argmin(diff_table, axis=1)
        slaves_apex = edge_apexes[mask_slaves]
        new_pt_midside[slaves, slaves_apex] = new_pt_midside[
            slaves_masters, slave_masters_apex]

        # Builds the 4 child masked_triangles
        child_triangles = np.empty([ntri*4, 3], dtype=np.int32)
        child_triangles[0::4, :] = np.vstack([
            new_pt_corner[:, 0], new_pt_midside[:, 0],
            new_pt_midside[:, 2]]).T
        child_triangles[1::4, :] = np.vstack([
            new_pt_corner[:, 1], new_pt_midside[:, 1],
            new_pt_midside[:, 0]]).T
        child_triangles[2::4, :] = np.vstack([
            new_pt_corner[:, 2], new_pt_midside[:, 2],
            new_pt_midside[:, 1]]).T
        child_triangles[3::4, :] = np.vstack([
            new_pt_midside[:, 0], new_pt_midside[:, 1],
            new_pt_midside[:, 2]]).T
        child_triangulation = Triangulation(refi_x, refi_y, child_triangles)

        # Builds the child mask
        if triangulation.mask is not None:
            child_triangulation.set_mask(np.repeat(triangulation.mask, 4))

        if ancestors is None:
            return child_triangulation
        else:
            return child_triangulation, np.repeat(ancestors, 4)
    def show_img(self,
                 start_frame,
                 period=None,
                 output=None,
                 cell_rep=1,
                 vmax=None,
                 scalebar=False,
                 boundary=None,
                 offset=5,
                 boundary_offset=5,
                 img_offset=10,
                 cmap="gray",
                 mode='tri',
                 bin_step=1,
                 r=5,
                 bin_rep=7,
                 tri_method='linear',
                 roll_correction=True):

        if start_frame < 0:
            start_frame = len(self.Z_history) - 1

        if period is None:
            period = 100000000

        for num in range(start_frame, len(self.Z_history), period):
            img_name = "rip.{}.png".format(str(int(num / period)).zfill(5))

            print("DISPL NUM::{}".format(num))
            X_, Y_, Z_ = self.leveled_xyz(self.Z_history[num],
                                          cell_rep,
                                          correction=roll_correction)
            flat = [None, None, None]
            flat[0] = X_.flatten()
            flat[1] = Y_.flatten()
            flat[2] = Z_.flatten()
            flat = np.asarray(flat)

            if boundary is None:
                boundary = self.get_img_boundary(X_, Y_, Z_)
                boundary[0][0] += offset
                boundary[1][0] += offset
                boundary[0][1] -= offset
                boundary[1][1] -= offset

            print(boundary)

            if mode == 'scatter3d' or mode == 'scatter':
                #x_flag = np.logical_and(flat_[0] > boundary[0][0], flat_[0] < boundary[0][1])
                #y_flag = np.logical_and(flat_[1] > boundary[1][0], flat_[1] < boundary[1][1])
                #flat = np.array(flat_)
                #flat = flat[:, np.logical_and(x_flag, y_flag)]

                if mode == 'scatter3d':
                    fig = plt.figure()
                    ax = fig.add_subplot(111, projection='3d')

                    ax.scatter(flat[0], flat[1], flat[2])
                    ax.set_xlabel("X axis")
                    ax.set_ylabel("Y axis")
                    plt.show()

                else:
                    plt.scatter(flat[0], flat[1])
                    plt.show()

            elif mode == 'surf':
                r2 = np.power(r, 2)
                bin_centers = [
                    np.arange(boundary[0, 0], boundary[0, 1] + 0.001,
                              bin_step),
                    np.arange(boundary[1, 0], boundary[1, 1] + 0.001, bin_step)
                ]

                bin_edges = np.array([
                    bin_centers[0][:-1] + 0.5 * bin_step,
                    bin_centers[1][:-1] + 0.5 * bin_step
                ])

                indexes = [None, None]
                indexes[0] = np.digitize(flat_[0], bin_edges[0])  # x bins
                indexes[1] = np.digitize(flat_[1], bin_edges[1])  # y bins

                safe_offset = -1000000
                Z_holder = np.ones(
                    (bin_centers[1].shape[0], bin_centers[0].shape[0], 3, 3),
                    dtype=float) * safe_offset

                for i in range(len(flat_[0])):
                    ix = indexes[0][i]
                    iy = indexes[1][i]
                    cr_z = flat_[2][i]
                    if (Z_holder[iy, ix, 0, 2] < cr_z):
                        Z_holder[iy, ix, 2] = Z_holder[iy, ix, 1]
                        Z_holder[iy, ix, 1] = Z_holder[iy, ix, 0]
                        Z_holder[iy, ix, 0] = [flat_[0][i], flat_[1][i], cr_z]

                    elif (Z_holder[iy, ix, 1, 2] < cr_z):
                        Z_holder[iy, ix, 2] = Z_holder[iy, ix, 1]
                        Z_holder[iy, ix, 1] = [flat_[0][i], flat_[1][i], cr_z]

                    elif (Z_holder[iy, ix, 2, 2] < cr_z):
                        Z_holder[iy, ix, 2] = [flat_[0][i], flat_[1][i], cr_z]

                # discard edges
                Z_holder = Z_holder[1:-1, 1:-1, :, :]
                probe_bins = (bin_rep * 2 + 1) * (bin_rep * 2 + 1)
                probe_bins_total = probe_bins * 3
                Z_full_holder = np.empty((Z_holder.shape[0], Z_holder.shape[1],
                                          probe_bins_total, 3))

                bin_rep_arr = list(range(-bin_rep, bin_rep + 1))
                for n_, roll_ in zip(
                        range(probe_bins),
                        itertools.product(bin_rep_arr, bin_rep_arr)):
                    #print(roll_, n_*3, (n_+1)*3)
                    Z_full_holder[:, :, n_ * 3:(n_ + 1) * 3] = np.roll(
                        Z_holder, (roll_[0], roll_[1]), axis=(0, 1))
                Z_full_holder = Z_full_holder[1:-1, 1:-1, :, :]

                bin_centers[0] = bin_centers[0][2:-2]
                bin_centers[1] = bin_centers[1][2:-2]

                probe = np.stack(np.meshgrid(bin_centers[0], bin_centers[1]),
                                 -1)
                probe = np.append(probe,
                                  np.zeros(
                                      (probe.shape[0], probe.shape[1], 1)),
                                  axis=2)
                probe = np.tile(probe, probe_bins_total).reshape(
                    probe.shape[0], probe.shape[1], probe_bins_total, 3)

                probe_diff = Z_full_holder - probe
                probe_height = np.sqrt(r2 -
                                       (np.power(probe_diff[:, :, :, 0], 2) +
                                        np.power(probe_diff[:, :, :, 1], 2)))
                probe_z = Z_full_holder[:, :, :, 2] + probe_height

                probe_z[np.isnan(probe_z)] = safe_offset
                probe_z = np.amax(probe_z, -1)

                probe_z[probe_z <= safe_offset + 1] = 0.0
                probe_z -= np.min(probe_z)
                print("Probe {}".format(np.max(probe_z)))

                if vmax is None:
                    vmax = np.max(probe_z)

                if vmax == "get":
                    return np.max(probe_z)

                # normalize
                probe_z = probe_z / vmax
                probe_z = (0.5 - np.mean(probe_z)) + probe_z

                if output:
                    plt.imsave("{}/{}".format(output, img_name),
                               probe_z,
                               cmap=cmap)
                else:
                    plt.imshow(probe_z, cmap=cmap, vmin=0.0, vmax=1.0)
                    plt.show()

            elif mode == 'tri' or mode == 'tri_scatter':
                tri = Triangulation(flat[0], flat[1])
                if tri_method == 'cube':
                    interpol = CubicTriInterpolator(tri, flat[2])
                else:
                    interpol = LinearTriInterpolator(tri, flat[2])

                x_new = np.arange(boundary[0][0], boundary[0][1], self.img_dx)
                y_new = np.arange(boundary[1][0], boundary[1][1], self.img_dx)
                X_new, Y_new = np.meshgrid(x_new, y_new)

                Z_new = interpol(X_new, Y_new)

                print("Orginal range: {}   {}".format(np.min(Z_new),
                                                      np.max(Z_new)))

                Z_new = Z_new - np.min(Z_new)

                if vmax == "get":
                    return np.max(Z_new)
                if vmax is None:
                    vmax = np.max(Z_new)

                Z_new = Z_new / vmax
                Z_new += (1 - np.max(Z_new)) * 0.5

                if scalebar:
                    plt.gca().add_artist(ScaleBar(1.0 / self.img_dx, 'nm'))

                if output:
                    if mode == 'tri':
                        plt.imsave("{}/{}".format(output, img_name),
                                   Z_new,
                                   vmin=0,
                                   vmax=1,
                                   cmap=cmap)
                    else:
                        inside_box = np.logical_and(
                            np.logical_and(flat[0] > boundary[0][0],
                                           flat[0] < boundary[0][1]),
                            np.logical_and(flat[1] > boundary[1][0],
                                           flat[1] < boundary[1][1]))
                        scatter_x = flat[0, inside_box]
                        scatter_y = flat[1, inside_box]

                        plt.imshow(Z_new, vmin=0, vmax=1, cmap=cmap)
                        plt.scatter(scatter_x - boundary[0][0],
                                    scatter_y - boundary[1][0],
                                    marker=',',
                                    s=1,
                                    lw=0,
                                    color='red')
                        plt.savefig("{}/{}".format(output, img_name))
                        plt.cla()

                else:
                    plt.imshow(Z_new, vmin=0, vmax=1, cmap=cmap)
                    if mode == 'tri_scatter':
                        inside_box = np.logical_and(
                            np.logical_and(flat[0] > boundary[0][0],
                                           flat[0] < boundary[0][1]),
                            np.logical_and(flat[1] > boundary[1][0],
                                           flat[1] < boundary[1][1]))
                        scatter_x = flat[0, inside_box]
                        scatter_y = flat[1, inside_box]

                        plt.scatter(scatter_x - boundary[0][0],
                                    scatter_y - boundary[1][0],
                                    marker=',',
                                    s=1,
                                    lw=0,
                                    color='red')
                    plt.show()
Exemplo n.º 5
0
def _get_interp_tri(x_in, y_in, gr_x, gr_y, method=None):
    """
    For each value (x_in, y_in) returns _indexes of the closets 3 values (Delaunay) in the (gr_x, gr_y) table, 
    and the corresponding coefficients.
    @method: tri_surf', 'plan_interp'
    """
    methods = ['tri_surf', 'plan_interp']

    calling = 'interp_3D'
    pc.log_.message('Entering interp 3D', calling=calling)
    if not pc.config.INSTALLED['Triangulation']:
        pc.log_.error('Triangulation package not available from matplotlib.',
                      calling=calling)
        return None
    if method is None:
        method = methods[0]
    if method not in methods:
        pc.log_.error('{0} is not a valid method'.format(method),
                      calling=calling)
        return None

    n_points = np.size(x_in)
    indexes = np.zeros((n_points, 3), dtype=int) - 1
    coeffs = np.zeros((n_points, 3))
    if method == 'tri_surf':

        def get_coeff(x, y, P1, P2, P3):
            v1x = P1[0] - x
            v1y = P1[1] - y
            v2x = P2[0] - x
            v2y = P2[1] - y
            v3x = P3[0] - x
            v3y = P3[1] - y
            d1 = abs(v2x * v3y - v2y * v3x)
            d2 = abs(v1x * v3y - v1y * v3x)
            d3 = abs(v1x * v2y - v1y * v2x)
            dsum = d1 + d2 + d3
            return np.squeeze(np.transpose([d1 / dsum, d2 / dsum, d3 / dsum]))
    elif method == 'plan_interp':

        def get_coeff(x, y, P1, P2, P3):
            XY = np.asarray((x, y))
            d1 = misc.dist_point_line(XY, P2, P3) / dpl1
            d2 = misc.dist_point_line(XY, P1, P3) / dpl2
            d3 = misc.dist_point_line(XY, P1, P2) / dpl3
            dsum = d1 + d2 + d3
            return np.squeeze(np.transpose([d1 / dsum, d2 / dsum, d3 / dsum]))

    tri = Triangulation(gr_x, gr_y)
    pc.log_.message('Triangulation done', calling=calling)
    n_triangles = tri.triangle_nodes.shape[0]
    for i, triangle in enumerate(tri.triangle_nodes):
        T1 = np.asarray((gr_x[triangle[0]], gr_y[triangle[0]]))
        T2 = np.asarray((gr_x[triangle[1]], gr_y[triangle[1]]))
        T3 = np.asarray((gr_x[triangle[2]], gr_y[triangle[2]]))
        points_inside = misc.points_inside_triangle(x_in, y_in, T1, T2, T3)
        pc.log_.message('{0} points inside triangle {1} over {2}'.format(
            points_inside.sum(), i, n_triangles),
                        calling=calling)
        if method == 'plan_interp':
            dpl1 = misc.dist_point_line(T1, T2, T3)
            dpl2 = misc.dist_point_line(T2, T3, T1)
            dpl3 = misc.dist_point_line(T3, T1, T2)
        if points_inside.sum() != 0:
            indexes[points_inside] = triangle
            coeffs[points_inside] = get_coeff(x_in[points_inside],
                                              y_in[points_inside], T1, T2, T3)
    return indexes, coeffs
Exemplo n.º 6
0
# Read in the grid's dimensions
n_nodes = mediator.get_dimension_variable('node')
n_elems = mediator.get_dimension_variable('element')

# Grid connectivity/adjacency
nv = mediator.get_grid_variable('nv', (3, n_elems), int)

# Cartesian coordinates
x_nodes = mediator.get_grid_variable('x', (n_nodes), float)
y_nodes = mediator.get_grid_variable('y', (n_nodes), float)
x_centroids = mediator.get_grid_variable('xc', (n_elems), float)
y_centroids = mediator.get_grid_variable('yc', (n_elems), float)

triangles = nv.transpose()
tri = Triangulation(x_nodes, y_nodes, triangles)

# Plot
fig = plt.figure()
ax = fig.add_subplot(111)
ax.triplot(tri)

for idx, (xc, yc) in enumerate(zip(x_centroids, y_centroids)):
    ax.scatter(xc, yc)
    ax.annotate('xc_{}'.format(idx), xy=(xc, yc), xytext=(xc, yc))

# Plot
for idx, (x, y) in enumerate(zip(x_nodes, y_nodes)):
    ax.scatter(x, y)
    ax.annotate('xn_{}'.format(idx), xy=(x, y), xytext=(x, y))