-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwiggle.py
135 lines (106 loc) · 3.56 KB
/
wiggle.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
import numpy as np
import matplotlib.pyplot as plt
def insert_zeros(trace, tt=None):
'''
Insert zero locations in data trace and tt vector based on linear fit
'''
if tt is None:
tt = np.arange(len(trace))
# Find zeros
zc_idx = np.where(np.diff(np.signbit(trace)))[0]
x1 = tt[zc_idx]
x2 = tt[zc_idx + 1]
y1 = trace[zc_idx]
y2 = trace[zc_idx + 1]
a = (y2 - y1) / (x2 - x1)
tt_zero = x1 - y1 / a
# split tt and trace
tt_split = np.split(tt, zc_idx + 1)
trace_split = np.split(trace, zc_idx + 1)
tt_zi = tt_split[0]
trace_zi = trace_split[0]
# insert zeros in tt and trace
for i in range(len(tt_zero)):
tt_zi = np.hstack(
(tt_zi, np.array([tt_zero[i]]), tt_split[i + 1]))
trace_zi = np.hstack(
(trace_zi, np.zeros(1), trace_split[i + 1]))
return trace_zi, tt_zi
def wiggle_input_check(data, tt, xx):
'''
Helper function for wiggle() and traces() to check input
'''
# Input check for data
if type(data).__module__ != np.__name__:
raise TypeError("data must be a numpy array")
if len(data.shape) != 2:
raise ValueError("data must be a 2D array")
# Input check for tt
if tt is None:
tt = np.arange(data.shape[0])
else:
if type(tt).__module__ != np.__name__:
raise TypeError("tt must be a numpy array")
if len(tt.shape) != 1:
raise ValueError("tt must be a 1D array")
if tt.shape[0] != data.shape[0]:
raise ValueError("tt must have same as data's rows")
# Input check for xx
if xx is None:
xx = np.arange(data.shape[1])
else:
if type(xx).__module__ != np.__name__:
raise TypeError("tt must be a numpy array")
if len(xx.shape) != 1:
raise ValueError("tt must be a 1D array")
if tt.shape[0] != data.shape[0]:
raise ValueError("tt must have same as data's rows")
# Compute min trace horizontal spacing
ts = np.min(np.diff(xx))
# Rescale data
# data_new = np.zeros((data.shape[0],data.shape[1]))
# data_new_std = np.zeros((data.shape[1]))
# for i in range (0,data.shape[1]):
# data_new_std[i] = np.std(data[:,i], axis=0)
# for j in range (0,data.shape[0]):
# data_new[j,:] = data[j,:] / data_new_std
# data = data_new
return data, tt, xx, ts
def wiggle(data, tt=None, xx=None, color='k'):
'''
Wiggle plot of a seismic data section.
Use the column major order for array as in Fortran to optimal performance.
The following color abbreviations are supported:
========== ========
character color
========== ========
'b' blue
'g' green
'r' red
'c' cyan
'm' magenta
'y' yellow
'k' black
'w' white
========== ========
'''
# Input check
data, tt, xx, ts = wiggle_input_check(data, tt, xx)
# Plot data using matplotlib.pyplot
Ntr = data.shape[1]
ax = plt.gca()
for ntr in range(Ntr):
trace = data[:, ntr]
offset = xx[ntr]
trace_zi, tt_zi = insert_zeros(trace, tt)
ax.fill_betweenx(tt_zi, offset, trace_zi + offset,
where=trace_zi >= 0,
facecolor=color)
ax.plot(trace_zi + offset, tt_zi, color)
ax.set_xlim(xx[0] - ts, xx[-1] + ts)
ax.set_ylim(tt[0], tt[-1])
ax.invert_yaxis()
if __name__ == '__main__':
data = np.random.randn(1000, 100)
wiggle(data)
plt.show()