Passed
Pull Request — main (#25)
by
unknown
02:24
created

mutis.correlation.Correlation.peak_find()   A

Complexity

Conditions 2

Size

Total Lines 26
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 16
dl 0
loc 26
rs 9.6
c 0
b 0
f 0
cc 2
nop 6
1
# Licensed under a 3-clause BSD style license - see LICENSE
2
"""Analysis of correlation of light curves."""
3
4
import logging
5
6
import matplotlib.pyplot as plt
0 ignored issues
show
introduced by
Unable to import 'matplotlib.pyplot'
Loading history...
7
import numpy as np
0 ignored issues
show
introduced by
Unable to import 'numpy'
Loading history...
8
import scipy as sp
0 ignored issues
show
introduced by
Unable to import 'scipy'
Loading history...
9
10
from mutis.lib.correlation import *
0 ignored issues
show
Unused Code introduced by
get_grid was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
ndcf was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
welsh_ab_p was imported with wildcard, but is not used.
Loading history...
Unused Code introduced by
kroedel_ab_p was imported with wildcard, but is not used.
Loading history...
Coding Style introduced by
The usage of wildcard imports like mutis.lib.correlation should generally be avoided.
Loading history...
11
12
__all__ = ["Correlation"]
13
14
log = logging.getLogger(__name__)
15
16
17
class Correlation:
0 ignored issues
show
best-practice introduced by
Too many instance attributes (21/7)
Loading history...
18
    """Analysis of the correlation of two signals.
19
20
    Parameters
21
    ----------
22
    signal1 : :class:`~mutis.signal.Signal`
23
        Values of the time axis.
24
    signal2 : :class:`~mutis.signal.Signal`
25
        Values of the signal axis.
26
    fcorr : :py:class:`~str`
27
        Method used to correlate the signals.
28
    """
29
30
    def __init__(self, signal1, signal2, fcorr):
31
        self.signal1 = signal1
32
        self.signal2 = signal2
33
        self.fcorr = fcorr
34
35
        self.times = np.array([])
36
        self.dts = np.array([])
37
        self.nb = np.array([])
0 ignored issues
show
Coding Style Naming introduced by
Attribute name "nb" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
38
        self.values = None
39
40
        # TODO: have a much smaller set of attributes
0 ignored issues
show
Coding Style introduced by
TODO and FIXME comments should generally be avoided.
Loading history...
41
        self.samples = None
42
        # storage of the significance limits of the correlation
43
        self.l1s = None
44
        self.l2s = None
45
        self.l3s = None
46
        # storage of the uncertainties of the correlation
47
        self.s1s = None
48
        self.s2s = None
49
        self.s3s = None
50
51
        # attributes indicating the ranges where the correlations are defined
52
        t1, t2 = self.signal1.times, self.signal2.times
0 ignored issues
show
Coding Style Naming introduced by
Variable name "t2" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
Coding Style Naming introduced by
Variable name "t1" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
53
        self.tmin_full = t2.min() - t1.max()
54
        self.tmax_full = t2.max() - t1.min()
55
        self.t0_full = (self.tmax_full + self.tmin_full) / 2
56
        self.tmin_same = -(np.max([t1.max() - t1.min(), t2.max() - t2.min()])) / 2 + self.t0_full
57
        self.tmax_same = (np.max([t1.max() - t1.min(), t2.max() - t2.min()])) / 2 + self.t0_full
58
        self.tmin_valid = (
59
            -(
60
                np.max([t1.max() - t1.min(), t2.max() - t2.min()])
61
                - np.min([t1.max() - t1.min(), t2.max() - t2.min()])
62
            )
63
            / 2
64
            + self.t0_full
65
        )
66
        self.tmax_valid = (
67
            +(
68
                np.max([t1.max() - t1.min(), t2.max() - t2.min()])
69
                - np.min([t1.max() - t1.min(), t2.max() - t2.min()])
70
            )
71
            / 2
72
            + self.t0_full
73
        )
74
75
76
    def peak_find(self, k=3, a=-0.1, b=0.1, n=5, ax=None):
0 ignored issues
show
Coding Style Naming introduced by
Argument name "ax" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
best-practice introduced by
Too many arguments (6/5)
Loading history...
Coding Style Naming introduced by
Argument name "n" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
Coding Style Naming introduced by
Argument name "b" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
Coding Style Naming introduced by
Argument name "a" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
Comprehensibility introduced by
This function exceeds the maximum number of variables (16/15).
Loading history...
Unused Code introduced by
The argument k seems to be unused.
Loading history...
77
        """Find the peak of the correlation
78
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
79
        """
80
        x, y = self.times, self.values
0 ignored issues
show
Coding Style Naming introduced by
Variable name "y" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
Coding Style Naming introduced by
Variable name "x" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
81
        t = np.linspace(a, b, n)
0 ignored issues
show
Coding Style Naming introduced by
Variable name "t" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
82
83
        spl = sp.interpolate.LSQUnivariateSpline(x, y, t, k=3)
84
85
        xs = np.linspace(min(x), max(x), 1000)
0 ignored issues
show
Coding Style Naming introduced by
Variable name "xs" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
86
        ys = spl(xs)
0 ignored issues
show
Coding Style Naming introduced by
Variable name "ys" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
87
               
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
88
        peak_idx = np.argmax(ys)
89
        peak_x = xs[peak_idx]
90
        peak_y = ys[peak_idx]
91
        
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
92
        if ax is None:
93
            print(f'Peak at {365*peak_x:.1f} days (C = {peak_y:.2f})')
94
            fig, ax = plt.subplots()
0 ignored issues
show
Unused Code introduced by
The variable fig seems to be unused.
Loading history...
95
            self.plot_corr()
96
            plt.xlim([-100/365,100/365])
0 ignored issues
show
Coding Style introduced by
Exactly one space required after comma
Loading history...
97
98
        plt.plot(xs, ys, 'k-')
99
        #plot_corr_set_axs()
100
101
        return {'x_peak':peak_x, 'y_peak':peak_y}
102
103
    def gen_synth(self, samples):
104
        """Generates the synthetic light curves.
105
106
        Generates the specified number `samples` of synthetic light
107
        curves for each signal, to be used to compute the significance
108
        the correlation.
109
110
        Parameters
111
        ----------
112
        samples : :py:class:`~int`
113
            Number of synthetic light curves to be generated for each signal.
114
        """
115
116
        self.samples = samples
117
        self.signal1.gen_synth(samples)
118
        self.signal2.gen_synth(samples)
119
120
    def gen_corr(self, uncert=True, dsamples=500):
121
        """Generates the correlation of the signals.
122
123
        Generates the correlation of the signals, and computes their
124
        confidence level from the synthetic light curves, which must
125
        have been generated before.
126
        """
127
128
        if uncert and self.signal1.dvalues is None:
129
            log.error(
130
                "uncert is True but no uncertainties for Signal 1 were specified, setting uncert to False"
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (106/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
131
            )
132
            uncert = False
133
        if uncert and self.signal2.dvalues is None:
134
            log.error(
135
                "uncert is True but no uncertainties for Signal 2 were specified, setting uncert to False"
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (106/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
136
            )
137
            uncert = False
138
139
        if len(self.times) == 0 or len(self.dts) == 0:
140
            raise Exception(
141
                "You need to define the times on which to calculate the correlation."
142
                "Please use gen_times() or manually set them."
143
            )
144
145
        # TODO: refactor if/elif with a helper function
0 ignored issues
show
Coding Style introduced by
TODO and FIXME comments should generally be avoided.
Loading history...
146
        mc_corr = np.empty((self.samples, self.times.size))
147
        if uncert:
148
            mc_sig = np.empty((dsamples, self.times.size))
149
150
        if self.fcorr == "welsh_ab":
151
            for idx in range(self.samples):
152
                mc_corr[idx] = welsh_ab(
153
                    self.signal1.times,
154
                    self.signal1.synth[idx],
155
                    self.signal2.times,
156
                    self.signal2.synth[idx],
157
                    self.times,
158
                    self.dts,
159
                )
160
            if uncert:
161
                for idx in range(dsamples):
162
                    mc_sig[idx] = welsh_ab(
163
                        self.signal1.times,
164
                        self.signal1.values
165
                        + self.signal1.dvalues * np.random.randn(self.signal1.values.size),
166
                        self.signal2.times,
167
                        self.signal2.values
168
                        + self.signal2.dvalues * np.random.randn(self.signal2.values.size),
169
                        self.times,
170
                        self.dts,
171
                    )
172
            self.values = welsh_ab(
173
                self.signal1.times,
174
                self.signal1.values,
175
                self.signal2.times,
176
                self.signal2.values,
177
                self.times,
178
                self.dts,
179
            )
180
        elif self.fcorr == "kroedel_ab":
181
            for idx in range(self.samples):
182
                mc_corr[idx] = kroedel_ab(
183
                    self.signal1.times,
184
                    self.signal1.synth[idx],
185
                    self.signal2.times,
186
                    self.signal2.synth[idx],
187
                    self.times,
188
                    self.dts,
189
                )
190
            if uncert:
191
                for idx in range(dsamples):
192
                    mc_sig[idx] = kroedel_ab(
193
                        self.signal1.times,
194
                        self.signal1.values
195
                        + self.signal1.dvalues * np.random.randn(self.signal1.values.size),
196
                        self.signal2.times,
197
                        self.signal2.values
198
                        + self.signal2.dvalues * np.random.randn(self.signal2.values.size),
199
                        self.times,
200
                        self.dts,
201
                    )
202
            self.values = kroedel_ab(
203
                self.signal1.times,
204
                self.signal1.values,
205
                self.signal2.times,
206
                self.signal2.values,
207
                self.times,
208
                self.dts,
209
            )
210
        elif self.fcorr == "numpy":
211
            for idx in range(self.samples):
212
                mc_corr[idx] = nindcf(
213
                    self.signal1.times,
214
                    self.signal1.synth[idx],
215
                    self.signal2.times,
216
                    self.signal2.synth[idx],
217
                )
218
            if uncert:
219
                for idx in range(dsamples):
220
                    mc_sig[idx] = nindcf(
221
                        self.signal1.times,
222
                        self.signal1.values
223
                        + self.signal1.dvalues * np.random.randn(self.signal1.values.size),
224
                        self.signal2.times,
225
                        self.signal2.values
226
                        + self.signal2.dvalues * np.random.randn(self.signal2.values.size),
227
                    )
228
            self.values = nindcf(
229
                self.signal1.times,
230
                self.signal1.values,
231
                self.signal2.times,
232
                self.signal2.values,
233
            )
234
        else:
235
            raise Exception("Unknown method " + self.fcorr + " for correlation.")
236
237
        self.l3s = np.percentile(mc_corr, [0.135, 99.865], axis=0)
238
        self.l2s = np.percentile(mc_corr, [2.28, 97.73], axis=0)
239
        self.l1s = np.percentile(mc_corr, [15.865, 84.135], axis=0)
240
241
        if uncert:
242
            self.s3s = np.percentile(mc_sig, [0.135, 99.865], axis=0)
0 ignored issues
show
introduced by
The variable mc_sig does not seem to be defined in case uncert on line 147 is False. Are you sure this can never be the case?
Loading history...
243
            self.s2s = np.percentile(mc_sig, [2.28, 97.73], axis=0)
244
            self.s1s = np.percentile(mc_sig, [15.865, 84.135], axis=0)
245
246
    def gen_times(self, ftimes="canopy", *args, **kwargs):
0 ignored issues
show
introduced by
Keyword argument before variable positional arguments list in the definition of gen_times function
Loading history...
247
        """Sets times and bins using the method defined by ftimes parameter.
248
249
        Parameters
250
        ----------
251
        ftimes : :py:class:`~str`
252
            Method used to bin the time interval of the correlation.
253
            Possible values are:
254
            - "canopy": Computes a binning as dense as possible, with
255
            variable bin width and (with a minimum and a maximum
256
            resolution) and a minimum statistic.
257
            - "rawab": Computes a binning with variable bin width,
258
            a given step, maximum bin size and a minimum statistic.
259
            - "uniform": Computes a binning with uniform bin width
260
            and a minimum statistic.
261
            - "numpy": Computes a binning suitable for method='numpy'.
262
        """
263
        if ftimes == "canopy":
264
            self.times, self.dts, self.nb = gen_times_canopy(
265
                self.signal1.times, self.signal2.times, *args, **kwargs
266
            )
267
        elif ftimes == "rawab":
268
            self.times, self.dts, self.nb = gen_times_rawab(
269
                self.signal1.times, self.signal2.times, *args, **kwargs
270
            )
271
        elif ftimes == "uniform":
272
            self.times, self.dts, self.nb = gen_times_uniform(
273
                self.signal1.times, self.signal2.times, *args, **kwargs
274
            )
275
        elif ftimes == "numpy":
276
            t1, t2 = self.signal1.times, self.signal1.times
0 ignored issues
show
Coding Style Naming introduced by
Variable name "t2" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
Coding Style Naming introduced by
Variable name "t1" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
277
            dt = np.max([(t1.max() - t1.min()) / t1.size, (t2.max() - t2.min()) / t2.size])
0 ignored issues
show
Coding Style Naming introduced by
Variable name "dt" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
278
            n1 = int(np.ptp(t1) / dt * 10.0)
0 ignored issues
show
Coding Style Naming introduced by
Variable name "n1" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
279
            n2 = int(np.ptp(t1) / dt * 10.0)
0 ignored issues
show
Coding Style Naming introduced by
Variable name "n2" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
280
            self.times = np.linspace(self.tmin_full, self.tmax_full, n1 + n2 - 1)
281
            self.dts = np.full(self.times.size, (self.tmax_full - self.tmin_full) / (n1 + n2))
282
        else:
283
            raise Exception("Unknown method " + ftimes + ", please indicate how to generate times.")
284
285
    def plot_corr(self, uncert=True, peak=False, ax=None, legend=False):
0 ignored issues
show
Coding Style Naming introduced by
Argument name "ax" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
286
        """Plots the correlation of the signals.
287
288
        Plots the correlation of the signal, and the confidence limits
289
        computed from the synthetic curves.
290
291
        Parameters
292
        ----------
293
        ax : :class:`matplotlib.axes.Axes`
294
            Axes to be used (default None, it creates a new axes).
295
        legend : :py:class:`~bool`
296
            Whether to add a legend indicating the confidence levels.
297
        """
298
299
        # TODO: develop a plotting object for plots
0 ignored issues
show
Coding Style introduced by
TODO and FIXME comments should generally be avoided.
Loading history...
300
        #       this will considerably shorten the
301
        #       number of attributes of this class
302
303
        if uncert and self.signal1.dvalues is None:
304
            log.error(
305
                "uncert is True but no uncertainties for Signal 1 were specified, setting uncert to False"
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (106/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
306
            )
307
            uncert = False
308
        if uncert and self.signal2.dvalues is None:
309
            log.error(
310
                "uncert is True but no uncertainties for Signal 2 were specified, setting uncert to False"
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (106/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
311
            )
312
            uncert = False
313
314
        # plt.figure()
315
        if ax is None:
316
            ax = plt.gca()
317
318
        ax.plot(self.times, self.l1s[0], "c-.")
319
        ax.plot(self.times, self.l1s[1], "c-.", label=r"$1\sigma$")
320
        ax.plot(self.times, self.l2s[0], "k--")
321
        ax.plot(self.times, self.l2s[1], "k--", label=r"$2\sigma$")
322
        ax.plot(self.times, self.l3s[0], "r-")
323
        ax.plot(self.times, self.l3s[1], "r-", label=r"$3\sigma$")
324
        ax.plot(self.times, self.values, "b.--", lw=1)
325
326
        # full limit
327
        ax.axvline(x=self.tmin_full, ymin=-1, ymax=+1, color="red", linewidth=4, alpha=0.5)
328
        ax.axvline(x=self.tmax_full, ymin=-1, ymax=+1, color="red", linewidth=4, alpha=0.5)
329
        # same limit
330
        ax.axvline(x=self.tmin_same, ymin=-1, ymax=+1, color="black", linewidth=2, alpha=0.5)
331
        ax.axvline(x=self.tmax_same, ymin=-1, ymax=+1, color="black", linewidth=2, alpha=0.5)
332
        # valid limit
333
        ax.axvline(x=self.tmin_valid, ymin=-1, ymax=+1, color="cyan", linewidth=1, alpha=0.5)
334
        ax.axvline(x=self.tmax_valid, ymin=-1, ymax=+1, color="cyan", linewidth=1, alpha=0.5)
335
336
        if uncert:
337
            ax.fill_between(x=self.times, y1=self.s1s[0], y2=self.s1s[1], color="b", alpha=0.5)
338
            ax.fill_between(x=self.times, y1=self.s2s[0], y2=self.s2s[1], color="b", alpha=0.3)
339
            ax.fill_between(x=self.times, y1=self.s3s[0], y2=self.s3s[1], color="b", alpha=0.1)
340
341
        if peak:
342
            peak_sp = self.peak_find(ax=ax)
343
            ax.annotate(f"Peak at ({365*peak_sp['x_peak']:.1f}, {peak_sp['y_peak']:.2f})", (peak_sp['x_peak'], peak_sp['y_peak']))
0 ignored issues
show
Coding Style introduced by
This line is too long as per the coding-style (130/100).

This check looks for lines that are too long. You can specify the maximum line length.

Loading history...
344
            
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
345
            
0 ignored issues
show
Coding Style introduced by
Trailing whitespace
Loading history...
346
        if legend:
347
            ax.legend()
348
349
        # plt.show()
350
        return ax
351
352
    def plot_times(self, rug=False):
353
        """Plots the time binning generated previously.
354
355
        Plots the number of total bins, their distribution and the
356
        number of points in each bin for the generated time binning,
357
        previously generated with Correlation().gen_times(...).
358
359
        Parameters
360
        ----------
361
        rug : :py:class:`~bool`
362
            Whether to make a rug plot just below the binning, to make
363
            it easier to visually understand the density and distribution
364
            of the generated bins.
365
366
        """
367
368
        # TODO: develop a plotting object for plots
0 ignored issues
show
Coding Style introduced by
TODO and FIXME comments should generally be avoided.
Loading history...
369
        #       this will considerably shorten the
370
        #       number of attributes of this class
371
372
        fig, ax = plt.subplots(nrows=2, ncols=1, sharex=True)
0 ignored issues
show
Coding Style Naming introduced by
Variable name "ax" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
373
        tab, dtab, nab = self.times, self.dts, self.nb
374
375
        fig.suptitle("Total bins: {:d}".format(self.times.size))
376
        ax[0].plot(tab, nab, "b.")
377
        ax[0].errorbar(x=tab, y=nab, xerr=dtab / 2, fmt="none")
378
        ax[0].set_ylabel("$n_i$")
379
        ax[0].grid()
380
        ax[0].axvline(x=self.tmin_full, ymin=-1, ymax=+1, color="red", linewidth=4, alpha=0.5)
381
        ax[0].axvline(x=self.tmax_full, ymin=-1, ymax=+1, color="red", linewidth=4, alpha=0.5)
382
        ax[0].axvline(x=self.tmin_same, ymin=-1, ymax=+1, color="black", linewidth=2, alpha=0.5)
383
        ax[0].axvline(x=self.tmax_same, ymin=-1, ymax=+1, color="black", linewidth=2, alpha=0.5)
384
        ax[0].axvline(x=self.tmin_valid, ymin=-1, ymax=+1, color="cyan", linewidth=1, alpha=0.5)
385
        ax[0].axvline(x=self.tmax_valid, ymin=-1, ymax=+1, color="cyan", linewidth=1, alpha=0.5)
386
        ax[1].plot(tab, dtab, "b.")
387
        ax[1].set_ylabel("$dt_i$")
388
        # ax[1].grid()
389
        ax[1].axvline(x=self.tmin_full, ymin=-1, ymax=+1, color="red", linewidth=4, alpha=0.5)
390
        ax[1].axvline(x=self.tmax_full, ymin=-1, ymax=+1, color="red", linewidth=4, alpha=0.5)
391
        ax[1].axvline(x=self.tmin_same, ymin=-1, ymax=+1, color="black", linewidth=2, alpha=0.5)
392
        ax[1].axvline(x=self.tmax_same, ymin=-1, ymax=+1, color="black", linewidth=2, alpha=0.5)
393
        ax[1].axvline(x=self.tmin_valid, ymin=-1, ymax=+1, color="cyan", linewidth=1, alpha=0.5)
394
        ax[1].axvline(x=self.tmax_valid, ymin=-1, ymax=+1, color="cyan", linewidth=1, alpha=0.5)
395
396
        if rug:
397
            for time in self.times:
398
                ax[1].axvline(x=time, ymin=0, ymax=0.2, color="black", linewidth=0.8, alpha=1.0)
399
            # ax[1].plot(self.t, ax[1].get_ylim()[0]+np.zeros(self.t.size), 'k|', alpha=0.8, lw=1)
400
401
        ax[1].grid()
402
        # fig.show()
403
404
    def plot_signals(self, ax=None):
0 ignored issues
show
Coding Style Naming introduced by
Argument name "ax" doesn't conform to snake_case naming style ('([^\\W\\dA-Z][^\\WA-Z]2,|_[^\\WA-Z]*|__[^\\WA-Z\\d_][^\\WA-Z]+__)$' pattern)

This check looks for invalid names for a range of different identifiers.

You can set regular expressions to which the identifiers must conform if the defaults do not match your requirements.

If your project includes a Pylint configuration file, the settings contained in that file take precedence.

To find out more about Pylint, please refer to their site.

Loading history...
405
        """Plots the signals involved in this correlation.
406
407
        Plots the signals involved in this correlation, in the same window
408
        but with different twin y-axes and different colors.
409
410
        Parameters
411
        ----------
412
        ax : :py:class:`~matplotlib.axes.Axes`
413
            Axes to be used for plotting.
414
        """
415
416
        # TODO: develop a plotting object for plots
0 ignored issues
show
Coding Style introduced by
TODO and FIXME comments should generally be avoided.
Loading history...
417
        #       this will considerably shorten the
418
        #       number of attributes of this class
419
420
        if ax is None:
421
            ax = plt.gca()
422
423
        ax.plot(self.signal1.times, self.signal1.values, "b.-", lw=1, alpha=0.4)
424
        ax.tick_params(axis="y", labelcolor="b")
425
        ax.set_ylabel("sig 1", color="b")
426
427
        ax2 = ax.twinx()
428
        ax2.plot(self.signal2.times, self.signal2.values, "r.-", lw=1, alpha=0.4)
429
        ax2.tick_params(axis="y", labelcolor="r")
430
        ax2.set_ylabel("sig 2", color="r")
431