Skip to content

Commit

Permalink
Merge pull request #933 from QuLogic/section-plot-updates
Browse files Browse the repository at this point in the history
Section plot updates
  • Loading branch information
mbyt committed Jan 25, 2015
2 parents 7e44f1d + e7a1624 commit d618861
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 36 deletions.
3 changes: 3 additions & 0 deletions obspy/core/stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -1076,6 +1076,9 @@ def plot(self, *args, **kwargs):
:type time_down: bool, optional
:param time_down: Flip the plot horizontally, time goes down.
Defaults to ``False``, i.e., time goes up.
:type reftime: :class:`~obspy.core.utcdatetime.UTCDateTime`, optional
:param reftime: The reference time to which the time scale will refer.
Defaults to the minimum start time of the visible traces.
**Relative Parameters**
Expand Down
Binary file modified obspy/imaging/tests/images/waveform_default_section.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 17 additions & 1 deletion obspy/imaging/tests/test_waveform.py
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,8 @@ def test_plotDefaultSection(self):
start = UTCDateTime(0)
st = Stream()
for _i in range(10):
st += self._createStream(start, start + 3600, 100)
this_start = start + 300 * np.sin(np.pi * _i / 9)
st += self._createStream(this_start, this_start + 3600, 100)
st[-1].stats.distance = _i * 10e3
# create and compare image
with ImageComparison(self.path, 'waveform_default_section.png') as ic:
Expand All @@ -296,6 +297,21 @@ def test_plotAzimSection(self):
st.plot(outfile=ic.name, type='section', dist_degree=True,
ev_coord=(0.0, 0.0))

def test_plotRefTimeSection(self):
"""
Tests plotting 10 in a section with alternate reference time
"""
start = UTCDateTime(0)
reftime = start + 600
st = Stream()
for _i in range(10):
this_start = start + 300 * np.sin(np.pi * _i / 9)
st += self._createStream(this_start, this_start + 3600, 100)
st[-1].stats.distance = _i * 10e3
# create and compare image
with ImageComparison(self.path, 'waveform_reftime_section.png') as ic:
st.plot(outfile=ic.name, type='section', reftime=reftime)

