def test_fit_girdle(self): for strike in range(0, 370, 10): for dip in range(0, 100, 10): lon, lat = mplstereonet.plane(strike, dip) strikes, dips = mplstereonet.geographic2pole(lon, lat) s, d = mplstereonet.fit_girdle(strikes, dips) self.compare_strikedip(strike, dip, s, d)
def test_fit_girdle_noisy(self): np.random.seed(1) for strike in range(0, 370, 10): for dip in range(0, 100, 10): lon, lat = mplstereonet.plane(strike, dip) lon += np.radians(np.random.normal(0, 1, lon.shape)) lat += np.radians(np.random.normal(0, 1, lat.shape)) s_noisy, d_noisy = mplstereonet.geographic2pole(lon, lat) s, d = mplstereonet.fit_girdle(s_noisy, d_noisy) ang_dist = self.cos_distance(strike, dip, s, d) assert ang_dist < 2 or (180 - ang_dist) < 2
def Stereo(self): """ Stereographic representation function Determine the hight place density of structure, Calculate distributiion of structure and its characteristic (min, mean, max) """ strikes, dips = self.pts['stk'], self.pts['dip'] fig = plt.figure(figsize=(10, 8)) ax = fig.add_subplot(111, projection='stereonet') ax.plane(strikes, dips, c='k', label='Fault system') strike, dip = mste.fit_girdle(strikes, dips) ax.pole(strike, dip, c='r', label='Pole of Fault plane') # Calculate the number of directions (strikes) every 10° using numpy.histogram bin_edges = np.arange(-5, 366, 10) number_of_strikes, bin_edges = np.histogram(strikes, bin_edges) # Sum the last value with the first value number_of_strikes[0] += number_of_strikes[-1] ''' Sum the first half 0-180° with the second half 180-360° to achieve the "mirrored behavior" of Rose Diagrams ''' half = np.sum(np.split(number_of_strikes[:-1], 2), 0) two_halves = np.concatenate([half, half]) # Create the rose diagram fig = plt.figure(figsize=(8, 8)) ax = fig.add_subplot(111, projection='stereonet') ax.pole(strikes, dips, c='k', label='Pole of Structure Planes') ax.density_contourf(strikes, dips, mesurement='poles', cmap='Reds') ax.set_title('Pole Density contour of de Structure', y=1.10, fontsize=15) ax.grid() fig = plt.figure(figsize=(8, 8)) ax = fig.add_subplot(111, projection='polar') ax.bar(np.deg2rad(np.arange(0, 360, 10)), two_halves, width=np.deg2rad(10), bottom=0.0, color='.8', edgecolor='k') ax.set_theta_zero_location('N') ax.set_theta_direction(-1) ax.set_thetagrids(np.arange(0, 360, 10), labels=np.arange(0, 360, 10)) ax.set_rgrids(np.arange(1, two_halves.max() + 1, 2), angle=0, weight='black') ax.set_title('Rose Diagram of Structure', y=1.10, fontsize=15) fig.tight_layout()
def fitfold(self): strike, dip = self.get_strike_dip() # discards the old graph self.ax.hold(True) fit_strike,fit_dip = mplstereonet.fit_girdle(strike,dip) lon, lat = mplstereonet.pole(fit_strike, fit_dip) (plunge,), (bearing,) = mplstereonet.pole2plunge_bearing(fit_strike, fit_dip) template = u'Plunge / Direction of Fold Axis\n{:02.0f}\u00b0/{:03.0f}\u00b0' self.ax.annotate(template.format(plunge, bearing), ha='center', va='bottom', xy=(lon, lat), xytext=(-50, 20), textcoords='offset points', arrowprops=dict(arrowstyle='-|>', facecolor='black')) self.ax.plane(fit_strike, fit_dip, color='red', lw=2) self.ax.pole(fit_strike, fit_dip, marker='o', color='red', markersize=14) self.canvas.draw()
def fitfold(self): strike = [] dip = [] for f in self.layer.selectedFeatures(): dip.append(f['dip']) #self.dip_combo.currentText()]) strike.append(f['strike'])#self.strike_combo.currentText()]) # discards the old graph self.ax.hold(True) fit_strike,fit_dip = mplstereonet.fit_girdle(strike,dip) lon, lat = mplstereonet.pole(fit_strike, fit_dip) (plunge,), (bearing,) = mplstereonet.pole2plunge_bearing(fit_strike, fit_dip) template = u'P/B of Fold Axis\n{:02.0f}\u00b0/{:03.0f}\u00b0' self.ax.annotate(template.format(plunge, bearing), ha='center', va='bottom', xy=(lon, lat), xytext=(-50, 20), textcoords='offset points', arrowprops=dict(arrowstyle='-|>', facecolor='black')) print fit_strike, fit_dip self.ax.plane(fit_strike, fit_dip, color='red', lw=2) self.ax.pole(fit_strike, fit_dip, marker='o', color='red', markersize=14) self.canvas.draw()
N 60 E, 45 NW N 41 E, 50 SE N 35 E, 35 SE N 20 E, 20 E ''' strikes, dips = zip(*[mplstereonet.parse_strike_dip(*s.strip().split(',')) for s in fold_mesurements.split('\n') if s]) strikes, dips from collections import OrderedDict fig = plt.figure(figsize=(10,8)) # Method 1 ax = fig.add_subplot(121, projection='stereonet') ax.plane(strikes, dips, c='k', label='Planes (Fold Limbs)') strike, dip = mplstereonet.fit_girdle(strikes,dips) ax.pole(strike, dip, c='r', label='Beta axis (Intersection of Planes)') # Method 2 ax = fig.add_subplot(122, projection='stereonet') ax.pole(strikes, dips, c='k', label='Planes (Fold Limbs)') ax.plane(strike, dip, c='g', label='Fitted GC') ax.pole(strike, dip, c='r', label='Beta axis (Pole of GC)') for ax, title in zip(fig.axes[1::2], ['Beta diagram', 'S-pole diagram']): ax.set_title(title, y=1.10, fontsize=15) ax.grid() #this will avoid repetition in the legend handles, labels = ax.get_legend_handles_labels() by_label = OrderedDict(zip(labels, handles)) ax.legend(by_label.values(), by_label.keys(), loc='upper left')
def plot_bedding_stereonets_old(orientations,all_sorts): import mplstereonet import matplotlib.pyplot as plt groups=all_sorts['group'].unique() print("All observations n=",len(orientations)) fig, ax = mplstereonet.subplots(figsize=(7,7)) strikes = orientations["azimuth"].values -90 dips = orientations["dip"].values cax = ax.density_contourf(strikes, dips, measurement='poles') ax.pole(strikes, dips, markersize=5, color='w') ax.grid(True) text = ax.text(2.2, 1.37, "All data", color='b') plt.show() for gp in groups: all_sorts2=all_sorts[all_sorts["group"]==gp] all_sorts2.set_index("code", inplace = True) frames={} first=True for indx,as2 in all_sorts2.iterrows(): orientations2=orientations[orientations["formation"]==indx] if(first): first=False all_orientations=orientations2.copy() else: all_orientations=pd.concat([all_orientations,orientations2],sort=False) if(len(all_orientations)>0): print("----------------------------------------------------------------------------------------------------------------------") print(gp,"observations n=",len(all_orientations)) fig, ax = mplstereonet.subplots(figsize=(5,5)) strikes = all_orientations["azimuth"].values -90 dips = all_orientations["dip"].values cax = ax.density_contourf(strikes, dips, measurement='poles') ax.pole(strikes, dips, markersize=5, color='w') ax.grid(True) text = ax.text(2.2, 1.37,gp, color='b') plt.show() for gp in groups: all_sorts2=all_sorts[all_sorts["group"]==gp] all_sorts2.set_index("code", inplace = True) print("----------------------------------------------------------------------------------------------------------------------") print(gp) #display(all_sorts2) ind=0 for indx,as2 in all_sorts2.iterrows(): ind2=int(fmod(ind,3)) orientations2=orientations[orientations["formation"]==indx] print(indx,"observations n=",len(orientations2)) #display(orientations2) if(len(orientations2)>0): if(ind2==0): fig, ax = mplstereonet.subplots(1,3,figsize=(15,15)) strikes = orientations2["azimuth"].values -90 dips = orientations2["dip"].values cax = ax[ind2].density_contourf(strikes, dips, measurement='poles') ax[ind2].pole(strikes, dips, markersize=5, color='w') ax[ind2].grid(True) #fig.colorbar(cax) text = ax[ind2].text(2.2, 1.37, indx, color='b') # Fit a plane to the girdle of the distribution and display it. fit_strike, fit_dip = mplstereonet.fit_girdle(strikes, dips) print('strike/dip of girdle',fit_strike, '/', fit_dip) if(ind2==2): plt.show() ind=ind+1 if(ind>0 and not ind2==2): plt.show()
def plot_bedding_stereonets(orientations_clean,geology,c_l,display): import mplstereonet import matplotlib.pyplot as plt orientations = gpd.sjoin(orientations_clean, geology, how="left", op="within") groups=geology[c_l['g']].unique() codes=geology[c_l['c']].unique() print("All observations n=",len(orientations_clean)) print('groups',groups,'\ncodes',codes) if(display): fig, ax = mplstereonet.subplots(figsize=(7,7)) if(c_l['otype']=='dip direction'): strikes = orientations[c_l['dd']].values -90 else: strikes = orientations[c_l['dd']].values dips = orientations[c_l['d']].values if(display): cax = ax.density_contourf(strikes, dips, measurement='poles') ax.pole(strikes, dips, markersize=5, color='w') ax.grid(True) text = ax.text(2.2, 1.37, "All data", color='b') plt.show() group_girdle={} for gp in groups: all_orientations=orientations[orientations[c_l['g']]==gp] if(len(all_orientations)==1): print("----------------------------------------------------------------------------------------------------------------------") print(gp,"observations has 1 observation") group_girdle[gp]=(-999,-999,1) elif(len(all_orientations)>0): print("----------------------------------------------------------------------------------------------------------------------") print(gp,"observations n=",len(all_orientations)) if(display): fig, ax = mplstereonet.subplots(figsize=(5,5)) if(c_l['otype']=='dip direction'): strikes = all_orientations[c_l['dd']].values -90 else: strikes = all_orientations[c_l['dd']].values dips = all_orientations[c_l['d']].values if(display): cax = ax.density_contourf(strikes, dips, measurement='poles') ax.pole(strikes, dips, markersize=5, color='w') ax.grid(True) text = ax.text(2.2, 1.37,gp, color='b') plt.show() fit_strike, fit_dip = mplstereonet.fit_girdle(strikes, dips) (plunge,), (bearing,) = mplstereonet.pole2plunge_bearing(fit_strike, fit_dip) group_girdle[gp]=(plunge, bearing,len(all_orientations)) print('strike/dip of girdle',fit_strike, '/', fit_dip) else: print("----------------------------------------------------------------------------------------------------------------------") print(gp,"observations has no observations") group_girdle[gp]=(-999,-999,0) if(False): for gp in groups: print("----------------------------------------------------------------------------------------------------------------------") print(gp) #display(all_sorts2) ind=0 orientations2=orientations[orientations[c_l['g']]==gp] for code in codes: orientations3=orientations2[orientations2[c_l['c']]==code] ind2=int(fmod(ind,3)) if(len(orientations3)>0): print(code,"observations n=",len(orientations3)) #display(orientations2) if(len(orientations3)>0): if(ind2==0): fig, ax = mplstereonet.subplots(1,3,figsize=(15,15)) if(c_l['otype']=='dip direction'): strikes = orientations3[c_l['dd']].values -90 else: strikes = orientations3[c_l['dd']].values dips = orientations3[c_l['d']].values cax = ax[ind2].density_contourf(strikes, dips, measurement='poles') ax[ind2].pole(strikes, dips, markersize=5, color='w') ax[ind2].grid(True) #fig.colorbar(cax) text = ax[ind2].text(2.2, 1.37, code, color='b') # Fit a plane to the girdle of the distribution and display it. fit_strike, fit_dip = mplstereonet.fit_girdle(strikes, dips) print('strike/dip of girdle',fit_strike, '/', fit_dip) if(ind2==2): plt.show() ind=ind+1 if(ind>0 and not ind2==2): plt.show() return(group_girdle)
num_points = 200 real_bearing, real_plunge = 300, 5 s, d = mplstereonet.plunge_bearing2pole(real_plunge, real_bearing) lon, lat = mplstereonet.plane(s, d, segments=num_points) lon += np.random.normal(0, np.radians(15), lon.shape) lat += np.random.normal(0, np.radians(15), lat.shape) strike, dip = mplstereonet.geographic2pole(lon, lat) # Plot the raw data and contour it: fig, ax = mplstereonet.subplots() ax.density_contourf(strike, dip, cmap='gist_earth') ax.density_contour(strike, dip, colors='black') ax.pole(strike, dip, marker='.', color='black') # Fit a plane to the girdle of the distribution and display it. fit_strike, fit_dip = mplstereonet.fit_girdle(strike, dip) ax.plane(fit_strike, fit_dip, color='red', lw=2) ax.pole(fit_strike, fit_dip, marker='o', color='red', markersize=14) # Add some annotation of the result lon, lat = mplstereonet.pole(fit_strike, fit_dip) (plunge, ), (bearing, ) = mplstereonet.pole2plunge_bearing(fit_strike, fit_dip) template = u'P/B of Fold Axis\n{:02.0f}\u00b0/{:03.0f}\u00b0' ax.annotate(template.format(plunge, bearing), ha='center', va='bottom', xy=(lon, lat), xytext=(-50, 20), textcoords='offset points', arrowprops=dict(arrowstyle='-|>', facecolor='black'))
""" In this example two planes are plottet as great circles and poles. The planes are given as dip-direction/dip and converted to strike/dip. The strikes and dips are passed to the 'mplstereonet.fit_girdle()' function that calculates the best fitting plane for the poles of the planes. The resulting plane is the optimal cross-section plane for this structure. The pole of the resulting plane would correspond to the intersection-linear when looking at schistosities or the fold-axis when looking at fold-hinges. """ import matplotlib.pyplot as plt import numpy as np import mplstereonet fig, ax = mplstereonet.subplots() dip_directions = [100, 200] dips = [30, 40] strikes = np.array(dip_directions) - 90 ax.pole(strikes, dips, "bo") ax.plane(strikes, dips, color='black', lw=1) fit_strike, fit_dip = mplstereonet.fit_girdle(strikes, dips) ax.plane(fit_strike, fit_dip, color='red', lw=1) ax.pole(fit_strike, fit_dip, marker='o', color='red', markersize=5) plt.show()
strike, dip, rake = parse_angelier_data.load() # Plot the raw data and contour it: fig, ax = mplstereonet.subplots() 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.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, midx], [yp, midy] axial_s, axial_dip = mplstereonet.fit_girdle(x, y, measurement='radians')