import numpy as np

from ipywidgets import Layout, HTML, VBox
import bqplot.pyplot as plt

"""
Explanation: Linking Plots Using Fast Interval Selector
Details on how to use the fast interval selector can be found in this notebook. In this tutorial notebook, we will look at linking plots using the fast interval selector. Interval selectors are ideally suited for time series analysis where we want to perform statistical computations on different time periods.
When creating an interval selector we need pass in the x scale. We can additionally pass in the marks on which the interval selector operates. When the interval selector moves, it updates the following traits (on which callbacks can be registered)
* selected trait of the interval selector object itself. This trait contains the start and end of the x axis obtained from the x scale. Note that these values may not be present in the x attribute of the marks!
* selected trait of the marks on which the selector operates. This trait contains all the indices of the line.x which are spanned by the interval selector.
The recipe for linking plots is as follows:

Create an interval selector object by passing in the X-scale and marks on which the selector should operate on (optional)
Pass it to the figure through the interaction argument
Register a callback (which potentially updates other plots) on either the selected attribute of the interval selector object or selected attribute of the marks objects in the figure

<br>FastIntervalSelector updates the selected trait continuously. Therefore, registering computationally intensive callbacks is not recommended with FastIntervalSelector
Let's now look at an example of linking a time series plot to a scatter plot using a FastIntervalSelector
End of explanation
"""


from bqplot.interacts import FastIntervalSelector

y1, y2 = np.random.randn(2, 200).cumsum(axis=1)  # two simple random walks

fig_layout = Layout(width="900px", height="500px")
time_series_fig = plt.figure(layout=fig_layout)
line = plt.plot([y1, y2])

# create a fast interval selector by passing in the X scale and the line mark on which the selector operates
intsel = FastIntervalSelector(marks=[line], scale=line.scales["x"])
time_series_fig.interaction = intsel  # set the interval selector on the figure

"""
Explanation: Let's set up an interval selector on a figure containing two time series plots. The interval selector can be activated by clicking on the figure
End of explanation
"""


scat_fig = plt.figure(
    layout=fig_layout,
    title="Scatter of time series slice selected by the interval selector",
)
# set the x and y attributes to the y values of line.y
scat = plt.scatter(*line.y, colors=["red"], stroke="black")

# define a callback for the interval selector
def update_scatter(*args):
    # get the start and end indices of the interval
    start_ix, end_ix = line.selected[0], line.selected[-1]

    # update the x and y attributes of the scatter by slicing line.y
    with scat.hold_sync():
        scat.x, scat.y = line.y[:, start_ix:end_ix]


# register the callback with line.selected trait
line.observe(update_scatter, "selected")

help_label = HTML(
    '<div style="color: blue; font-size: 16px; margin:20px 0px 0px 50px">\
                  Click on the time series plot to activate the interval selector</div>'
)
VBox([help_label, time_series_fig, scat_fig])

"""
Explanation: Let's now create a scatter plot of the two time series and stack it below the time series plot using a VBox
End of explanation
"""