def test_plotDefaultRelative(self):
"""
Plots one hour, starting Jan 1970, with a relative scale.
Expand Down
60 changes: 25 additions & 35 deletions obspy/imaging/waveform.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,6 @@ def __init__(self, **kwargs):
self.sect_recordstart = kwargs.get('recordstart', None)
self.sect_recordlength = kwargs.get('recordlength', None)
self.sect_norm_method = kwargs.get('norm_method', 'trace')
self.sect_timeshift = kwargs.get('timeshift', False)
self.sect_user_scale = kwargs.get('scale', 1.0)
self.sect_vred = kwargs.get('vred', None)
# normalize times
Expand All @@ -108,6 +107,8 @@ def __init__(self, **kwargs):
# fix stream times
for tr in self.stream:
tr.stats.starttime = UTCDateTime(tr.stats.starttime - dt)
elif self.type == 'section':
self.sect_reftime = kwargs.get('reftime', None)
# Whether to use straight plotting or the fast minmax method. If not
# set explicitly by the user "full" method will be used by default and
# "fast" method will be used above some threshold of data points to
Expand Down Expand Up @@ -1157,7 +1158,7 @@ def plotSection(self, *args, **kwargs): # @UnusedVariable
ax.set_xticklabels(ticks)
ax.minorticks_on()
# Limit time axis
ax.set_ylim([0, self._time_max])
ax.set_ylim([self._time_min, self._time_max])
if self.sect_recordstart is not None:
ax.set_ylim(bottom=self.sect_recordstart)
if self.sect_recordlength is not None:
Expand Down Expand Up @@ -1185,18 +1186,18 @@ def __sectInitTraces(self):
if not self.sect_dist_degree:
# Define offset in km from tr.stats.distance
try:
for _tr in range(len(self.stream)):
self._tr_offsets[_tr] = self.stream[_tr].stats.distance
for _i, tr in enumerate(self.stream):
self._tr_offsets[_i] = tr.stats.distance
except:
msg = 'Define trace.stats.distance in meters to epicenter'
raise ValueError(msg)
else:
# Define offset as degree from epicenter
try:
for _tr in range(len(self.stream)):
self._tr_offsets[_tr] = locations2degrees(
self.stream[_tr].stats.coordinates.latitude,
self.stream[_tr].stats.coordinates.longitude,
for _i, tr in enumerate(self.stream):
self._tr_offsets[_i] = locations2degrees(
tr.stats.coordinates.latitude,
tr.stats.coordinates.longitude,
self.ev_coord[0], self.ev_coord[1])
except:
msg = 'Define latitude/longitude in trace.stats.' + \
Expand All @@ -1213,12 +1214,10 @@ def __sectInitTraces(self):
else:
self._offset_max = self.sect_offset_max
# Reduce data to indexes within offset_min/max
self._tr_selected = np.where(
(self._tr_offsets >= self._offset_min) &
(self._tr_offsets <= self._offset_max))[0]
self._tr_offsets = self._tr_offsets[
(self._tr_offsets >= self._offset_min) &
(self._tr_offsets <= self._offset_max)]
mask = ((self._tr_offsets >= self._offset_min) &
(self._tr_offsets <= self._offset_max))
self._tr_offsets = self._tr_offsets[mask]
stream = [tr for m, tr in zip(mask, self.stream) if m]
# Normalized offsets for plotting
self._tr_offsets_norm = self._tr_offsets / self._tr_offsets.max()
# Number of traces
Expand All @@ -1231,26 +1230,21 @@ def __sectInitTraces(self):
self._tr_npts = np.empty(self._tr_num)
self._tr_delta = np.empty(self._tr_num)
# TODO dynamic DATA_MAXLENGTH according to dpi
for _i, _tr in enumerate(self._tr_selected):
if len(self.stream[_tr].data) >= self.max_npts:
tmp_data = signal.resample(self.stream[_tr].data,
self.max_npts)
for _i, tr in enumerate(stream):
if len(tr.data) >= self.max_npts:
tmp_data = signal.resample(tr.data, self.max_npts)
else:
tmp_data = self.stream[_tr].data
tmp_data = tr.data
# Initialising trace stats
self._tr_data.append(tmp_data)
self._tr_starttimes.append(self.stream[_tr].stats.starttime)
self._tr_starttimes.append(tr.stats.starttime)
self._tr_max_count[_i] = tmp_data.max()
self._tr_npts[_i] = tmp_data.size
self._tr_delta[_i] = (
self.stream[_tr].stats.endtime -
self.stream[_tr].stats.starttime) / self._tr_npts[_i]
# Maximum global count of the traces
self._tr_max_count_glob = np.abs(self._tr_max_count).max()
tr.stats.endtime -
tr.stats.starttime) / self._tr_npts[_i]
# Init time vectors
self.__sectInitTime()
# Traces initiated!
self._traces_init = True

def __sectScaleTraces(self, scale=None):
"""
Expand All @@ -1265,16 +1259,14 @@ def __sectInitTime(self):
"""
Define the time vector for each trace
"""
reftime = self.sect_reftime or min(self._tr_starttimes)
self._tr_times = []
for _tr in range(self._tr_num):
self._tr_times.append(
np.arange(self._tr_npts[_tr]) * self._tr_delta[_tr])
(np.arange(self._tr_npts[_tr]) +
(self._tr_starttimes[_tr] - reftime)) * self._tr_delta[_tr])
if self.sect_vred:
self._tr_times[-1] -= self._tr_offsets[_tr] / self.sect_vred
if self.sect_timeshift:
self._tr_times[-1] += \
(self._tr_starttimes[_tr] - min(self._tr_starttimes))\
* self._tr_delta[_tr]

self._time_min = np.concatenate(self._tr_times).min()
self._time_max = np.concatenate(self._tr_times).max()
Expand Down Expand Up @@ -1309,7 +1301,6 @@ def __sectInitPlot(self):
* (1. / self._sect_scale)
+ self._tr_offsets_norm[_tr],
self._tr_times[_tr])
self._sect_plot_init = True
return ax

def __sectNormalizeTraces(self):
Expand All @@ -1323,14 +1314,13 @@ def __sectNormalizeTraces(self):
self._tr_normfac[tr] = np.abs(self._tr_data[tr]).max()
elif self.sect_norm_method == 'stream':
# Normalize the whole stream
self._tr_normfac.fill(self._tr_max_count_glob)
tr_max_count_glob = np.abs(self._tr_max_count).max()
self._tr_normfac.fill(tr_max_count_glob)
else:
msg = 'Define a normalisation method. Valid normalisations' + \
'are \'trace\', \'stream\'. See documentation.'
raise ValueError(msg)

self._plot_init = False

def __setupFigure(self):
"""
The design and look of the whole plot to be produced.
Expand Down

0 comments on commit d618861

Please sign in to comment.