def arrow(self, obj, sense, *args, **kwargs): assert obj.type is Lin, 'Only Lin instance could be plotted as quiver.' bearing, plunge = obj.dd xx, yy = mplstereonet.line(plunge, bearing) xx1, yy1 = mplstereonet.line(plunge - 5, bearing) for x, y, x1, y1 in zip(xx, yy, xx1, yy1): self._ax.arrow(x, y, sense * (x1 - x), sense * (y1 - y)) self.draw()
def arrow(self, obj, sense, *args, **kwargs): assert obj.type is Lin, "Only Lin instance could be plotted as quiver." bearing, plunge = obj.dd xx, yy = mplstereonet.line(plunge, bearing) xx1, yy1 = mplstereonet.line(plunge - 5, bearing) for x, y, x1, y1 in zip(xx, yy, xx1, yy1): self._ax.arrow(x, y, sense * (x1 - x), sense * (y1 - y)) self.draw()
def rotate_data(self, raxis, raxis_angle, dipdir, dip): """ Rotates a measurment around a rotation axis a set number of degrees. Expects a rotation-axis, a rotation-angle, a dip-direction and a dip angle. The measurement is converted to latlot and then passed to the mplstereonet rotate function. """ lonlat = mplstereonet.line(dip, dipdir) #Rotation around x-axis until rotation-axis azimuth is east-west rot1 = (90 - raxis[0]) lon1 = np.degrees(lonlat[0]) lat1 = np.degrees(lonlat[1]) lon_rot1, lat_rot1 = mplstereonet.stereonet_math._rotate(lon1, lat1, theta=rot1, axis="x") #Rotation around z-axis until rotation-axis dip is east-west rot2 = -(90 - raxis[1]) lon2 = np.degrees(lon_rot1) lat2 = np.degrees(lat_rot1) lon_rot2, lat_rot2 = mplstereonet.stereonet_math._rotate(lon2, lat2, theta=rot2, axis="z") #Rotate around the x-axis for the specified rotation: rot3 = raxis_angle lon3 = np.degrees(lon_rot2) lat3 = np.degrees(lat_rot2) lon_rot3, lat_rot3 = mplstereonet.stereonet_math._rotate(lon3, lat3, theta=rot3, axis="x") #Undo the z-axis rotation rot4 = -rot2 lon4 = np.degrees(lon_rot3) lat4 = np.degrees(lat_rot3) lon_rot4, lat_rot4 = mplstereonet.stereonet_math._rotate(lon4, lat4, theta=rot4, axis="z") #Undo the x-axis rotation rot5 = -rot1 lon5 = np.degrees(lon_rot4) lat5 = np.degrees(lat_rot4) lon_rot5, lat_rot5 = mplstereonet.stereonet_math._rotate(lon5, lat5, theta=rot5, axis="x") dipdir5, dip5 = self.convert_lonlat_to_dipdir(lon_rot5, lat_rot5) return dipdir5, dip5
def compare_plungebearing(self, plunge1, azi1, plunge2, azi2): """Avoids ambiguities in plunge/bearing convention when dip is 0 or 90.""" convert = lambda a, b: sph2cart(*mplstereonet.line(a, b)) x1, y1, z1 = convert(plunge1, azi1) x2, y2, z2 = convert(plunge2, azi2) rtol, atol = 1e-7, 1e-7 try: assert np.allclose([x1, y1, z1], [x2, y2, z2], rtol, atol) except AssertionError: # Antipode is also acceptable in this case.... assert np.allclose([x1, y1, z1], [-x2, -y2, -z2], rtol, atol)
def line_in_cone(cplunge, cbearing, cangle, lplunge, lbearing): """ Evaluates if line is within a small circle (cone), such that the acute angle between the line, and the cone center line should be less than the cone angle. Parameters ---------- cplunge, cbearing, cangle: integer or float plunge, bearing, and angle defining a cone lplunge, lbearing: integer or float plunge, bearing of a line Returns ------- ang_diff<cangle: boolean True if line is within the cone """ ang_dist = np.degrees( st.angular_distance(st.line(cplunge, cbearing), st.line(lplunge, lbearing), False)) return ang_dist < cangle
def annotate_vector(ax, plunge, bearing, i, **kwargs): """Annotate a sigma1, sigma2, or sigma3 plunge/bearing.""" rotation = 90 - bearing lon, lat = mplstereonet.line(plunge, bearing) ax.scatter(lon, lat, s=200, marker=(3,0,rotation+33), clip_on=False, zorder=10, **kwargs) x = 30 * np.cos(np.radians(rotation)) y = 30 * np.sin(np.radians(rotation)) x, y = int(x), int(y) if plunge < 80: ax.annotate('', xy=(lon, lat), xytext=(x, y), xycoords='data', textcoords='offset points', arrowprops=dict(arrowstyle='-')) ax.annotate(r'$\sigma_%i : %0.0f^{\circ}$'%(i, bearing), xy=(lon, lat), xytext=(x, y), textcoords='offset points', ha='right', va='center', size=24) else: ax.annotate(r'$\sigma_%i$'%i, xy=(lon, lat), textcoords='offset points', xytext=(15, 0), ha='left', va='center', size=24, color='white')
ax.density_contour(strike, dip, rake, measurement='rakes', cmap='gist_earth', sigma=1.5) ax.rake(strike, dip, rake, marker='.', color='black') # Find the two modes centers = mplstereonet.kmeans(strike, dip, rake, num=2, measurement='rakes') strike_cent, dip_cent = mplstereonet.geographic2pole(*zip(*centers)) ax.pole(strike_cent, dip_cent, 'ro', ms=12) # Fit a girdle to the two modes # The pole of this plane will be the plunge of the fold axis axis_s, axis_d = mplstereonet.fit_girdle(*zip(*centers), measurement='radians') ax.plane(axis_s, axis_d, color='green') ax.pole(axis_s, axis_d, color='green', marker='o', ms=15) # Now we'll find the midpoint. We could project the centers as rakes on the # plane we just fit, but it's easier to get their mean vector instead. mid, _ = mplstereonet.find_mean_vector(*zip(*centers), measurement='radians') midx, midy = mplstereonet.line(*mid) # Now let's find the axial plane by fitting another girdle to the midpoint # and the pole of the plunge axis. xp, yp = mplstereonet.pole(axis_s, axis_d) x, y = [xp[0], midx], [yp[0], midy] axial_s, axial_dip = mplstereonet.fit_girdle(x, y, measurement='radians') ax.plane(axial_s, axial_dip, color='lightblue', lw=3) plt.show()
cmap='gist_earth', sigma=1.5) ax.rake(strike, dip, rake, marker='.', color='black') # Find the two modes centers = mplstereonet.kmeans(strike, dip, rake, num=2, measurement='rakes') strike_cent, dip_cent = mplstereonet.geographic2pole(*zip(*centers)) ax.pole(strike_cent, dip_cent, 'ro', ms=12) # Fit a girdle to the two modes # The pole of this plane will be the plunge of the fold axis axis_s, axis_d = mplstereonet.fit_girdle(*zip(*centers), measurement='radians') ax.plane(axis_s, axis_d, color='green') ax.pole(axis_s, axis_d, color='green', marker='o', ms=15) # Now we'll find the midpoint. We could project the centers as rakes on the # plane we just fit, but it's easier to get their mean vector instead. mid, _ = mplstereonet.find_mean_vector(*zip(*centers), measurement='radians') midx, midy = mplstereonet.line(*mid) # Now let's find the axial plane by fitting another girdle to the midpoint # and the pole of the plunge axis. xp, yp = mplstereonet.pole(axis_s, axis_d) x, y = [xp, midx], [yp, midy] axial_s, axial_dip = mplstereonet.fit_girdle(x, y, measurement='radians') ax.plane(axial_s, axial_dip, color='lightblue', lw=3) plt.show()