Example #1
0
def set_up_widgets(p, source, source1, source2, source3, df, text_dsn, table):
    dsn = text_dsn.value
    # Set up widgets
    text_title = TextInput(title="Title:", value="{} Data".format(dsn))
    text_save = TextInput(title="Save As:", value=dsn)

    max_for_dsn = df.row_timestamp.max()
    min_day, max_day = day_limits(table)
    calendar = DatePicker(title="Day:",
                          value=date(max_for_dsn.year, max_for_dsn.month,
                                     max_for_dsn.day + 1),
                          max_date=date(max_day.year, max_day.month,
                                        max_day.day + 1),
                          min_date=date(min_day.year, min_day.month,
                                        min_day.day + 1))
    button = Button(label="Update", button_type="success")

    # Set up callbacks
    def update_title(attrname, old, new):
        p.title.text = text_title.value

    def update_save(attrname, old, new):
        p.tools[0].save_name = text_save.value

    def update():
        text_dsn.value = text_dsn.value.strip(" ")  # Get rid of extra space
        # Make sure time is valid
        date_start = "{} 00:00:00".format(calendar.value)
        date_end = "{} 23:59:59".format(calendar.value)

        df_new = update_data(p,
                             text_title,
                             text_save,
                             source,
                             source1,
                             source2,
                             source3,
                             text_dsn.value,
                             table,
                             dates=[date_start, date_end])
        # if df_new is going to be used, make sure it's not empty:
        # if df_new is empty...

        # day = df_new.row_timestamp.max()
        # min_day = df_new.row_timestamp.min()
        # calendar.value = date(day.year, day.month, day.day+1)
        # calendar.max_date = date(day.year, day.month, day.day+1)
        # calendar.min_date = date(min_day.year, min_day.month,min_day.day+1)

    text_title.on_change('value', update_title)
    text_save.on_change('value', update_save)

    button.on_click(update)
    button.js_on_click(CustomJS(args=dict(p=p), code="""p.reset.emit()"""))

    # Set up layouts and add to document
    inputs = widgetbox(text_title, text_save, calendar, button)

    curdoc().add_root(row(inputs, p, width=1300))
Example #2
0
def init():
    output_notebook()
    display(Javascript(_init_js))
    but = '<img src="resources/show.png" width="34" height="25" style="display: inline" alt="Slideshow button" title="Enter/Exit RISE Slideshow">'
    txt = Div(text='<h2>You can now start the slideshow!</h3>' +
                   f'<h3 style="margin: 0.5em 0;">Just click the RISE slideshow button above - the one that looks like: {but}<br/>' +
                   '(or you can press alt+R on your keyboard instead if you prefer).</h3>')
    clearbutton = Button(label="Clear")
    clearbutton.js_on_click(CustomJS(code='primes_clear();'))
    cleartext = Paragraph(text='Clear all plots and outputs (e.g. before restarting slideshow).')
    increm = Toggle(label='Incremental', active=True)
    increm.js_on_click(CustomJS(code='primes_incremental(cb_obj.active)'))
    incremtext = Paragraph(text='Update timing plots incrementally (disable for static slide show).')
    repeats = Slider(start=1, end=10, value=3)
    repeats.js_on_change('value', CustomJS(code='primes_repeats(cb_obj.value)'))
    repeatstext = Paragraph(text='Repeats for timing measurements (higher is more accurate, but slower).')
    controls = layout([[clearbutton, cleartext],
                       [increm, incremtext],
                       [repeats, repeatstext]])
    show(column(txt, controls, sizing_mode='stretch_width'))
Example #3
0
from bokeh.plotting import show
from bokeh.layouts import column
from bokeh.models import CustomJS
from bokeh.models.widgets import Button
from fontawesome_icon import FontAwesomeIcon

btn = Button(icon=FontAwesomeIcon(icon_name="thumbs-o-up", size=2),
             label="It works!")
btn.js_on_click(CustomJS(code="alert('It works!')"))

show(column(btn))
class signalHandler:
    def __init__(self,
                 signalFilename="",
                 lyricsFilename="",
                 signal=[],
                 sampleRate=0,
                 color="red"):
        self.path = os.getcwd()

        logger.logData(source="Signal handler",
                       priority="INFO",
                       msgType="Setup start",
                       msgData=())

        self.setupVariables()

        self.color = color
        self.setupMapper()
        self.setupColorBar()

        self.lyricsImported = 0
        if lyricsFilename:
            self.setupLyricTable(lyricsFilename)
            self.lyricsImported = 1

        self.setupPlotWindow()
        self.setupControls()
        self.setupGUI()

        if signalFilename:
            self.importFile(signalFilename)

        if len(signal):
            self.addSignal(signal, sampleRate)

        logger.logData(source="Signal handler",
                       priority="INFO",
                       msgType="Setup done",
                       msgData=((self.signalImported)))

    def setupGUI(self):
        """Wraps the plot, slider, and tool column into one layout"""

        audioCol = column(self.p,
                          self.colorBar,
                          self.timeWindowSlider,
                          height=self.figureHeight)
        # dtgCol = column(self.dtg.gui,width=400)
        if self.lyricsImported:
            # self.gui = self.lyricTable
            self.gui = row(self.lyricsGui,
                           audioCol,
                           self.controls,
                           height=self.figureHeight - 110)
        else:
            self.gui = row(audioCol,
                           self.controls,
                           height=self.figureHeight - 110)

    def setupVariables(self):
        """sets up important variables to the tool, including
			figure size
			dummy variables to use before file import
			tool options - loop, button sizes, button delay
		"""

        try:
            self.masterPath = os.getcwd()  #use when running from Sublime
            os.listdir(self.masterPath)

        except:
            self.masterPath = os.path.join("soundTools",
                                           "")  #use when running from Bokeh
            os.listdir(self.masterPath)

        self.subtitlePath = os.path.join(self.masterPath, "lyrics")
        self.audioPath = os.path.join(self.masterPath, "audio")
        self.webpagePath = os.path.join(self.masterPath, "webpages")

        self.figureWidth = 1000
        self.figureHeight = 500

        self.buttonWidth = 200
        self.buttonHeight = 15
        self.numXTicks = 4
        self.soundPlaying = 0
        self.signalImported = 0
        self.lastChunkIndex = 0

        self.strideMultiplier = 100

        self.sweepStartSample = 0
        self.sweepEndSample = 10
        self.activeChannels = []
        self.yRange = (-1, 1)
        self.channelAnchorYs = np.arange(0, self.yRange[1], 2)

        self.plotStyle = 0
        self.glyphsSetup = 0
        self.loop = 0
        self.plotMode = 0

        self.outputFilename = "output"
        self.updateDelay = 12  #delay period in milliseconds befwen timeline update while playing the active signal
        self.windowChunkLength = 10  #seconds

    def showGui(self):
        output_file(os.path.join("webpages", "signalHandler.html"))

        logger.logData(source="Signal handler",
                       priority="INFO",
                       msgType="Show",
                       msgData=())

        show(self.gui)
        curdoc().add_root(self.gui)

    def addSignal(self, signalIn, sampleRate):
        """Adds a prexisting list/mutliDim ndarray  (with known sample rate) as the active signal and updates plot"""

        #keep the original in case of a reset
        self.originalSignal = signalIn

        #signal gets changed on update of time slider
        self.signal = self.originalSignal
        #activeSignal gets changed on update of of signal AND update of active channels
        self.activeSignal = self.signal

        self.sampleRate = sampleRate
        self.signalImported = 1

        logger.logData(source="Signal handler",
                       priority="INFO",
                       msgType="Signal add",
                       msgData=())

        self.analyzeSignal()

    def importFile(self, filename):
        """imports a wav file into the tool and updates the plot and tools"""

        #check to make sure the filename is valid
        try:
            self.sampleRate, self.originalSignal = wavfile.read(
                os.path.join(
                    self.audioPath,
                    filename))  #keep the original for master reference
        except:
            logger.logData(source="Signal handler",
                           priority="WARN",
                           msgType="Import file fail",
                           msgData=(filename))
            return
        #update tool's internal filename
        self.filename = filename
        #import the wav file
        self.signal = self.originalSignal
        self.activeSignal = self.signal
        self.signalImported = 1

        logger.logData(source="Signal handler",
                       priority="INFO",
                       msgType="Import file",
                       msgData=(filename))

        #get relevant signal info and update plot
        self.analyzeSignal()

    def analyzeSignal(self):
        """Parses the metadata from the active signal and updates plot and tools"""

        self.glyphsSetup = 0
        #get number of channels of signal
        try:
            self.numChannels = self.signal.shape[1]
        except:
            #if it's single channel its imported as a list, make it a 1D ndarray
            self.numChannels = 1
            self.signal = np.transpose(np.array([self.signal]))

        self.activeChannels = list(range(self.numChannels))
        self.channelButtons.labels = list(map(str, self.activeChannels))

        self.channelButtons.active = self.activeChannels

        if not np.any(self.signal):

            logger.logData(source="Signal handler",
                           priority="WARN",
                           msgType="Empty",
                           msgData=())

            return

        self.numSamples = len(self.signal)
        self.sampleIndices = range(self.numSamples)
        self.messedUpTs = self.sampleIndices

        self.updateMapperHigh(self.numSamples)
        self.updateColorBar(self.sampleIndices)

        self.signalDuration = self.numSamples / float(self.sampleRate)
        self.windowChunks = int(
            (self.signalDuration / self.windowChunkLength)) + 1

        #update the time slider with the imported signal's duration
        self.timeWindowSlider.end = self.signalDuration
        self.timeWindowSlider.value = [0, self.signalDuration]

        self.sweepStartSample = 0
        self.sweepEndSample = self.numSamples

        #setup the ticker to replace indices with timestamps
        self.setMasterXAxisTicker()

        #PLOT SCATTER PARAMS
        #get max amplitude of signal to adjust y range and channel spacing
        self.sigPeak = np.amax(self.signal)
        self.yRange = (0, 2 * self.numChannels * self.sigPeak)

        #generate offsets to space multiple channels out in the y axis
        self.channelAnchorYs = np.arange(self.sigPeak, self.yRange[1],
                                         2 * self.sigPeak)

        logger.logData(source="Signal handler",
                       priority="INFO",
                       msgType="Analyze",
                       msgData=(round(self.signalDuration,
                                      3), self.numChannels, self.numSamples,
                                self.sampleRate))

        self.drawActivePlot()
        # self.drawFullSignal()

    def setMasterXAxisTicker(self):
        #ticker dictionary to rpaplce x axis index ticks with their coirrosponding timestamps
        self.masterTicker = list(
            range(0, self.numSamples, int(self.numSamples / self.numXTicks)))
        self.masterXAxisOverrideDict = {}

        timeLabels = np.linspace(0, self.signalDuration, self.numXTicks)
        for sampleInd, timeLabel in zip(self.masterTicker, timeLabels):
            self.masterXAxisOverrideDict[sampleInd] = str(round(timeLabel, 3))

        #set up the size and duration of the sub-chunks displayed while the signal is playing
        self.samplesPerChunk = int(self.numSamples / self.windowChunks)

        self.chunkDuration = self.samplesPerChunk / float(self.sampleRate)
        #the absolute index values comprising the x axis ticks
        self.chunkTicker = list(
            range(0, self.samplesPerChunk,
                  int(self.samplesPerChunk / self.numXTicks)))

        # self.chunkLabels = np.linspace(0,self.chunkDuration,10)
        # self.chunkTickOverride = {}
        # for sampleInd,timeLabel in zip(self.chunkTicker,self.chunkLabels):
        # 	self.chunkTickOverride[sampleInd] = str(round(timeLabel,3))

    def fileCallback(self, attr, old, new):
        """Callback assigned to choosing a file from the file browser"""

        filename = new['file_name'][0]
        self.importFile(filename)

    def fileButtonSetup(self):
        """Creates a "File opener" button and assigns a javascript callback to it that opens an os-independent file picker window
		imports chosen file into the class"""
        fileSource = ColumnDataSource({'file_name': []})

        self.fileImportButton.callback = CustomJS(
            args=dict(file_source=fileSource),
            code="""
		function read_file(filename) {
		    var reader = new FileReader();
		    reader.onload = load_handler;
		    reader.onerror = error_handler;
		    // readAsDataURL represents the file's data as a base64 encoded string
		    reader.readAsDataURL(filename);
		}

		function load_handler(event) {
		    file_source.data = {'file_name':[input.files[0].name]};
		    file_source.trigger("change");
		}

		function error_handler(evt) {
		    if(evt.target.error.name == "NotReadableError") {
		        alert("Can't read file!");
		    }
		}

		var input = document.createElement('input');
		input.setAttribute('type', 'file');
		input.onchange = function(){
		    if (window.FileReader) {
		        read_file(input.files[0]);
		    } else {
		        alert('FileReader is not supported in this browser');
		    }
		}
		input.click();
		""")

        fileSource.on_change('data', self.fileCallback)

    def setupControls(self):
        """Called on setup, creates buttons and sliders to:
			open a local audio file
			set loop mode
			update the active timespan
			play the active timespan
			set filename to save active signal to
			save active signal to that filename
		"""

        #check boxes to choose what plots to display
        self.plotModeButtons = RadioButtonGroup(
            labels=["Wav", "FFT", "Spectrogram"],
            active=self.plotMode,
            button_type="warning",
            width=self.buttonWidth,
            height=self.buttonHeight)
        self.plotModeButtons.on_change("active", self.plotModeCallback)

        #choose betwen line or scatter plot
        self.plotStyleButtons = RadioButtonGroup(labels=["Line", "Scatter"],
                                                 active=0,
                                                 button_type="danger",
                                                 width=self.buttonWidth,
                                                 height=self.buttonHeight)
        self.plotStyleButtons.on_change("active", self.plotStyleCallback)

        channelTitle = Div(text="""<b>Audio Channels:</b>""",
                           width=self.buttonWidth,
                           height=2)
        self.channelButtons = CheckboxButtonGroup(labels=["-"],
                                                  active=[0],
                                                  button_type="primary",
                                                  width=self.buttonWidth,
                                                  height=self.buttonHeight)
        self.channelButtonRow = column(channelTitle,
                                       self.channelButtons,
                                       width=self.buttonWidth,
                                       height=self.buttonHeight * 2)
        self.channelButtons.on_change("active", self.channelButtonCallback)

        #creates a filebutton and assigns it a callback linked to a broser-based file browser
        self.fileImportButton = Button(label="Import File",
                                       button_type="success",
                                       width=self.buttonWidth,
                                       height=self.buttonHeight)
        self.fileButtonSetup()

        #create a loop toggle button and assigns a callback to it
        self.loopAudioToggle = Toggle(label="Loop",
                                      button_type="success",
                                      width=self.buttonWidth,
                                      height=self.buttonHeight)
        self.loopAudioToggle.on_click(self.loopAudioCallback)

        #double ended slider to clip audio by time
        self.timeWindowSlider = RangeSlider(start=0,
                                            end=1,
                                            value=[0, 1],
                                            step=.05,
                                            title="Wav File Window",
                                            width=self.figureWidth,
                                            height=self.buttonHeight)
        self.timeWindowSlider.on_change("value", self.timeSliderCallback)

        #button to commit clip changes to active signal
        self.updateButton = Button(label="Update",
                                   button_type="success",
                                   width=self.buttonWidth,
                                   height=self.buttonHeight)
        self.updateButton.on_click(self.updateButtonCallback)

        #button to play active signal,
        self.playButton = Button(label="Play",
                                 button_type="success",
                                 width=self.buttonWidth,
                                 height=self.buttonHeight)
        self.playButton.on_click(self.playSound)

        self.filenameBox = TextInput(value="output",
                                     title="Output Filename:",
                                     width=self.buttonWidth)

        #button to write active signal to file
        self.writeFileButton = Button(label="Write Active File",
                                      button_type="success",
                                      width=self.buttonWidth,
                                      height=self.buttonHeight)
        self.writeFileButton.on_click(self.writeFileButtonCallback)

        #button to reset tool to state right after signal import
        self.resetButton = Button(label="Reset",
                                  button_type="success",
                                  width=self.buttonWidth,
                                  height=self.buttonHeight)
        self.resetButton.on_click(self.resetButtonCallback)

        self.resetZoomButton = Button(label="Reset Zoom",
                                      button_type="success",
                                      width=self.buttonWidth,
                                      height=self.buttonHeight)
        self.resetZoomButton.js_on_click(
            CustomJS(args=dict(p=self.p), code="""
    		p.reset.emit()
			"""))

        self.generalControlsColumn = column(self.plotModeButtons,
                                            self.plotStyleButtons,
                                            self.filenameBox,
                                            self.channelButtonRow,
                                            width=self.buttonWidth)

        self.buttonColumn = column(
            self.resetZoomButton,
            self.fileImportButton,
            self.updateButton,
            self.loopAudioToggle,
            self.playButton,
            self.writeFileButton,
            self.resetButton,
            width=self.buttonWidth)  #,height=self.figureHeight)

        self.controls = row(self.generalControlsColumn, self.buttonColumn)
        #wrap buttons and text box in a column of fixed width
        # self.buttonColumn = column(self.plotModeButtons,self.plotStyleButtons,self.channelButtonRow,self.resetZoomButton,self.fileImportButton,self.updateButton,self.loopToggle,self.playButton,self.writeFileButton,self.resetButton,self.filenameBox,width=self.buttonWidth)#,height=self.figureHeight)

    #choose active channels
    def channelButtonCallback(self, attr, old, new):
        if not self.signalImported: return

        try:
            self.activeChannels = new
            self.activeSignal = self.signal[:, self.activeChannels]
            self.glyphsSetup = 0
            self.drawActivePlot()

            logger.logData(source="Signal handler",
                           priority="INFO",
                           msgType="Channel update",
                           msgData=((old, new)))

        except:
            logger.logData(source="Signal handler",
                           priority="WARN",
                           msgType="Channel fail",
                           msgData=(old))

            return

        #choose between line or scatter plot
    def plotStyleCallback(self, attr, old, new):
        self.plotStyle = new
        self.glyphsSetup = 0

        # self.drawFullSignal()
        self.drawActivePlot()

    def plotModeCallback(self, att, old, new):
        self.plotMode = new
        self.drawActivePlot()

    def loopAudioCallback(self, event):
        """Called on toggling of the loop button,
			binary inverts previous loop val"""

        self.loop = 1 - self.loop

    def writeFileButtonCallback(self):
        """Called on click of the write Fiile button
		Writes the active signal to the filename set by the textbox"""
        outputFilename = self.filenameBox.value + ".wav"
        outputPath = os.path.join(self.path, "audio", outputFilename)

        numChannels = len(self.activeChannels)

        logger.logData(source="Signal handler",
                       priority="INFO",
                       msgType="Write",
                       msgData=(outputFilename, numChannels, self.sampleRate,
                                self.signalDuration))

        wavfile.write(outputPath, self.sampleRate, self.activeSignal)

    # def resetZoomCallback(self):
    # 	print(1)

    def resetButtonCallback(self):
        """Returns the tool to state it was immediately after file was imported"""

        #if no signal is imported, do nothing
        if not self.signalImported: return

        #reset active to signal to the original, unclipped signal
        self.signal = self.originalSignal

        logger.logData(source="Signal handler",
                       priority="INFO",
                       msgType="Reset",
                       msgData=())

        #return variables and plot to original state
        self.analyzeSignal()

    def updateButtonCallback(self):
        """Called on press of the update button,
			clips the signsal by the estart and end trimes decreed by the time slider,
			resets the plot to like the clipped signal is the new full signal"""

        #if no signal is imported, do nothing
        if not self.signalImported:
            logger.logData(source="Signal handler",
                           priority="WARN",
                           msgType="Update failed",
                           msgData=())

            return

        #clip all channel samples corresponding to the times on slider
        self.signal = self.signal[self.sweepStartSample:self.sweepEndSample, :]

        logger.logData(source="Signal handler",
                       priority="INFO",
                       msgType="Update signal",
                       msgData=())

        #update variables and plot with clipped signal
        self.analyzeSignal()

    def timeSliderCallback(self, attr, old, new):
        """Called on update of the time slider
			moves the sweep start/end lines used for clipping the signal when the update button is pressed"""

        if not self.signalImported:
            return

        try:
            #convert the start and end times to integer sample numbers and update internal locations
            self.sweepStartSample = int(new[0] * self.sampleRate)
            self.sweepEndSample = int(new[1] * self.sampleRate)

            #update sweep line graphics
            startLine = self.p.select_one({'name': 'sweepStartLine'})
            startLine.data_source.data = {
                'x': [self.sweepStartSample, self.sweepStartSample],
                'y': self.yRange
            }

            endLine = self.p.select_one({'name': 'sweepEndLine'})
            endLine.data_source.data = {
                'x': [self.sweepEndSample, self.sweepEndSample],
                'y': self.yRange
            }
        except:
            return

    def shiftSamples(self, channelIndex):
        """Element wise adds to the channel's vector to offset a channel so it can vbe plotted alongside other channels"""

        channelSamples = self.signal[:, channelIndex]

        reducedSamples = channelSamples[::self.strideMultiplier]
        return reducedSamples + self.channelAnchorYs[channelIndex]

    def setupPlotWindow(self):
        """Creates a window containing the channel plots"""

        p = figure(height=300,
                   width=self.figureWidth,
                   x_range=(0, 1),
                   y_range=(0, 1),
                   tools="box_zoom",
                   toolbar_location=None,
                   output_backend="webgl")
        # p.toolbar.active_scroll = "auto"
        p.yaxis.visible = False
        p.grid.visible = False
        self.p = p

    def updateFigureForSpectrogram(self):
        self.p.x_range.end = self.numSamples
        self.p.y_range.end = self.yRange[1]

        self.p.xaxis.ticker = self.masterTicker
        self.p.xaxis.major_label_overrides = self.masterXAxisOverrideDict

    def plotSpectrogram(self):
        """Plots a log spectrogram of the active audio, returns figure object"""

        #max freq represetnedf (nyquist constrained)
        imgHeight = self.sampleRate / 2

        self.p.y_range.end = imgHeight * self.numChannels

        imgWidth = self.signalDuration
        self.p.x_range.end = imgWidth

        for channelNum in self.activeChannels:
            channelSignal = self.signal[:, channelNum]

            freqs, times, data = self.log_specgram(channelSignal,
                                                   self.sampleRate)

            self.p.image(image=[data],
                         x=0,
                         y=imgHeight * channelNum,
                         dw=imgWidth,
                         dh=imgHeight,
                         palette="Spectral11")

    def log_specgram(self,
                     audio,
                     sampleRate,
                     window_size=20,
                     step_size=10,
                     eps=1e-10):
        """Kraggin log spectrogram useful for MFCC analysis"""

        nperseg = int(round(window_size * sampleRate / 1e3))
        noverlap = int(round(step_size * sampleRate / 1e3))
        freqs, times, spec = spectrogram(audio,
                                         fs=sampleRate,
                                         window='hann',
                                         nperseg=nperseg,
                                         noverlap=noverlap,
                                         detrend=False)
        return freqs, times, np.log(spec.T.astype(np.float32) + eps)

    def setupPlotScatterGlyphs(self):
        self.p.line([self.sweepStartSample, self.sweepStartSample],
                    self.yRange,
                    color="blue",
                    line_width=2,
                    name="sweepStartLine")
        self.p.line([self.sweepEndSample, self.sweepEndSample],
                    self.yRange,
                    color="blue",
                    line_width=2,
                    name="sweepEndLine")

        self.p.line([0, 0],
                    self.yRange,
                    color='red',
                    line_width=2,
                    name='timeLine')

        # self.scatterSource = {"x":[],"place":[]}

        self.scatterSources = []
        for channelNum in self.activeChannels:
            self.scatterSources.append(
                ColumnDataSource({
                    "x": list(self.sampleIndices),
                    "y": list(self.sampleIndices),
                    "place": self.messedUpTs
                }))
            # self.p.scatter(x=[],y=[],radius=.1, fill_color={'field':"place",'transform': self.mapper},name="audioLine" + str(channelNum))
            self.p.scatter(x="x",
                           y="y",
                           radius=1,
                           source=self.scatterSources[channelNum],
                           fill_color={
                               'field': "place",
                               'transform': self.mapper
                           },
                           line_color={
                               'field': "place",
                               'transform': self.mapper
                           },
                           name="audioLine" + str(channelNum))

    def setupLinePlotGlyphs(self):
        self.p.line([self.sweepStartSample, self.sweepStartSample],
                    self.yRange,
                    color="blue",
                    line_width=2,
                    name="sweepStartLine")
        self.p.line([self.sweepEndSample, self.sweepEndSample],
                    self.yRange,
                    color="blue",
                    line_width=2,
                    name="sweepEndLine")

        self.p.line([0, 0],
                    self.yRange,
                    color='red',
                    line_width=2,
                    name='timeLine')
        for channelNum in self.activeChannels:
            self.p.line(x=[],
                        y=[],
                        line_width=.3,
                        color=self.color,
                        name="audioLine" + str(channelNum))

    def drawActivePlot(self):
        if not self.signalImported: return

        if self.plotMode == 0:
            self.drawFullSignal()
        elif self.plotMode == 1:
            self.getFFT()
        else:
            self.plotSpectrogram()

    def drawFullSignal(self):
        if self.glyphsSetup == 0:
            self.p.renderers = []

            if self.plotStyle:
                self.setupPlotScatterGlyphs()
            else:
                self.setupLinePlotGlyphs()

            self.glyphsSetup = 1
        """redraws each channel of the full plot and updates the xaxis to the full signal duration"""
        for channelNum in self.activeChannels:

            shiftedSamples = self.shiftSamples(channelNum)

            reducedSampleIndices = self.sampleIndices[::self.strideMultiplier]

            if self.plotStyle:
                self.scatterSources[channelNum].data = {
                    'x': reducedSampleIndices,
                    'y': list(shiftedSamples),
                    "place": reducedSampleIndices
                }
            else:
                channelLine = self.p.select_one(
                    {'name': 'audioLine' + str(channelNum)})
                channelLine.data_source.data = {
                    'x': reducedSampleIndices,
                    'y': shiftedSamples,
                    "place": reducedSampleIndices
                }
        #update x axis with full timespan
        self.p.x_range.end = self.numSamples
        self.p.y_range.end = self.yRange[1]

        self.p.xaxis.ticker = self.masterTicker
        self.p.xaxis.major_label_overrides = self.masterXAxisOverrideDict

    def playSound(self):
        """Starts playing the signal, and draws a sweeping vertical line on actively updating sub-samples of the audfio"""

        #if the "Play" button is pushed during play, it acts as a stop button
        if self.soundPlaying == 1:
            logger.logData(source="Signal handler",
                           priority="INFO",
                           msgType="Pause",
                           msgData=())

            self.stopAudio()
            return

        #if no signal is imported, do nothing
        if not self.signalImported: return

        #hide sweep lines until their chunk occurs
        startLine = self.p.select_one({'name': 'sweepStartLine'})
        startLine.visible = False

        endLine = self.p.select_one({'name': 'sweepEndLine'})
        endLine.visible = False

        ##Chunk-specific sweep lines
        self.startLineAdded = 0
        self.endLineAdded = 0

        #precompute which chunk the sweep lines are in for speed
        self.sweepStartChunk = int(
            np.floor(self.sweepStartSample / (self.samplesPerChunk + 1)))
        self.sweepEndChunk = int(
            np.floor(self.sweepEndSample / (self.samplesPerChunk + 1)))

        #precompute their indices in their chunk
        self.shiftedSweepStart = self.sweepStartSample - self.sweepStartChunk * self.samplesPerChunk
        self.shiftedSweepEnd = self.sweepEndSample - self.sweepEndChunk * self.samplesPerChunk

        if self.p.select_one({'name': 'sweepEndLineChunk'}) == None:
            #preadd the lines for speed
            self.p.line([self.shiftedSweepStart, self.shiftedSweepStart],
                        self.yRange,
                        color="blue",
                        line_width=2,
                        visible=False,
                        name="sweepStartLineChunk")
            self.p.line([self.shiftedSweepEnd, self.shiftedSweepEnd],
                        self.yRange,
                        color="blue",
                        line_width=2,
                        visible=False,
                        name="sweepEndLineChunk")

        #update the x axis with the sub-chunk values
        self.p.x_range.end = self.samplesPerChunk
        self.p.xaxis.ticker = self.chunkTicker
        self.p.xaxis.major_label_overrides = self.createChunkXAxisOverrideDict(
            0)

        #set the play button to read "Pause" to pull double duty
        self.playButton.label = "Pause"

        logger.logData(source="Signal handler",
                       priority="INFO",
                       msgType="Play",
                       msgData=())

        #log start time to keep track of where the time line should be
        self.startTime = time.time()

        #start playing the sound
        try:
            sd.play(self.activeSignal,
                    self.sampleRate,
                    loop=self.loop,
                    blocking=False)
        except:
            logger.logData(source="Signal handler",
                           priority="CRIT",
                           msgType="Play failed",
                           msgData=())
            self.playButton.label = "Play"
            return
        self.soundPlaying = 1

        #add a call callback to trigger periodcially and update the timeline and sub-samples
        self.perCallback = curdoc().add_periodic_callback(
            self.update, self.updateDelay)

    def createChunkXAxisOverrideDict(self, chunkIndex):
        """	creates a dictionary replacing absolute index ticks on the x axis with their corrosponding times
		"""
        #get the time labels corrosponding to this chunk
        chunkTimeLabels = np.linspace(self.chunkDuration * chunkIndex,
                                      self.chunkDuration * (chunkIndex + 1),
                                      self.numXTicks)

        chunkTickOverride = {}
        for sampleInd, timeLabel in zip(self.chunkTicker, chunkTimeLabels):
            #replace each sample index x tick with the time label
            chunkTickOverride[sampleInd] = str(round(timeLabel, 3))
        return chunkTickOverride

    def update(self):
        """Set to be called periodically when audio is playing to draw the active time line on the audio signal"""

        if self.loop:
            #mod the time played by total signal duration to keep the time line accurate for multiple plays
            deltaTime = (
                time.time() - self.startTime
            ) % self.signalDuration  #get time elapsed since the file started playing
        else:
            deltaTime = time.time(
            ) - self.startTime  #get time elapsed since the file started playing

        #if signal not done playing
        if deltaTime < self.signalDuration:
            #number of samples elapsed
            dSamples = deltaTime * self.sampleRate

            #get the active chunk
            chunkIndex = int(self.windowChunks * (dSamples / self.numSamples))

            #if the chunk is different, need to update the audio plot window to the next chunk
            if self.lastChunkIndex != chunkIndex:
                #get the starting and ending sample indices for the next chunk
                chunkStartIndex = self.samplesPerChunk * chunkIndex
                chunkEndIndex = self.samplesPerChunk * (chunkIndex + 1)

                #check if any of the sweep lines lie in this chunk
                if self.startLineAdded:
                    self.p.select_one({
                        'name': 'sweepStartLineChunk'
                    }).visible = False
                    self.startLineAdded = 0

                if chunkIndex == self.sweepStartChunk:
                    self.p.select_one({
                        'name': 'sweepStartLineChunk'
                    }).visible = True
                    self.startLineAdded = 1

                if self.endLineAdded:
                    self.p.select_one({
                        'name': 'sweepEndLineChunk'
                    }).visible = False
                    self.endLineAdded = 0

                if chunkIndex == self.sweepEndChunk:
                    self.p.select_one({
                        'name': 'sweepEndLineChunk'
                    }).visible = True
                    self.endLineAdded = 1

                #get the signal samples from this chunk and downsample them and shift them by channel
                reducedChunkSamps = self.signal[
                    chunkStartIndex:chunkEndIndex:self.
                    strideMultiplier] + self.channelAnchorYs

                reducedPlaces = list(
                    range(chunkStartIndex, chunkEndIndex,
                          self.strideMultiplier))
                #original
                # chunkSamps = self.signal[chunkStartIndex:chunkEndIndex]
                # shiftedChunkSamps = chunkSamps + self.channelAnchorYs

                reducedSampleIndices = list(
                    range(0, self.samplesPerChunk, self.strideMultiplier))

                #update plot for each channel
                for channelIndex in self.activeChannels:
                    if self.plotMode == 0:
                        audioLine = self.p.select_one(
                            {'name': "audioLine" + str(channelIndex)})
                        audioLine.data_source.data = {
                            'x': reducedSampleIndices,
                            'y': reducedChunkSamps[:, channelIndex],
                            "place": reducedPlaces
                        }

                        # audioLine.data_source.data = {'x': reducedSampleIndices, 'y': shiftedChunkSamps[:,channelIndex],"place":reducedPlaces}
                    else:
                        self.scatterSources[channelIndex].data = {
                            "x": reducedSampleIndices,
                            "y": self.sampleIndices,
                            "place": self.messedUpTs
                        }

                #update the x-axis ticks with the new times
                self.p.xaxis.major_label_overrides = self.createChunkXAxisOverrideDict(
                    chunkIndex)

                #update chunk index with new one
                self.lastChunkIndex = chunkIndex

            ##time line update
            #get the glyph for the time line
            timeLine = self.p.select_one({'name': 'timeLine'})

            #sample index of the timeline is total samples elapsed less the number of samples in all previous chunks
            timeLineIndex = dSamples - chunkIndex * self.samplesPerChunk

            #update the time line with the new times
            timeLine.data_source.data = {
                'x': [timeLineIndex, timeLineIndex],
                'y': self.yRange
            }

        #signal IS done playing
        else:
            if self.loop:
                return
            else:
                self.stopAudio()

    def stopAudio(self):
        """Stops the audio playing, returns the plot to state before audio started playing"""
        #stop the updating of the time line
        curdoc().remove_periodic_callback(self.perCallback)

        #stop playing the signal
        sd.stop()
        self.soundPlaying = 0

        #change play button back to play from pause
        self.playButton.label = "Play"

        logger.logData(source="Signal handler",
                       priority="INFO",
                       msgType="Play done",
                       msgData=())

        #restore plot to full signal
        self.drawActivePlot()

        #redraw sweep lines on the full signal plot
        startLine = self.p.select_one({'name': 'sweepStartLine'})
        startLine.visible = True

        endLine = self.p.select_one({'name': 'sweepEndLine'})
        endLine.visible = True

        #return time line to t=0
        timeLine = self.p.select_one({'name': 'timeLine'})
        timeLine.data_source.data["x"] = [0, 0]

    def setupMapper(self):
        self.mapper = LinearColorMapper(palette="Inferno256", low=0, high=10)

    def updateMapperPalette(self, newColors):
        self.mapper.palette = newColors

    def updateMapperHigh(self, newHigh):
        self.mapper.high = newHigh

    def updateColorBar(self, times):
        colorBarPlot = self.gui.select_one({'name': 'colorBarPlot'})
        colorBarPlot.x_range.end = self.numSamples
        colorBar = self.gui.select_one({'name': 'colorBar'})

        self.messedUpTs = times
        self.colorSource.data = {
            "x": self.sampleIndices,
            "place": self.messedUpTs
        }

        # if self.plotMode == 1:
        # 	for channelInd in self.activeChannels:
        # 		self.scatterSources[channelIndex].data = {"x":self.sampleIndices,"y":self.sampleIndices,"place":self.messedUpTs}

    def setupColorBar(self):
        colorTimeline = figure(height=30,
                               y_range=(-.5, .5),
                               width=self.figureWidth,
                               x_range=(0, 10),
                               toolbar_location=None,
                               output_backend="webgl",
                               name="colorBarPlot",
                               tools="")

        colorTimeline.axis.visible = False
        colorTimeline.grid.visible = False

        # colorTimeline.image(image=range(self.numSamples),x=0,y=.5,dh=1,dw=1,fill_color={'field':"x",'transform': self.mappers[colorBarType-1]},
        #        name="cbar" + str(colorBarType))

        self.colorSource = ColumnDataSource({
            "x": range(10),
            "place": range(10)
        })

        # colorTimeline.rect(x="x", y=0, width=1, height=1,fill_color={'field':"place",'transform': self.mapper},name="colorBar",
        #        line_width=0.0,line_color= None,line_alpha = 0.0,source=colorSource
        #        )

        colorBar = Rect(x="x",
                        y=0,
                        width=1,
                        height=1,
                        fill_color={
                            'field': "place",
                            'transform': self.mapper
                        },
                        name="colorBar",
                        line_width=0.0,
                        line_color=None,
                        line_alpha=0.0)

        colorTimeline.add_glyph(self.colorSource, colorBar)

        self.colorBar = colorTimeline

    def getFFT(self):
        """Plots the fast fourier transform of the active audio, returns a figure object"""
        fftHeight = self.numChannels
        self.p.y_range.end = fftHeight

        maxFreq = self.sampleRate / 2
        self.p.x_range.end = maxFreq

        for channelNum in self.activeChannels:
            sigPadded = self.signal[:, channelNum]

            # Determine frequencies
            f = np.fft.fftfreq(self.numSamples) * self.sampleRate

            #pull out only positive frequencies (upper half)
            upperHalf = int(len(f) / 2)
            fHalf = f[:upperHalf]

            # Compute power spectral density
            psd = np.abs(np.fft.fft(sigPadded))**2 / self.numSamples

            #pull out only power densities for the positive frequencies
            psdHalf = psd[:upperHalf]

            #nromalize y vals
            psdHalf = psdHalf / max(psdHalf)

            #shift them to allow multiple channels
            psdHalf += channelNum

            self.p.line(fHalf, psdHalf)

    def lyricModeCallback(self, event):
        self.lyricMode = 1 - self.lyricMode

        if self.lyricMode:
            self.lyricsHandler.lyricModeButton.label = "Change to start lyric"
        else:
            self.lyricsHandler.lyricModeButton.label = "Change to end lyric"

    def dataTableCallback(self, att, old, new):
        if not self.activeChannels:
            logger.logData(source="Signal handler",
                           priority="WARN",
                           msgType="Lyric empty",
                           msgData=())
            return

        selectionIndex = self.lyricsHandler.lyricTableHandler.source.selected.indices[
            0]

        timestamp = self.lyricsHandler.lyricTableHandler.source.data[
            "timestamps"][selectionIndex]
        lyricText = self.lyricsHandler.lyricTableHandler.source.data["lyrics"][
            selectionIndex]

        timestampSeconds = timestamp.seconds
        lyricSample = int(timestampSeconds * self.sampleRate)

        if self.lyricMode == 0:
            #update sweep line graphics
            self.sweepStartSample = lyricSample
            startLine = self.p.select_one({'name': 'sweepStartLine'})
            startLine.data_source.data = {
                'x': [lyricSample, lyricSample],
                'y': self.yRange
            }

            logger.logData(source="Lyrics",
                           priority="INFO",
                           msgType="Start lyric",
                           msgData=(timestamp, lyricText))

        else:
            self.sweepEndSample = lyricSample
            endLine = self.p.select_one({'name': 'sweepEndLine'})
            endLine.data_source.data = {
                'x': [lyricSample, lyricSample],
                'y': self.yRange
            }
            logger.logData(source="Lyrics",
                           priority="INFO",
                           msgType="End lyric",
                           msgData=(timestamp, lyricText))

    def setupLyricTable(self, lyricsFilename):
        lyricsPath = os.path.join(self.path, "lyrics", lyricsFilename)
        self.lyricsHandler = lyricsHandler(lyricsPath)

        self.lyricMode = 0

        self.lyricsHandler.lyricTableHandler.source.selected.on_change(
            'indices', self.dataTableCallback)
        #create a loop toggle button and assigns a callback to it
        self.lyricsHandler.lyricModeButton.on_click(self.lyricModeCallback)

        self.lyricsGui = self.lyricsHandler.gui
Example #5
0
    
    //addresses IE
    if(navigator.msSaveBlob){
        navigator.msSaveBlob(blob, filename);
    }
    else{
        const link = document.createElement('a');
        link.href = URL.createObjectURL(blob);
        link.download = filename;
        link.target = '_blank';
        link.style.visibility = 'hidden';
        link.dispatchEvent(new MouseEvent('click'));
    }
""")
"""Callback Assignments"""
Connect.js_on_click(callback_status)
Save.js_on_click(callback_Save)


def update():
    s = slice(10)
    new_x = source.data['time'][s] + np.random.uniform(-0.1, 0.1, size=10)
    new_y = source.data['raw_data'][s] + np.random.uniform(-1, 1, size=10)
    source.patch({'time': [(s, new_x)], 'raw_data': [(s, new_y)]})


#-----------#
#    GUI    #
#-----------#
"""Front End"""
Comm_Panel = row(Port_input, Comm_Status_Message)
Example #6
0
                    mut_bohr[i] =  computeBohrParameter(mut_R, mut_ep_r, c[i],
                                                        mut_ka, mut_ki, mut_ep_ai,
                                                        mut_n);
                    var ref_bohr = computeBohrParameter(ref_R, ref_ep_r, c[i],
                                                        ref_ka, ref_ki, ref_ep_ai,
                                                        ref_n);
                    source.data['ref_bohr'][i] = ref_bohr;
                    mut_delta_bohr[i] = mut_bohr[i] - ref_bohr;
                }
                source.change.emit();
                """)

# Define the buttons
ref_reset = Button(label='reset reference to default', callback=reset_ref)
mut_reset = Button(label='reset mutant to reference', callback=reset_mut)
ref_reset.js_on_click(callback)
mut_reset.js_on_click(callback)

# Assemble controls
ref_controls = [
    ref_reset, ref_R_slider, ref_epRA_slider, ref_ka_slider, ref_ki_slider,
    ref_epAI_slider, ref_n_slider
]
mut_controls = [
    mut_reset, mut_R_slider, mut_epRA_slider, mut_ka_slider, mut_ki_slider,
    mut_epAI_slider, mut_n_slider
]

for rc, mc in zip(ref_controls[1:], mut_controls[1:]):
    rc.callback = callback
    mc.callback = callback
        j for j, sent in enumerate(source_sentences.data['sentence'])
        if sent == sentence
    ]
    source_sentences.selected.indices = ind


text_input.on_change('value', update_sentences)

###################################################
# ADD RESET BUTTON
###################################################

reset_button = Button(label='ALL WORDS', button_type='primary')
reset_button.js_on_click(
    CustomJS(args=dict(source=source_words_visible, words=source_words, p=p),
             code="""
    p.reset.emit()
    source.data = words.data
"""))

###################################################
# CREATION OF THE LAYOUT
###################################################

window = row(
    p,
    column(row(widgetbox(text_input),
               column(Div(text="", height=9), reset_button)),
           p_w,
           width=600))

curdoc().title = 'Interligua Visualization'
    data['dates'] = newdatedata['x']
    
    source.change.emit();
    
    
    reviews.text = newtextdata[q][0];
    
""")

#for (var i = 0; i < x.length; i++) {
#        y[i] = newy[i]
#    }


#query.js_on_change('value', callback)
update_plots_button.js_on_click(callback)





def update_app(attrname, old, new):
    
    app_name = app_select.value
    unique_dates = unique_dates_dict[app_name]
    
    #just to reset the slider
    date_range.start = unique_dates[0]
    date_range.end = unique_dates[-1]
    date_range.value = (unique_dates[0], unique_dates[-1])
    
Example #9
0
                      value=today)
end_date.on_change('value', refresh_plot)
end_hour = select = Select(title='hour', value="23", options=hours, width=70)
end_minute = select = Select(title='min',
                             value="59",
                             options=minutes,
                             width=70)
end_hour.on_change('value', refresh_plot)
end_minute.on_change('value', refresh_plot)

## live button
live_button = Button(width=130,
                     margin=[15, 10, 15, 10],
                     label="live",
                     button_type="default")
live_button.js_on_click(CustomJS(code=""" window.location.href='./live'; """))

## force update_data()
history_button = Button(width=130,
                        margin=[15, 10, 15, 10],
                        label="history",
                        button_type="primary")
history_button.on_click(plot_data)

tz_text = Paragraph(text=f"timezone: {timezone}", width=340)

controls = column(row(live_button, history_button), instrum_select,
                  row(start_date, start_hour, start_minute),
                  row(end_date, end_hour, end_minute), tz_text)

# plot
Example #10
0
    for _ in range(num_edges):
        vertices = sample(graph.vertices.keys(), 2)
        # TODO check if edge already exists
        graph.add_edge(vertices[0], vertices[1])

    bokeh_graph = BokehGraph(graph, draw_components=draw_components)
    bokeh_graph.show()


if __name__ == '__main__':
    if len(argv) == 4:
        NUM_VERTICES = int(argv[1])
        NUM_EDGES = int(argv[2])
        DRAW_COMPONENTS = bool(int(argv[3]))
        main(NUM_VERTICES, NUM_EDGES, DRAW_COMPONENTS)
    else:
        print('Expected arguments: num_vertices num_edges draw_components')
        print('Both numbers should be integers, draw_components should be 0/1')

rando_button = Button(label='Randomize', button_type='success')
show(widgetbox(rando_button))

source = ColumnDataSource(data=bokeh_graph.vertices)

callback = CustomJS(args=dict(source=source),
                    code="""
          console.log('clicked')
        """)

rando_button.js_on_click(callback)
Example #11
0
file_source_populations.on_change('data', file_callback_populations)

file_source_patient.on_change('data', file_callback_pat)

file_source_clinical.on_change('data', file_callback_clinical)

# upload tree files
menu_tree = [("Upload cluster coordinates", "coordinates"), ("Upload graph edges", "edges")]
tree_dropdown = Dropdown(label="Upload tree structure", button_type="warning", menu=menu_tree,
                         css_classes=['dropdowns'])
tree_dropdown.callback = CustomJS(args=dict(file_source=file_source_tree),
                                  code=open(join(dirname(__file__), "static/js/upload.js")).read())

# upload patients data
upload_patients = Button(label="upload patients data")
upload_patients.js_on_click(CustomJS(args=dict(file_source=file_source_patient),
                                     code=open(join(dirname(__file__), "static/js/upload_multiple.js")).read()))

# upload population list
upload_populations = Button(label="upload population list")
upload_populations.js_on_click(CustomJS(args=dict(file_source=file_source_populations),
                                        code=open(join(dirname(__file__), "static/js/upload.js")).read()))

# select patient
patient = Select(title='Patient', value='None', options=['None'] + df_viz.columns.tolist())

patient.on_change('value', select_patient)

# interaction with the plot
x = Select(title='X-Axis', value='x', options=df_viz.columns.tolist())
y = Select(title='Y-Axis', value='y', options=df_viz.columns.tolist())
size = Select(title='Size', value='None', options=['None'] + df_viz.columns.tolist())
Example #12
0
observe_segment.on_click(segment_func)

cluster_select_data = OD
cluster_select_table_Columns = [
    TableColumn(field=Ci, title=Ci) for Ci in cluster_select_data.columns
]
cluster_select_table_source = ColumnDataSource(
    cluster_select_data.round(decimals=2))
cluster_select_table = DataTable(columns=cluster_select_table_Columns,
                                 source=cluster_select_table_source,
                                 width=table_width,
                                 height=table_height)

download_button = Button(label="Download", button_type="success")
download_button.js_on_click(
    CustomJS(args=dict(source=cluster_select_table_source),
             code=open(join(dirname(__file__), "download.js")).read()))

cluster_select_panel = Panel(child=column(
    row(cluster_select_table, width=table_width, height=table_height),
    download_button),
                             title='Cluster Table')
"""


END OF SEGMNENTATION


"""

#Data Description and Selected Data panel
Example #13
0
    source.data = dict(url=[url])


file_input = FileInput(accept=".jpeg")
file_input.on_change('value', upload_data)

########################################################################

btn4 = Button(label="Download Image", button_type="success")
btn4.js_on_click(
    CustomJS(args=dict(source=source),
             code="""
        var data = source.data;
        value1=data['url'];
        var file = new Blob([value1], {type: 'image/jpeg'});
        var elem = window.document.createElement('output');
        elem.href = window.URL.createObjectURL(file);
        elem.download = 'downloaded_image.jpeg';
        document.body.appendChild(elem);
        elem.click();
        document.body.removeChild(elem);
        """))

doc = curdoc()
doc.add_root(
    row(column(file_input, p),
        column(btn1, gsmooth, btn2, threshold, btn3, btn4)))
curdoc.title = "Image Processing Demo"

#bokeh serve server_folder --show
Example #14
0
def explore_tab(df):
    def get_dataset(src, name, words, start, end):
        df = src[src.user == name].copy()
        mask = (df['timestamp'] > start) & (df['timestamp'] <= end)
        df = df[mask]
        words = [str(i) for i in words.split()]
        safe_words = []
        for word in words:
            word = re.escape(word)
            word = "(?=.*{})".format(word)
            safe_words.append(word)

        df = df[df['texts'].str.contains(''.join(safe_words))]

        source = ColumnDataSource(data=dict())

        cols = ['texts', 'displaySource', 'source']
        df[cols] = df[cols].replace({',': '', ',,': '', ';': ''}, regex=True)

        source.data = {
            # 'index': df.index,
            'impressionTime': df.impressionTime,
            'impressionOrder': df.impressionOrder,
            'source': df.source,
            'fblinktype': df.fblinktype,
            'texts': df.texts,
            'textsize': df.textsize,
            'publicationTime': df.publicationTime,
            'permaLink': df.permaLink,
            'nature': df.nature,
            'ANGRY': df.ANGRY,
            'HAHA': df.HAHA,
            'LIKE': df.LIKE,
            'LOVE': df.LOVE,
            'SAD': df.SAD,
            'WOW': df.WOW,
            'displaySource': df.displaySource,
            'id': df.id,
            'timestamp': df.timestamp,
            # 'images': df.images,
            # 'opengraph': df.opengraph,
            'postId': df.postId,
            # 'semanticCount': df.semanticCount,
            # 'semanticId': df.semanticId,
            'sourceLink': df.sourceLink,
            'timeline': df.timeline,
            'user': df.user,
            # 'videoautoplay': df.videoautoplay
        }
        return source

    def make_table(source):
        # Columns of tablem
        table_columns = [
            TableColumn(field='impressionTime', title='Time'),
            TableColumn(field='impressionOrder', title='Order'),
            TableColumn(field='source', title='Source'),
            TableColumn(field='fblinktype', title='Type'),
            TableColumn(field='texts', title='Text'),
            TableColumn(field='textsize', title='Text Size'),
            TableColumn(field='publicationTime', title='Publication Time'),
            TableColumn(field='permaLink', title='Link'),
            TableColumn(field='nature', title='Nature'),
            TableColumn(field='ANGRY', title='Angry'),
            TableColumn(field='HAHA', title='Haha'),
            TableColumn(field='LIKE', title='Like'),
            TableColumn(field='LOVE', title='Love'),
            TableColumn(field='SAD', title='Sad'),
            TableColumn(field='WOW', title='Wow')
        ]
        user_table = DataTable(source=source,
                               columns=table_columns,
                               width=1400)
        return user_table

    def update(attrname, old, new):
        name = name_select.value
        text_filter = text_input.value
        start = date_slider.value[0]
        end = date_slider.value[1]
        src = get_dataset(df, name, text_filter, start, end)
        source.data.update(src.data)

    name = df.user.iloc[0]
    words = ''
    names = df.user.unique()
    start = df.timestamp.min()
    end = df.timestamp.max()

    name_select = Select(value=name, title='User', options=sorted(names))
    text_input = TextInput(value="", title="Filter text:")
    date_slider = DateRangeSlider(title="Date Range: ",
                                  start=df.timestamp.min(),
                                  end=date.today(),
                                  value=(df.timestamp.min(), date.today()),
                                  step=1,
                                  callback_policy='mouseup')

    button = Button(label="Download", button_type="success")

    source = get_dataset(df, name, words, start, end)

    table = make_table(source)

    name_select.on_change('value', update)
    text_input.on_change('value', update)
    date_slider.on_change('value', update)

    button.js_on_click(
        CustomJS(args=dict(source=source),
                 code=open(join(dirname(__file__), "download.js")).read()))

    controls = column(name_select, date_slider, text_input, button)
    tab = Panel(child=row(table, controls), title='Explore')
    return tab
Example #15
0
def load_page(plate):
    '''
    Load new page
    '''
    global well_id 
    well_id = (0, 0)
    
    global sample 
    sample = plate[well_id]
    
    # Button to upload local file
    global file_source
    file_source = ColumnDataSource(data=dict(file_contents = [], file_name = []))
    file_source.on_change('data', file_callback)
    try:
        output_file_name = file_source.data['file_name'] + '-out.csv'
    except:
        output_filename = 'output.csv'
    global upload_button
    upload_button = Button(label="Upload local file", button_type="success", width=200, height=30)
    upload_button.js_on_click(CustomJS(args=dict(file_source=file_source),
                               code=open(join(dirname(__file__), "upload.js")).read()))
    
    # Text boxes for setting fit parameters
    global bottom_set_text
    bottom_set_text = TextInput(value='', title="Set initial value for Fmin", width=200, height=50)
    bottom_set_text.on_change('value', parameter_set_callback)

    global top_set_text
    top_set_text = TextInput(value='', title="Set initial value for Fmax", width=200, height=50)
    top_set_text.on_change('value', parameter_set_callback)
    
    global slope_set_text
    slope_set_text = TextInput(value='', title="Set initial value for a", width=200, height=50)
    slope_set_text.on_change('value', parameter_set_callback)
    
    # Radio button group for setting plate type
    global plate_type_buttons
    global plate_type
    plate_type_buttons = RadioButtonGroup(labels=['96 well', '384 well'], 
                                          width=200, height=25, active=plate_type)
    plate_type_buttons.on_change('active', plate_type_callback)
    
    # Radio button group for setting data layout
    global plate_layout_buttons
    global plate_layout
    plate_layout_buttons = RadioButtonGroup(labels=['by row', 'by column'],
                                           width=200, height=25, active=plate_layout)
    plate_layout_buttons.on_change('active', plate_layout_callback)
    
    # Checkbox groups for fixing fit parameters
    global fix_bottom_checkbox
    fix_bottom_checkbox = CheckboxButtonGroup(labels=['Fix min fluoresence (Fmin)'], 
                                              width=200, height=30)
    fix_bottom_checkbox.on_change('active', parameter_set_callback)
    
    global fix_top_checkbox
    fix_top_checkbox = CheckboxButtonGroup(labels=['Fix max fluorescence (Fmax)'], width=200, height=30)
    fix_top_checkbox.on_change('active', parameter_set_callback)
    
    global fix_slope_checkbox
    fix_slope_checkbox = CheckboxButtonGroup(labels=['Fix curve shape parameter (a)'], width=200, height=30)
    fix_slope_checkbox.on_change('active', parameter_set_callback)
    
    # Slider for selecting data to fit
    global df
    xmin = df[df.columns[0]].values[0]
    xstep = df[df.columns[0]].values[1] - xmin
    xstart = sample.data['x'].values[0]
    xend = sample.data['x'].values[-1]
    xmax = df[df.columns[0]].values[-1]
    
    global range_slider
    range_slider = RangeSlider(start=xmin, end=xmax, value=(xstart, xend),
                    step=xstep,
                    title='Fine tune temperature range', width=550)
    range_slider.on_change('value', slider_callback)
    
    # Scatter plot for fitting individual samples
    global sample_source
    sample_source = ColumnDataSource(data=dict(x=sample.data.x, y=sample.data.y, 
                                        fit=sample.y_fit, residuals=sample.residuals))
    global sample_scatter
    plot_tools = 'wheel_zoom, pan, reset, save'
    sample_scatter = figure(title="Boltzman sigmoidal fit", x_axis_label='Temperature ('+degree_sign+'C)',
                            y_axis_label="Fluoresence intensity", plot_width=600, 
                            plot_height=300, tools=plot_tools)
    sample_scatter.circle(x='x', y='y', color='grey', size=8, alpha=0.6, source=sample_source)
    sample_scatter.line(x='x', y='fit', color='black', line_width=2, 
                        alpha=1.0, source=sample_source)
    sample_scatter.title.text = sample.name + ' fit'
    
    # Scatter plot for residuals of individual sample fit
    global residual_scatter
    residual_scatter = figure(title="Fit residuals", x_axis_label='Temperature ('+degree_sign+'C)',
                              y_axis_label="Residual", plot_width=600, 
                              plot_height=200, tools='wheel_zoom,pan,reset')
    residual_scatter.yaxis.formatter = BasicTickFormatter(precision=2, use_scientific=True)
    residual_scatter.circle('x', 'residuals', size=8, source=sample_source, 
                            color='grey', alpha=0.6)
    
    # Heatmap for displaying all Tm values in dataset
    global plate_source
    letters = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P']
    w, n, t, e = [], [], [], []
    if plate_type_buttons.active == 1:
        rows = 16
        columns = 24
    else:
        rows = 8
        columns = 12
    
    for i in range(rows):
        for j in range(columns):
            w.append(letters[i]+str(j+1))
            try:
                n.append(plate[(i, j)].name)
                t.append(plate[(i, j)].v50_fit)
                e.append(plate[(i, j)].v50_err)
            except:
                n.append('')
                t.append(np.nan)
                e.append(np.nan)
                
    xname = [x[1:] for x in w]
    yname = [y[0] for y in w]
    
    plate_source = ColumnDataSource(dict(w=w, n=n, t=t, e=e, xname=xname, yname=yname)) 
    plate_columns = [
        TableColumn(field='w', title='Well ID'),
        TableColumn(field='n', title='Sample name'),
        TableColumn(field='t', title='Tm ('+degree_sign+'C)'),
        TableColumn(field='e', title='Error ('+degree_sign+'C)'),
    ]
    
    plate_map_hover = HoverTool(tooltips="""
        <div>
                <div>
                        <span style="font-size: 14px; font-weight: bold; ">@n:</span>
                        <span style="font-size: 14px; font-weight: bold; ">@t</span>
                </div>
        </div>
        """
    )
    
    if plate_type_buttons.active == 1:
        plate_map = figure(title="Plate view", x_axis_location="above", height=400, width=620, 
                       tools=["save, tap, reset", plate_map_hover], 
                       x_range=[str(x+1) for x in range(0, columns)]+['', 'Tm ('+degree_sign+'C)'],
                       y_range=letters[:rows][::-1])
    else:
        plate_map = figure(title="Plate view", x_axis_location="above", height=400, width=620, 
                       tools=["save, tap, reset", plate_map_hover], 
                       x_range=[str(x+1) for x in range(0, columns)]+['Tm ('+degree_sign+'C)'], 
                       y_range=letters[:rows][::-1])
        
    taptool = plate_map.select(type=TapTool)
    plate_map.on_event(Tap, plate_select)
    
    global mapper
    mapper = linear_cmap(field_name='t', palette=RdBu[8], low=min(t), high=max(t))
    
    global color_bar
    color_bar = ColorBar(color_mapper=mapper['transform'], width=10, height=250, name='Tm ('+degree_sign+'C)')
    plate_map.add_layout(color_bar, 'right')
    
    plate_map.grid.grid_line_color = None
    plate_map.axis.axis_line_color = None
    plate_map.axis.major_tick_line_color = None
    plate_map.axis.major_label_text_font_size = "10pt"
    plate_map.axis.major_label_standoff = 0
    plate_map.rect('xname', 'yname', .95, .95, source=plate_source,
            color=mapper, line_color='black', line_width=1)
    
    # Table listing all Tm values in dataset
    global plate_table
    plate_table = DataTable(source=plate_source, columns=plate_columns, width=500,
                            height=500, selectable=True, editable=True)
    plate_table.source.selected.on_change('indices', table_select)
    
    # Table showing fitting parameters for current sample
    global sample_table_source
    sample_table_source = ColumnDataSource(data=dict(l=['Fit value', 'Std. error'],
                                                     b=[sample.bottom_fit, sample.bottom_err],
                                                     t=[sample.top_fit, sample.top_err],
                                                     v=[sample.v50_fit, sample.v50_err],
                                                     s=[sample.slope_fit, sample.slope_err])) 
    sample_table_columns = [
        TableColumn(field='l', title=''),
        TableColumn(field='b', title='Fmin'),
        TableColumn(field='t', title='Fmax'),
        TableColumn(field='v', title='Tm ('+degree_sign+'C)'),
        TableColumn(field='s', title='a')
    ]
    global sample_table
    sample_table = DataTable(source=sample_table_source, columns=sample_table_columns, width=600,
                            height=200, selectable=False, editable=False)
   
    # Button to re-fit all with current parameter settings
    global refit_all_button
    refit_all_button = Button(label="Re-fit all samples", 
                              button_type='danger', width=200, height=30)
    refit_all_button.on_click(refit_all_callback)
    
    # Button to download Tm table to csv file
    global download_button
    download_button = Button(label="Download table to CSV", 
                             button_type="primary", width=200, height=30)
    download_button.js_on_click(CustomJS(args=dict(source=plate_source, file_name=output_filename), 
                                        code=open(join(dirname(__file__), "download.js")).read()))

    # Button to copy Tm table to clipboard
    global copy_button
    copy_button = Button(label="Copy table to clipboard", button_type="primary", 
                         width=200, height=30)
    copy_button.js_on_click(CustomJS(args=dict(source=plate_source),
                               code=open(join(dirname(__file__), "copy.js")).read()))

    # page formatting
    desc = Div(text=open(join(dirname(__file__), "description.html")).read(), width=1200)
    main_row = row(column(plate_type_buttons, plate_layout_buttons, upload_button, 
                          fix_bottom_checkbox, bottom_set_text, fix_top_checkbox, 
                          top_set_text, fix_slope_checkbox, slope_set_text, refit_all_button,
                          download_button, copy_button),
                   column(sample_scatter, residual_scatter, range_slider, sample_table),
                   column(plate_map, plate_table))
        
    sizing_mode = 'scale_width'
    l = layout([
        [desc],
        [main_row]
    ], sizing_mode=sizing_mode)
    
    update()
    curdoc().clear()
    curdoc().add_root(l)
    curdoc().title = "DSF"
Example #16
0
class SeparationDash():
    """
    A dashboard that displays separation data.

    Pass a reference to the Bokeh document for threading access.
    """
    def __init__(self, model):
        """
        Construct separation dashboard
        """
        # Save reference to model
        self.model = model

        ################################
        # Process button
        ################################

        self.process = Button(label="Generate",
                              button_type="primary",
                              name='process',
                              sizing_mode='scale_width',
                              css_classes=['generate'])
        self.process.js_on_click(CustomJS(code="toggleLoading()"))

        ################################
        # Widgets
        ################################

        # Data type selection
        self.data_type = RadioButtonGroup(
            labels=["All Data", "Experimental", "Simulated"],
            active=0,
            css_classes=['dtypes'])

        # Adsorbate drop-down selections
        self.g1_sel = Select(title="Adsorbate 1",
                             options=self.model.ads_list,
                             value=self.model.g1,
                             css_classes=['g-selectors'])
        self.g2_sel = Select(title="Adsorbate 2",
                             options=self.model.ads_list,
                             value=self.model.g2)

        # Temperature selection
        self.t_absolute = Spinner(value=self.model.t_abs,
                                  title='Temperature:',
                                  css_classes=['t-abs'])
        self.t_tolerance = Spinner(value=self.model.t_tol,
                                   title='Tolerance:',
                                   css_classes=['t-tol'])

        # Combined in a layout
        self.dsel_widgets = layout([
            [self.data_type],
            [self.g1_sel, self.g2_sel, self.t_absolute, self.t_tolerance],
        ],
                                   sizing_mode='scale_width',
                                   name="widgets")

        ################################
        # KPI Plots
        ################################

        # Top graph generation
        tooltip = load_tooltip()
        self.p_henry, rend1 = self.top_graph("K", "Henry coefficient (log)",
                                             self.model.data,
                                             self.model.errors, tooltip)
        self.p_loading, rend2 = self.top_graph(
            "L", "Uptake at selected pressure (bar)", self.model.data,
            self.model.errors, tooltip)
        self.p_wc, rend3 = self.top_graph(
            "W", "Working capacity in selected range (bar)", self.model.data,
            self.model.errors, tooltip)

        # Give graphs the same hover and select effect
        sel = Circle(fill_alpha=1, fill_color="red", line_color=None)
        nonsel = Circle(fill_alpha=0.2, fill_color="blue", line_color=None)
        for rend in [rend1, rend2, rend3]:
            rend.selection_glyph = sel
            rend.nonselection_glyph = nonsel
            rend.hover_glyph = sel

        # Pressure slider
        self.p_slider = Slider(
            title="Pressure (bar)",
            value=0.5,
            start=0,
            end=20,
            step=0.5,
            callback_policy='throttle',
            callback_throttle=200,
        )

        # Working capacity slider
        self.wc_slider = RangeSlider(
            title="Working capacity (bar)",
            value=(0.5, 5),
            start=0,
            end=20,
            step=0.5,
            callback_policy='throttle',
            callback_throttle=200,
        )

        # Material datatable
        self.mat_list = DataTable(
            columns=[
                TableColumn(field="labels", title="Material", width=300),
                TableColumn(field="sel",
                            title="KH2/KH1",
                            width=35,
                            formatter=NumberFormatter(format='‘0.0a’')),
                TableColumn(field="psa_W",
                            title="PSA-API",
                            width=35,
                            formatter=NumberFormatter(format='‘0.0a’')),
            ],
            source=self.model.data,
            index_position=None,
            selectable='checkbox',
            scroll_to_selection=True,
            width=400,
            fit_columns=True,
        )

        # Custom css classes for interactors
        self.p_henry.css_classes = ['g-henry']
        self.p_loading.css_classes = ['g-load']
        self.p_wc.css_classes = ['g-wcap']
        self.mat_list.css_classes = ['t-details']

        # Generate the axis labels
        self.top_graph_labels()

        self.kpi_plots = layout([
            [
                gridplot([[self.mat_list, self.p_henry],
                          [self.p_loading, self.p_wc]],
                         sizing_mode='scale_width')
            ],
            [self.p_slider, self.wc_slider],
        ],
                                sizing_mode='scale_width',
                                name="kpiplots")
        self.kpi_plots.children[0].css_classes = ['kpi']
        self.kpi_plots.children[1].css_classes = ['p-selectors']

        ################################
        # Isotherm details explorer
        ################################

        # Isotherm display graphs
        self.p_g1iso = self.bottom_graph(self.model.g1_iso_sel, self.model.g1)
        self.p_g2iso = self.bottom_graph(self.model.g2_iso_sel, self.model.g2)

        # Isotherm display palette
        self.c_cyc = cycle(gen_palette(20))

        self.detail_plots = layout([
            [self.p_g1iso, self.p_g2iso],
        ],
                                   sizing_mode='scale_width',
                                   name="detailplots")
        self.detail_plots.children[0].css_classes = ['isotherms']

    # #########################################################################
    # Graph generators

    def top_graph(self, ind, title, d_source, e_source, tooltip, **kwargs):
        """Generate the top graphs (KH, uptake, WC)."""

        # Generate figure dict
        plot_side_size = 400
        fig_dict = dict(tools="pan,wheel_zoom,tap,reset,save",
                        active_scroll="wheel_zoom",
                        plot_width=plot_side_size,
                        plot_height=plot_side_size,
                        title=title)
        fig_dict.update(kwargs)

        # Create a colour mapper for number of isotherms
        mapper = log_cmap(field_name='{0}_n'.format(ind),
                          palette="Viridis256",
                          low_color='grey',
                          high_color='yellow',
                          low=3,
                          high=100)

        # Create a new plot
        graph = figure(**fig_dict)

        # Add the hover tooltip
        graph.add_tools(
            HoverTool(names=["{0}_data".format(ind)],
                      tooltips=tooltip.render(p=ind)))

        # Plot the data
        rend = graph.circle("{0}_x".format(ind),
                            "{0}_y".format(ind),
                            source=d_source,
                            size=10,
                            line_color=mapper,
                            color=mapper,
                            name="{0}_data".format(ind))

        # Plot guide line
        graph.add_layout(
            Slope(gradient=1,
                  y_intercept=0,
                  line_color='black',
                  line_dash='dashed',
                  line_width=2))

        # Plot the error margins
        graph.segment('{0}_x0'.format(ind),
                      '{0}_y0'.format(ind),
                      '{0}_x1'.format(ind),
                      '{0}_y1'.format(ind),
                      source=e_source,
                      color="black",
                      line_width=2,
                      line_cap='square',
                      line_dash='dotted')

        # Plot labels next to selected materials
        graph.add_layout(
            LabelSet(
                x='{0}_x'.format(ind),
                y='{0}_y'.format(ind),
                source=e_source,
                text='labels',
                level='glyph',
                x_offset=5,
                y_offset=5,
                render_mode='canvas',
                text_font_size='10pt',
            ))

        # Add the colorbar to the side
        graph.add_layout(
            ColorBar(color_mapper=mapper['transform'],
                     ticker=LogTicker(desired_num_ticks=10),
                     width=8,
                     location=(0, 0)), 'right')

        return graph, rend

    def top_graph_labels(self):
        """Generate the top graph labels from selected ads_list."""
        self.p_loading.xaxis.axis_label = '{0} (mmol/g)'.format(self.model.g1)
        self.p_loading.yaxis.axis_label = '{0} (mmol/g)'.format(self.model.g2)
        self.p_henry.xaxis.axis_label = '{0} (mmol/bar)'.format(self.model.g1)
        self.p_henry.yaxis.axis_label = '{0} (mmol/bar)'.format(self.model.g2)
        self.p_wc.xaxis.axis_label = '{0} (mmol/g)'.format(self.model.g1)
        self.p_wc.yaxis.axis_label = '{0} (mmol/g)'.format(self.model.g2)

    def bottom_graph(self, source, ads):
        """Generate the bottom graphs (isotherm display)."""

        graph = figure(tools="pan,wheel_zoom,reset",
                       active_scroll="wheel_zoom",
                       plot_width=400,
                       plot_height=250,
                       x_range=(-0.01, 0.01),
                       y_range=(-0.01, 0.01),
                       title='Isotherms {0}'.format(ads))
        rend = graph.multi_line('x',
                                'y',
                                source=source,
                                alpha=0.6,
                                line_width=3,
                                hover_line_alpha=1.0,
                                hover_line_color="black",
                                line_color='color')

        # Make clicking a graph open the NIST database

        graph.add_tools(
            HoverTool(show_arrow=False,
                      line_policy='nearest',
                      tooltips="""Click for details"""))

        graph.add_tools(
            TapTool(renderers=[rend],
                    callback=CustomJS(args={
                        'tp': load_details().render(),
                    },
                                      code=load_details_js())))

        source.selected.js_on_change(
            'indices',
            CustomJS(
                code=
                'if (cb_obj.indices.length == 0) document.getElementById("iso-details").style.display = \"none\"'
            ))

        graph.xaxis.axis_label = 'Pressure (bar)'
        graph.yaxis.axis_label = 'Uptake (mmol/g)'

        return graph
Example #17
0
def create_layout():
    """Inclui o gráficos e os controles no curdoc do Bokeh Server."""
    plot_html = ColumnDataSource(dict(file_html=["Title"], html=[""]))
    plot = figure(
        title="Title",
        sizing_mode="stretch_both",
        tools="wheel_zoom,box_zoom,pan,,crosshair,reset,save",
        # tooltips=[("y", "$y"), ("x", "$x")],
        active_scroll="wheel_zoom",
        toolbar_location="above",
        output_backend="webgl",
    )
    plot.xaxis.axis_label = "X"
    plot.yaxis.axis_label = "Y"
    plot.add_layout(Legend())
    plot.legend.click_policy = "hide"
    plot.legend.background_fill_alpha = 0.6
    table_source = ColumnDataSource()
    side_controls = column(width=400, height=200)
    series_source_controls = row(sizing_mode="scale_width")
    tabs = Tabs()
    models.COLORS = cycle(Category10_10)
    models.Series.labels = []

    def upload_callback(attr, old, new):
        """Função que atualiza os dados do arquivo aberto."""
        file_contents = base64.b64decode(new)
        file_contents_bytes = io.BytesIO(file_contents)
        table_source.data = pd.read_csv(file_contents_bytes).to_dict("list")
        colmmns = list(table_source.data.keys())
        for widget in list(values_selectors.values()):
            widget.options = colmmns
        datatable.columns = [TableColumn(field=_, title=_) for _ in colmmns]

    def update_plot_html(event):
        title = plot.title.text
        file_name = title + ".html"
        # output_file(file_name, title=title, mode="inline")
        # save(plot)
        html = file_html(plot, INLINE, title)
        plot_html.data = dict(file_name=[file_name], html=[html])

    # Widgets (controls) ======================================================
    # Plot controls
    plot_title = TextInput(title="Plot title", value="Title")
    x_title = TextInput(title="X title", value="X")
    y_title = TextInput(title="Y title", value="Y")
    positions = [_.replace("_", "-") for _ in list(LegendLocation)]
    legend_position = Select(title="Legend position", options=positions)
    download_button = Button(label="Download saved",
                             button_type="success",
                             align="end")
    save_button = Button(label="Save", align="end")
    save_button.on_click(update_plot_html)
    with open("bokeh_chart_maker/download.js") as f:
        callback = CustomJS(args=dict(source=plot_html), code=f.read())
    download_button.js_on_click(callback)
    plot_controls = row(plot_title, x_title, y_title, legend_position,
                        save_button, download_button)

    def update_plot(attr, old, new):
        plot.title.text = plot_title.value
        plot.xaxis.axis_label = x_title.value
        plot.yaxis.axis_label = y_title.value
        plot.legend.location = legend_position.value.replace("-", "_")

    for widget in plot_controls.children:
        if hasattr(widget, "value"):
            widget.on_change("value", update_plot)
    legend_position.value = "top_left"

    # Series controls
    upload_button = FileInput(accept=".csv")
    upload_button.on_change("value", upload_callback)
    columns = [
        TableColumn(field=_, title=_, width=10)
        for _ in table_source.data.keys()
    ]
    datatable = DataTable(source=table_source,
                          columns=columns,
                          width=390,
                          height=200)
    values_selectors = {}
    glyph_type = Select(title="Glyph type",
                        options=["line", "scatter"],
                        width=100)

    def update_series_source_controls(attr, old, new):
        colmmns = list(table_source.data.keys())
        kw = dict(options=colmmns, width=80)
        values_selectors["x"] = Select(title=f"x-values", **kw)
        values_selectors["y"] = Select(title=f"y-values", **kw)
        series_source_controls.children = list(values_selectors.values())

    glyph_type.on_change("value", update_series_source_controls)
    glyph_type.value = "line"
    add_button = Button(label="Add glyph",
                        button_type="success",
                        width=50,
                        align="end")
    side_controls.children = [
        Div(text="<h3>Load file</h3>", height=35),
        upload_button,
        datatable,
        row(glyph_type, series_source_controls, add_button, width=390),
        Div(text="<h3>Glyphs</h3>", height=35),
        tabs,
    ]

    def add_series(event):
        any_col = list(table_source.data.keys())[0]
        source = ColumnDataSource()
        for key, selector in values_selectors.items():
            column_name = selector.value or any_col
            source.data[key] = table_source.data[column_name]
        vars_map = dict((k, str(k)) for k in values_selectors.keys())
        if glyph_type.value == "line":
            series = models.line_series(plot, source=source, **vars_map)
        elif glyph_type.value == "scatter":
            series = models.scatter_series(plot, source=source, **vars_map)

        def delete_series(event):
            plot.renderers = [
                r for r in plot.renderers if r.glyph != series.glyph
            ]
            legend_items = list(plot.legend.items)
            plot.legend.items = [
                item for item in legend_items
                if series.glyph != item.renderers[0].glyph
            ]
            tabs.tabs = [panel for panel in tabs.tabs if panel != series.panel]

        series.delete_button.on_click(delete_series)
        tabs.tabs.append(series.panel)

    add_button.on_click(add_series)
    return [
        side_controls,
        column(plot_controls, plot, sizing_mode="stretch_width")
    ]
		}

		else {
			var link = document.createElement("a");
			link = document.createElement('a')
			link.href = URL.createObjectURL(blob);
			link.download = filename
			link.target = "_blank";
			link.style.visibility = 'hidden';
			link.dispatchEvent(new MouseEvent('click'))
		}
	""") 




annotation_select = RadioButtonGroup(labels=["N", "V", "Q", "Delete Bin", "Noise Bin"], callback=cb_rgrp_button,height=15)

refresh = Button(label="Refresh ", button_type="success", callback = callback,sizing_mode='scale_height',width=100,height=10)
refresh.js_on_click(callback)



change_button = Button(label="Change ", button_type="success", sizing_mode='scale_width',callback = callback,width=100,height=10)

button = Button(label="Download Changed Annotations", button_type="success", callback = cb_button,height=0) 

figure = row(p1, column(div3,slider,div,checkboxes,div2,annotation_select,row(change_button, refresh), button),p2)

show(figure)
Example #19
0
def nn():
    ###------------------------PARAMETER DEFAULTS-----------------------------###
    # range[Lower, Upper, Step Size]
    ### - SAMPLING Parameters
    d_nsamp, r_nsamp = 500, [100, 2000, 50]  # Number of samples

    plot_data = figure(
        plot_height=400,
        plot_width=400,
        title="Simulated points (x,y)",
        toolbar_location="above",
        x_axis_label="x",
        y_axis_label="y",
        tools="pan,save,box_zoom,wheel_zoom",
    )

    source = ColumnDataSource(data=dict(x=[], y=[], z=[]))
    source.data = dict(x=np.zeros([1, 1]),
                       y=np.zeros([1, 1]),
                       z=np.zeros([1, 1]))
    surface_title = Div(
        text="<b> Surafce plot of the joint distribution z = p(x,y) </b>")
    surface = Surface3d(x="x", y="y", z="z", data_source=source)

    plot_conditional = figure(
        plot_height=400,
        plot_width=800,
        title="Conditional density p(y/x=X)",
        toolbar_location="above",
        x_axis_label="y",
        y_axis_label="CDF",
        tools="pan,save,box_zoom,wheel_zoom",
    )

    style(plot_conditional)

    plot_clear = Button(label="Clear All", button_type="warning")

    # Simulation of GMM

    ctl_title = Div(text="<h3>Simulator</h3>")
    div1 = Div(
        text=
        """<p style="border:3px; border-style:solid; border-color:grey; padding: 1em;">
                    Hyperparameters of bi-GMM components (refer to the blog post for details)<br />  
                    - n_kernels: Nb of componenets<br />  
                    - means_loc: mean of a normal distribution from where the means of components are sampled. <br /> 
                    - means_scale: associated scale. <br /> 
                    - covariance_x_loc: mean of a normal distribution from where the covariances of X are simpled <br /> 
                    - covariance_x_scale: associated scale. <br /> 
                    - covariance_y_loc: mean of a normal distribution from where the covariances of Y are simpled <br /> 
                    - covariance_y_scale: associated scale. <br /> 
                    </p>""",
        width=300,
        height=330,
    )

    ctl_nsamp = Slider(
        title="Number of samples",
        value=d_nsamp,
        start=r_nsamp[0],
        end=r_nsamp[1],
        step=r_nsamp[2],
    )

    n_kernels = Slider(title="Number of mixtures",
                       value=5,
                       start=1,
                       end=10,
                       step=1)

    means_loc = TextInput(title="means_loc", value="0.0")
    means_scale = TextInput(title="means_scale", value="4.0")

    covariance_x_loc = TextInput(title="covariance_x_loc", value="1.0")
    covariance_x_scale = TextInput(title="covariance_x_scale", value="0.5")

    covariance_y_loc = TextInput(title="covariance_y_loc", value="1.0")
    covariance_y_scale = TextInput(title="covariance_y_scale", value="0.5")

    plot_sim = Button(label="Simulate", button_type="primary")

    simulate = widgetbox(
        ctl_title,
        div1,
        ctl_nsamp,
        plot_sim,
        n_kernels,
        means_loc,
        means_scale,
        covariance_x_loc,
        covariance_x_scale,
        covariance_y_loc,
        covariance_y_scale,
    )

    ### MDN

    mdn_title = Div(text="<h3>MDN Training </h3>")
    mdn_text = Div(text="Choose training parameters")

    n_gaussians = Slider(title="Number of mixtures to fit",
                         value=10,
                         start=1,
                         end=20,
                         step=1)

    n_layers = Slider(title="Number of hidden layers",
                      value=1,
                      start=1,
                      end=3,
                      step=1)

    n_hidden = Slider(title="Size of hidden neurons",
                      value=20,
                      start=5,
                      end=10,
                      step=1)

    dropout = Slider(title="Dropout regularization",
                     value=0.05,
                     start=0,
                     end=0.2,
                     step=0.01)

    l2 = Slider(title="L2 regularization",
                value=0.001,
                start=0,
                end=0.1,
                step=0.001)

    epochs = Slider(title="Nb of epochs",
                    value=500,
                    start=1,
                    end=1500,
                    step=50)

    text_output = Paragraph(text="", width=200, height=20)

    train = Button(label="Train model", button_type="success")

    mdn_box = widgetbox(
        mdn_title,
        mdn_text,
        n_gaussians,
        n_layers,
        n_hidden,
        dropout,
        l2,
        epochs,
        train,
        text_output,
    )

    # Plot of p(y/x)

    fit_title = Div(
        text=
        "<h3>Plot Conditional Distribution P(y/x=X) </h3> - You can plot the real p(y/x) after simulating data. <br /> - You can plot estimated p(y/x) after taining the model."
    )

    at_X = TextInput(title="X", value="1.0")

    fit_sim = Button(label="Plot real p(y/x)", button_type="success")
    fit_sim_mdn = Button(label="Plot estimated p(y/x)", button_type="success")

    fit1 = widgetbox(fit_title, at_X, fit_sim, fit_sim_mdn)

    ###-----------------------------------------------------------------------###
    ###-----------------------BASE-LEVEL FUNCTIONS----------------------------###

    def make_data():
        # Sample points
        bi_gmm = SimulateBiGMM(
            int(n_kernels.value),
            float(means_loc.value),
            float(means_scale.value),
            float(covariance_x_loc.value),
            float(covariance_x_scale.value),
            float(covariance_y_loc.value),
            float(covariance_y_scale.value),
        )
        (x, y) = bi_gmm.simulate_xy(int(ctl_nsamp.value))

        return x, y, bi_gmm

    ###-----------------------------------------------------------------------###
    ###------------------DATA SOURCES AND INITIALIZATION----------------------###

    source1 = ColumnDataSource(data=dict(x=[], y=[]))
    plot_data.scatter("x",
                      "y",
                      source=source1,
                      size=3,
                      color="#3A5785",
                      alpha=0.6)

    source2 = ColumnDataSource(data=dict(x=[], prob=[]))
    source3 = ColumnDataSource(data=dict(x=[], prob=[]))

    plot_conditional.line("x",
                          "prob",
                          source=source2,
                          color="#21b093",
                          alpha=0.8,
                          legend="True CDF")

    plot_conditional.line("x",
                          "prob",
                          source=source3,
                          color="orange",
                          alpha=0.8,
                          legend="Estimated CDF")

    def click_simulate():
        # Make it global to be used later
        global x_points, y_points
        global bi_gmm_
        # reset pdf
        source2.data = dict(x=[], prob=[])
        source3.data = dict(x=[], prob=[])

        x_points, y_points, bi_gmm_ = make_data()

        source1.data = dict(x=x_points, y=y_points)

        plot_data.y_range.start = y_points.min() - 1
        plot_data.y_range.end = y_points.max() + 1

        plot_data.x_range.start = x_points.min() - 1
        plot_data.x_range.end = x_points.max() + 1

        plot_data.xaxis.axis_label = "x"
        plot_data.yaxis.axis_label = "y"

        # 3d surface plot

        xx, yy, zz = bi_gmm_.compute_pdf(x_points.min(), x_points.max(),
                                         y_points.min(), y_points.max())
        source.data = dict(x=xx, y=yy, z=zz)

    plot_sim.on_click(click_simulate)

    # Real P(y/x)
    def plot_real_conditional():

        source3.data = dict(x=[], prob=[])

        ys = np.linspace(y_points.min() - 1, y_points.max() + 1, 1000)
        prob = bi_gmm_.compute_cdf(float(at_X.value), ys)

        source2.data = dict(x=ys, prob=prob)

    fit_sim.on_click(plot_real_conditional)

    # Fit MDN

    def fit_mdn():
        global mdn_model

        mdn_model = MDN_network(
            int(n_hidden.value),
            int(n_layers.value),
            int(n_gaussians.value),
            float(dropout.value),
        )

        optimizer = torch.optim.Adam(mdn_model.parameters(),
                                     weight_decay=float(l2.value))

        x_tensor = torch.from_numpy(np.float32(x_points))
        y_tensor = torch.from_numpy(np.float32(y_points))

        for e in range(int(epochs.value)):
            l = train_epoch(mdn_model, (x_tensor, y_tensor), optimizer)

        text_output.text = "Taining is done."

    code = "cds.text = 'Training the model... Please wait.';"
    callback = CustomJS(args={"cds": text_output}, code=code)

    train.js_on_click(callback)
    train.on_click(fit_mdn)

    def plot_estimated_conditional():

        ys = np.linspace(y_points.min() - 1, y_points.max() + 1, 1000)

        prob = simulate_condprob_trained(float(at_X.value), mdn_model, ys)

        source3.data = dict(x=ys, prob=prob)

    fit_sim_mdn.on_click(plot_estimated_conditional)

    # Behavior when the "Clear" button is clicked
    def clear_plot():
        source1.data = dict(x=[], y=[])
        source2.data = dict(x=[], prob=[])
        source3.data = dict(x=[], prob=[])
        source.data = dict(x=np.zeros([1, 1]),
                           y=np.zeros([1, 1]),
                           z=np.zeros([1, 1]))
        text_output.text = ""

    plot_clear.on_click(clear_plot)

    ###-----------------------------------------------------------------------###
    ###----------------------------PAGE LAYOUT--------------------------------###

    col_inputs = column(simulate)
    col_output = column(mdn_box, fit1, plot_clear)

    # col_plots = column(plot_data, s3)
    plot_3d = column(surface_title, surface)

    col_plots = layout([[plot_data, plot_3d], [plot_conditional]])

    row_page = row(col_inputs, col_plots, col_output, width=1200)

    # Make a tab with the layout
    tab = Panel(child=row_page,
                title="Neual Network - Conditional Density Estimation")
    return tab
def plot_3DModel_bokeh(filename, map_data_all_slices, map_depth_all_slices, \
                       color_range_all_slices, profile_data_all, boundary_data, \
                       style_parameter):
    '''
    Plot shear velocity maps and velocity profiles using bokeh

    Input:
        filename is the filename of the resulting html file
        map_data_all_slices contains the velocity model parameters saved for map view plots
        map_depth_all_slices is a list of depths
        color_range_all_slices is a list of color ranges
        profile_data_all constains the velocity model parameters saved for profile plots
        boundary_data is a list of boundaries
        style_parameter contains plotting parameters

    Output:
        None
    
    '''
    xlabel_fontsize = style_parameter['xlabel_fontsize']
    #
    colorbar_data_all_left = []
    colorbar_data_all_right = []
    map_view_ndepth = style_parameter['map_view_ndepth']
    ncolor = len(palette)
    colorbar_top = [0.1 for i in range(ncolor)]
    colorbar_bottom = [0 for i in range(ncolor)]
    map_data_all_slices_depth = []
    for idepth in range(map_view_ndepth):
        color_min = color_range_all_slices[idepth][0]
        color_max = color_range_all_slices[idepth][1]
        color_step = (color_max - color_min) * 1. / ncolor
        colorbar_left = np.linspace(color_min, color_max - color_step, ncolor)
        colorbar_right = np.linspace(color_min + color_step, color_max, ncolor)
        colorbar_data_all_left.append(colorbar_left)
        colorbar_data_all_right.append(colorbar_right)
        map_depth = map_depth_all_slices[idepth]
        map_data_all_slices_depth.append(
            'Depth: {0:8.1f} km'.format(map_depth))
    #
    palette_r = palette[::-1]
    # data for the colorbar
    colorbar_data_one_slice = {}
    colorbar_data_one_slice['colorbar_left'] = colorbar_data_all_left[
        style_parameter['map_view_default_index']]
    colorbar_data_one_slice['colorbar_right'] = colorbar_data_all_right[
        style_parameter['map_view_default_index']]
    colorbar_data_one_slice_bokeh = ColumnDataSource(data=dict(colorbar_top=colorbar_top,colorbar_bottom=colorbar_bottom,\
                                                               colorbar_left=colorbar_data_one_slice['colorbar_left'],\
                                                               colorbar_right=colorbar_data_one_slice['colorbar_right'],\
                                                               palette_r=palette_r))
    colorbar_data_all_slices_bokeh = ColumnDataSource(data=dict(colorbar_data_all_left=colorbar_data_all_left,\
                                                                colorbar_data_all_right=colorbar_data_all_right))
    #
    map_view_label_lon = style_parameter['map_view_depth_label_lon']
    map_view_label_lat = style_parameter['map_view_depth_label_lat']
    map_data_one_slice_depth = map_data_all_slices_depth[
        style_parameter['map_view_default_index']]
    map_data_one_slice_depth_bokeh = ColumnDataSource(data=dict(lat=[map_view_label_lat], lon=[map_view_label_lon],
                                                           map_depth=[map_data_one_slice_depth],
                                                           left=[style_parameter['profile_plot_xmin']], \
                                                           right=[style_parameter['profile_plot_xmax']]))

    #
    map_view_default_index = style_parameter['map_view_default_index']
    #map_data_one_slice = map_data_all_slices[map_view_default_index]
    #
    map_color_all_slices = []
    for i in range(len(map_data_all_slices)):
        vmin, vmax = color_range_all_slices[i]
        map_color = val_to_rgb(map_data_all_slices[i], palette_r, vmin, vmax)
        map_color_2d = map_color.view('uint32').reshape(map_color.shape[:2])
        map_color_all_slices.append(map_color_2d)
    map_color_one_slice = map_color_all_slices[map_view_default_index]
    #
    map_data_one_slice_bokeh = ColumnDataSource(data=dict(x=[style_parameter['map_view_image_lon_min']],\
                   y=[style_parameter['map_view_image_lat_min']],dw=[style_parameter['nlon']*style_parameter['dlon']],\
                   dh=[style_parameter['nlat']*style_parameter['dlat']],map_data_one_slice=[map_color_one_slice]))
    map_data_all_slices_bokeh = ColumnDataSource(data=dict(map_data_all_slices=map_color_all_slices,\
                                                           map_data_all_slices_depth=map_data_all_slices_depth))
    # ------------------------------
    nprofile = len(profile_data_all)
    grid_lat_list = []
    grid_lon_list = []
    width_list = []
    height_list = []
    for iprofile in range(nprofile):
        aprofile = profile_data_all[iprofile]
        grid_lat_list.append(aprofile['lat'])
        grid_lon_list.append(aprofile['lon'])
        width_list.append(style_parameter['map_view_grid_width'])
        height_list.append(style_parameter['map_view_grid_height'])
    grid_data_bokeh = ColumnDataSource(data=dict(lon=grid_lon_list,lat=grid_lat_list,\
                                            width=width_list, height=height_list))
    profile_default_index = style_parameter['profile_default_index']
    selected_dot_on_map_bokeh = ColumnDataSource(data=dict(lat=[grid_lat_list[profile_default_index]], \
                                                           lon=[grid_lon_list[profile_default_index]], \
                                                           width=[style_parameter['map_view_grid_width']],\
                                                           height=[style_parameter['map_view_grid_height']],\
                                                           index=[profile_default_index]))
    # ------------------------------
    profile_vs_all = []
    profile_depth_all = []
    profile_ndepth = style_parameter['profile_ndepth']
    profile_lat_label_list = []
    profile_lon_label_list = []
    for iprofile in range(nprofile):
        aprofile = profile_data_all[iprofile]
        vs_raw = aprofile['vs']
        top_raw = aprofile['top']
        profile_lat_label_list.append('Lat: {0:12.1f}'.format(aprofile['lat']))
        profile_lon_label_list.append('Lon: {0:12.1f}'.format(aprofile['lon']))
        vs_plot = []
        depth_plot = []
        for idepth in range(profile_ndepth):
            vs_plot.append(vs_raw[idepth])
            depth_plot.append(top_raw[idepth])
            vs_plot.append(vs_raw[idepth])
            depth_plot.append(top_raw[idepth + 1])
        profile_vs_all.append(vs_plot)
        profile_depth_all.append(depth_plot)
    profile_data_all_bokeh = ColumnDataSource(data=dict(profile_vs_all=profile_vs_all, \
                                                        profile_depth_all=profile_depth_all))
    selected_profile_data_bokeh = ColumnDataSource(data=dict(vs=profile_vs_all[profile_default_index],\
                                                             depth=profile_depth_all[profile_default_index]))
    selected_profile_lat_label_bokeh = ColumnDataSource(data=\
                                dict(x=[style_parameter['profile_lat_label_x']], y=[style_parameter['profile_lat_label_y']],\
                                    lat_label=[profile_lat_label_list[profile_default_index]]))
    selected_profile_lon_label_bokeh = ColumnDataSource(data=\
                                dict(x=[style_parameter['profile_lon_label_x']], y=[style_parameter['profile_lon_label_y']],\
                                    lon_label=[profile_lon_label_list[profile_default_index]]))
    all_profile_lat_label_bokeh = ColumnDataSource(data=dict(
        profile_lat_label_list=profile_lat_label_list))
    all_profile_lon_label_bokeh = ColumnDataSource(data=dict(
        profile_lon_label_list=profile_lon_label_list))
    #
    button_ndepth = style_parameter['button_ndepth']
    button_data_all_vs = []
    button_data_all_vp = []
    button_data_all_rho = []
    button_data_all_top = []
    for iprofile in range(nprofile):
        aprofile = profile_data_all[iprofile]
        button_data_all_vs.append(aprofile['vs'][:button_ndepth])
        button_data_all_vp.append(aprofile['vp'][:button_ndepth])
        button_data_all_rho.append(aprofile['rho'][:button_ndepth])
        button_data_all_top.append(aprofile['top'][:button_ndepth])
    button_data_all_bokeh = ColumnDataSource(data=dict(button_data_all_vs=button_data_all_vs,\
                                                       button_data_all_vp=button_data_all_vp,\
                                                       button_data_all_rho=button_data_all_rho,\
                                                       button_data_all_top=button_data_all_top))
    # ==============================
    map_view = Figure(plot_width=style_parameter['map_view_plot_width'], plot_height=style_parameter['map_view_plot_height'], \
                      tools=style_parameter['map_view_tools'], title=style_parameter['map_view_title'], \
                      y_range=[style_parameter['map_view_figure_lat_min'], style_parameter['map_view_figure_lat_max']],\
                      x_range=[style_parameter['map_view_figure_lon_min'], style_parameter['map_view_figure_lon_max']])
    #
    map_view.image_rgba('map_data_one_slice',x='x',\
                   y='y',dw='dw',dh='dh',
                   source=map_data_one_slice_bokeh, level='image')

    depth_slider_callback = CustomJS(args=dict(map_data_one_slice_bokeh=map_data_one_slice_bokeh,\
                                               map_data_all_slices_bokeh=map_data_all_slices_bokeh,\
                                               colorbar_data_all_slices_bokeh=colorbar_data_all_slices_bokeh,\
                                               colorbar_data_one_slice_bokeh=colorbar_data_one_slice_bokeh,\
                                               map_data_one_slice_depth_bokeh=map_data_one_slice_depth_bokeh), code="""

        var d_index = Math.round(cb_obj.value)
        
        var map_data_all_slices = map_data_all_slices_bokeh.data
        
        map_data_one_slice_bokeh.data['map_data_one_slice'] = [map_data_all_slices['map_data_all_slices'][d_index]]
        map_data_one_slice_bokeh.change.emit()
        
        var color_data_all_slices = colorbar_data_all_slices_bokeh.data
        colorbar_data_one_slice_bokeh.data['colorbar_left'] = color_data_all_slices['colorbar_data_all_left'][d_index]
        colorbar_data_one_slice_bokeh.data['colorbar_right'] = color_data_all_slices['colorbar_data_all_right'][d_index]
        colorbar_data_one_slice_bokeh.change.emit()
        
        map_data_one_slice_depth_bokeh.data['map_depth'] = [map_data_all_slices['map_data_all_slices_depth'][d_index]]
        map_data_one_slice_depth_bokeh.change.emit()
        
    """)
    depth_slider = Slider(start=0, end=style_parameter['map_view_ndepth']-1, \
                          value=map_view_default_index, step=1, \
                          width=style_parameter['map_view_plot_width'],\
                          title=style_parameter['depth_slider_title'], height=50)
    depth_slider.js_on_change('value', depth_slider_callback)
    depth_slider_callback.args["depth_index"] = depth_slider
    # ------------------------------
    # add boundaries to map view
    # country boundaries
    map_view.multi_line(boundary_data['country']['longitude'],\
                        boundary_data['country']['latitude'],color='black',\
                        line_width=2, level='underlay',nonselection_line_alpha=1.0,\
                        nonselection_line_color='black')
    # marine boundaries
    map_view.multi_line(boundary_data['marine']['longitude'],\
                        boundary_data['marine']['latitude'],color='black',\
                        level='underlay',nonselection_line_alpha=1.0,\
                        nonselection_line_color='black')
    # shoreline boundaries
    map_view.multi_line(boundary_data['shoreline']['longitude'],\
                        boundary_data['shoreline']['latitude'],color='black',\
                        line_width=2, level='underlay',nonselection_line_alpha=1.0,\
                        nonselection_line_color='black')
    # state boundaries
    map_view.multi_line(boundary_data['state']['longitude'],\
                        boundary_data['state']['latitude'],color='black',\
                        level='underlay',nonselection_line_alpha=1.0,\
                        nonselection_line_color='black')
    # ------------------------------
    # add depth label
    map_view.rect(style_parameter['map_view_depth_box_lon'], style_parameter['map_view_depth_box_lat'], \
                  width=style_parameter['map_view_depth_box_width'], height=style_parameter['map_view_depth_box_height'], \
                  width_units='screen',height_units='screen', color='#FFFFFF', line_width=1., line_color='black', level='underlay')
    map_view.text('lon', 'lat', 'map_depth', source=map_data_one_slice_depth_bokeh,\
                  text_font_size=style_parameter['annotating_text_font_size'],text_align='left',level='underlay')
    # ------------------------------
    map_view.rect('lon', 'lat', width='width', \
                  width_units='screen', height='height', \
                  height_units='screen', line_color='gray', line_alpha=0.5, \
                  selection_line_color='gray', selection_line_alpha=0.5, selection_fill_color=None,\
                  nonselection_line_color='gray',nonselection_line_alpha=0.5, nonselection_fill_color=None,\
                  source=grid_data_bokeh, color=None, line_width=1, level='glyph')
    map_view.rect('lon', 'lat',width='width', \
                  width_units='screen', height='height', \
                  height_units='screen', line_color='#00ff00', line_alpha=1.0, \
                  source=selected_dot_on_map_bokeh, fill_color=None, line_width=3.,level='glyph')
    # ------------------------------
    grid_data_js = CustomJS(args=dict(selected_dot_on_map_bokeh=selected_dot_on_map_bokeh, \
                                                  grid_data_bokeh=grid_data_bokeh,\
                                                  profile_data_all_bokeh=profile_data_all_bokeh,\
                                                  selected_profile_data_bokeh=selected_profile_data_bokeh,\
                                                  selected_profile_lat_label_bokeh=selected_profile_lat_label_bokeh,\
                                                  selected_profile_lon_label_bokeh=selected_profile_lon_label_bokeh, \
                                                  all_profile_lat_label_bokeh=all_profile_lat_label_bokeh, \
                                                  all_profile_lon_label_bokeh=all_profile_lon_label_bokeh, \
                                                 ), code="""
        
        var inds = cb_obj.indices
        
        var grid_data = grid_data_bokeh.data
        selected_dot_on_map_bokeh.data['lat'] = [grid_data['lat'][inds]]
        selected_dot_on_map_bokeh.data['lon'] = [grid_data['lon'][inds]]
        selected_dot_on_map_bokeh.data['index'] = [inds]
        selected_dot_on_map_bokeh.change.emit()
        
        var profile_data_all = profile_data_all_bokeh.data
        selected_profile_data_bokeh.data['vs'] = profile_data_all['profile_vs_all'][inds]
        selected_profile_data_bokeh.data['depth'] = profile_data_all['profile_depth_all'][inds]
        selected_profile_data_bokeh.change.emit()
        
        var all_profile_lat_label = all_profile_lat_label_bokeh.data['profile_lat_label_list']
        var all_profile_lon_label = all_profile_lon_label_bokeh.data['profile_lon_label_list']
        selected_profile_lat_label_bokeh.data['lat_label'] = [all_profile_lat_label[inds]]
        selected_profile_lon_label_bokeh.data['lon_label'] = [all_profile_lon_label[inds]]
        selected_profile_lat_label_bokeh.change.emit()
        selected_profile_lon_label_bokeh.change.emit()
    """)
    grid_data_bokeh.selected.js_on_change('indices', grid_data_js)
    # ------------------------------
    # change style
    map_view.title.text_font_size = style_parameter['title_font_size']
    map_view.title.align = 'center'
    map_view.title.text_font_style = 'normal'
    map_view.xaxis.axis_label = style_parameter['map_view_xlabel']
    map_view.xaxis.axis_label_text_font_style = 'normal'
    map_view.xaxis.axis_label_text_font_size = xlabel_fontsize
    map_view.xaxis.major_label_text_font_size = xlabel_fontsize
    map_view.yaxis.axis_label = style_parameter['map_view_ylabel']
    map_view.yaxis.axis_label_text_font_style = 'normal'
    map_view.yaxis.axis_label_text_font_size = xlabel_fontsize
    map_view.yaxis.major_label_text_font_size = xlabel_fontsize
    map_view.xgrid.grid_line_color = None
    map_view.ygrid.grid_line_color = None
    map_view.toolbar.logo = None
    map_view.toolbar_location = 'above'
    map_view.toolbar_sticky = False
    # ==============================
    # plot colorbar
    colorbar_fig = Figure(tools=[], y_range=(0,0.1),plot_width=style_parameter['map_view_plot_width'], \
                      plot_height=style_parameter['colorbar_plot_height'],title=style_parameter['colorbar_title'])
    colorbar_fig.toolbar_location = None
    colorbar_fig.quad(top='colorbar_top',bottom='colorbar_bottom',left='colorbar_left',right='colorbar_right',\
                  color='palette_r',source=colorbar_data_one_slice_bokeh)
    colorbar_fig.yaxis[0].ticker = FixedTicker(ticks=[])
    colorbar_fig.xgrid.grid_line_color = None
    colorbar_fig.ygrid.grid_line_color = None
    colorbar_fig.xaxis.axis_label_text_font_size = xlabel_fontsize
    colorbar_fig.xaxis.major_label_text_font_size = xlabel_fontsize
    colorbar_fig.xaxis[0].formatter = PrintfTickFormatter(format="%5.2f")
    colorbar_fig.title.text_font_size = xlabel_fontsize
    colorbar_fig.title.align = 'center'
    colorbar_fig.title.text_font_style = 'normal'
    # ==============================
    profile_xrange = Range1d(start=style_parameter['profile_plot_xmin'],
                             end=style_parameter['profile_plot_xmax'])
    profile_yrange = Range1d(start=style_parameter['profile_plot_ymax'],
                             end=style_parameter['profile_plot_ymin'])
    profile_fig = Figure(plot_width=style_parameter['profile_plot_width'], plot_height=style_parameter['profile_plot_height'],\
                         x_range=profile_xrange, y_range=profile_yrange, tools=style_parameter['profile_tools'],\
                         title=style_parameter['profile_title'])
    profile_fig.line('vs',
                     'depth',
                     source=selected_profile_data_bokeh,
                     line_width=2,
                     line_color='black')
    # ------------------------------
    # add lat, lon
    profile_fig.rect([style_parameter['profile_label_box_x']], [style_parameter['profile_label_box_y']],\
                     width=style_parameter['profile_label_box_width'], height=style_parameter['profile_label_box_height'],\
                     width_units='screen', height_units='screen', color='#FFFFFF', line_width=1., line_color='black',\
                     level='underlay')
    profile_fig.text('x',
                     'y',
                     'lat_label',
                     source=selected_profile_lat_label_bokeh)
    profile_fig.text('x',
                     'y',
                     'lon_label',
                     source=selected_profile_lon_label_bokeh)
    # ------------------------------
    # change style
    profile_fig.xaxis.axis_label = style_parameter['profile_xlabel']
    profile_fig.xaxis.axis_label_text_font_style = 'normal'
    profile_fig.xaxis.axis_label_text_font_size = xlabel_fontsize
    profile_fig.xaxis.major_label_text_font_size = xlabel_fontsize
    profile_fig.yaxis.axis_label = style_parameter['profile_ylabel']
    profile_fig.yaxis.axis_label_text_font_style = 'normal'
    profile_fig.yaxis.axis_label_text_font_size = xlabel_fontsize
    profile_fig.yaxis.major_label_text_font_size = xlabel_fontsize
    profile_fig.xgrid.grid_line_dash = [4, 2]
    profile_fig.ygrid.grid_line_dash = [4, 2]
    profile_fig.title.text_font_size = style_parameter['title_font_size']
    profile_fig.title.align = 'center'
    profile_fig.title.text_font_style = 'normal'
    profile_fig.toolbar_location = 'above'
    profile_fig.toolbar_sticky = False
    profile_fig.toolbar.logo = None
    # ==============================
    profile_slider_callback = CustomJS(args=dict(selected_dot_on_map_bokeh=selected_dot_on_map_bokeh,\
                                                 grid_data_bokeh=grid_data_bokeh, \
                                                 profile_data_all_bokeh=profile_data_all_bokeh, \
                                                 selected_profile_data_bokeh=selected_profile_data_bokeh,\
                                                 selected_profile_lat_label_bokeh=selected_profile_lat_label_bokeh,\
                                                 selected_profile_lon_label_bokeh=selected_profile_lon_label_bokeh, \
                                                 all_profile_lat_label_bokeh=all_profile_lat_label_bokeh, \
                                                 all_profile_lon_label_bokeh=all_profile_lon_label_bokeh), code="""
        var p_index = Math.round(cb_obj.value)
        
        var grid_data = grid_data_bokeh.data
        selected_dot_on_map_bokeh.data['lat'] = [grid_data['lat'][p_index]]
        selected_dot_on_map_bokeh.data['lon'] = [grid_data['lon'][p_index]]
        selected_dot_on_map_bokeh.data['index'] = [p_index]
        selected_dot_on_map_bokeh.change.emit()
        
        var profile_data_all = profile_data_all_bokeh.data
        selected_profile_data_bokeh.data['vs'] = profile_data_all['profile_vs_all'][p_index]
        selected_profile_data_bokeh.data['depth'] = profile_data_all['profile_depth_all'][p_index]
        selected_profile_data_bokeh.change.emit()
        
        var all_profile_lat_label = all_profile_lat_label_bokeh.data['profile_lat_label_list']
        var all_profile_lon_label = all_profile_lon_label_bokeh.data['profile_lon_label_list']
        selected_profile_lat_label_bokeh.data['lat_label'] = [all_profile_lat_label[p_index]]
        selected_profile_lon_label_bokeh.data['lon_label'] = [all_profile_lon_label[p_index]]
        selected_profile_lat_label_bokeh.change.emit()
        selected_profile_lon_label_bokeh.change.emit()
        
    """)
    profile_slider = Slider(start=0, end=nprofile-1, value=style_parameter['profile_default_index'], \
                           step=1, title=style_parameter['profile_slider_title'], \
                           width=style_parameter['profile_plot_width'], height=50)
    profile_slider_callback.args['profile_index'] = profile_slider
    profile_slider.js_on_change('value', profile_slider_callback)
    # ==============================
    simple_text_button_callback = CustomJS(args=dict(button_data_all_bokeh=button_data_all_bokeh,\
                                                    selected_dot_on_map_bokeh=selected_dot_on_map_bokeh), \
                                           code="""
        var index = selected_dot_on_map_bokeh.data['index']
        
        var button_data_vs = button_data_all_bokeh.data['button_data_all_vs'][index]
        var button_data_vp = button_data_all_bokeh.data['button_data_all_vp'][index]
        var button_data_rho = button_data_all_bokeh.data['button_data_all_rho'][index]
        var button_data_top = button_data_all_bokeh.data['button_data_all_top'][index]
        
        var csvContent = ""
        var i = 0
        var temp = csvContent
        temp += "# Layer Top (km)      Vs(km/s)    Vp(km/s)    Rho(g/cm^3) \\n"
        while(button_data_vp[i]) {
            temp+=button_data_top[i].toPrecision(6) + "    " + button_data_vs[i].toPrecision(4) + "   " + \
                    button_data_vp[i].toPrecision(4) + "   " + button_data_rho[i].toPrecision(4) + "\\n"
            i = i + 1
        }
        const blob = new Blob([temp], { type: 'text/csv;charset=utf-8;' })
        const link = document.createElement('a');
        link.href = URL.createObjectURL(blob);
        link.download = 'vel_model.txt';
        link.target = '_blank'
        link.style.visibility = 'hidden'
        link.dispatchEvent(new MouseEvent('click'))
        
    """)

    simple_text_button = Button(
        label=style_parameter['simple_text_button_label'],
        button_type='default',
        width=style_parameter['button_width'])
    simple_text_button.js_on_click(simple_text_button_callback)
    # ------------------------------
    model96_button_callback = CustomJS(args=dict(button_data_all_bokeh=button_data_all_bokeh,\
                                                    selected_dot_on_map_bokeh=selected_dot_on_map_bokeh), \
                                           code="""
        var index = selected_dot_on_map_bokeh.data['index']
        var lat = selected_dot_on_map_bokeh.data['lat']
        var lon = selected_dot_on_map_bokeh.data['lon']
        
        var button_data_vs = button_data_all_bokeh.data['button_data_all_vs'][index]
        var button_data_vp = button_data_all_bokeh.data['button_data_all_vp'][index]
        var button_data_rho = button_data_all_bokeh.data['button_data_all_rho'][index]
        var button_data_top = button_data_all_bokeh.data['button_data_all_top'][index]
        
        var csvContent = ""
        var i = 0
        var temp = csvContent
        temp +=  "MODEL." + index + " \\n"
        temp +=  "ShearVelocityModel Lat: "+ lat +"  Lon: " + lon + "\\n"
        temp +=  "ISOTROPIC \\n"
        temp +=  "KGS \\n"
        temp +=  "SPHERICAL EARTH \\n"
        temp +=  "1-D \\n"
        temp +=  "CONSTANT VELOCITY \\n"
        temp +=  "LINE08 \\n"
        temp +=  "LINE09 \\n"
        temp +=  "LINE10 \\n"
        temp +=  "LINE11 \\n"
        temp +=  "      H(KM)   VP(KM/S)   VS(KM/S) RHO(GM/CC)     QP         QS       ETAP       ETAS      FREFP      FREFS \\n"
        while(button_data_vp[i+1]) {
            var thickness = button_data_top[i+1] - button_data_top[i]
            temp+="      " +thickness.toPrecision(6) + "    " + button_data_vp[i].toPrecision(4) + "      " + button_data_vs[i].toPrecision(4) \
                 + "      " + button_data_rho[i].toPrecision(4) + "     0.00       0.00       0.00       0.00       1.00       1.00" + "\\n"
            i = i + 1
        }
        const blob = new Blob([temp], { type: 'text/csv;charset=utf-8;' })
        const link = document.createElement('a');
        link.href = URL.createObjectURL(blob);
        link.download = 'vel_model96.txt';
        link.target = '_blank'
        link.style.visibility = 'hidden'
        link.dispatchEvent(new MouseEvent('click'))
    """)
    model96_button = Button(label=style_parameter['model96_button_label'],
                            button_type='default',
                            width=style_parameter['button_width'])
    model96_button.js_on_click(model96_button_callback)
    # ==============================
    # annotating text
    annotating_fig01 = Div(text=style_parameter['annotating_html01'], \
        width=style_parameter['annotation_plot_width'], height=style_parameter['annotation_plot_height'])
    annotating_fig02 = Div(text=style_parameter['annotating_html02'],\
        width=style_parameter['annotation_plot_width'], height=style_parameter['annotation_plot_height'])
    # ==============================
    output_file(filename,
                title=style_parameter['html_title'],
                mode=style_parameter['library_source'])
    left_column = Column(depth_slider,
                         map_view,
                         colorbar_fig,
                         annotating_fig01,
                         width=style_parameter['left_column_width'])
    button_pannel = Row(simple_text_button, model96_button)
    right_column = Column(profile_slider,
                          profile_fig,
                          button_pannel,
                          annotating_fig02,
                          width=style_parameter['right_column_width'])
    layout = Row(left_column, right_column)
    save(layout)
Example #21
0
def plot_iv(doc):

    init_calc = iv.iv_data(72, 800, 25, 45.9, 9.25, 37.2, 8.76, 7.47, 100)
    source = ColumnDataSource(data=init_calc[0])
    source_translated = ColumnDataSource(data=init_calc[1])
    res_source = ColumnDataSource(data=init_calc[2])
    status_param = init_calc[3]
    print(status_param)

    plot = Figure(plot_width=600,
                  plot_height=600,
                  y_range=(-1, 10),
                  x_range=(0, 60))
    plot.xaxis.axis_label = 'Voltage (V)'
    plot.yaxis.axis_label = 'Current (I)'
    plot.scatter(
        'x',
        'y',
        source=source,
        line_width=3,
        line_alpha=0.6,
    )
    plot.scatter(
        'x',
        'y',
        source=source_translated,
        line_width=3,
        line_alpha=0.6,
        line_color='red',
    )

    sig_plot = Figure(plot_width=300,
                      plot_height=300,
                      x_axis_label='Series Resistance (Rs)',
                      y_axis_label='Shunt Resistance (Rsh)',
                      title='Calculated Resistances')
    sig_plot.scatter('x', 'y', source=res_source, line_width=10)
    vline = Span(location=0,
                 dimension='height',
                 line_color='red',
                 line_width=3)
    # Horizontal line
    hline = Span(location=0,
                 dimension='width',
                 line_color='green',
                 line_width=3)
    sig_plot.renderers.extend([vline, hline])

    error_plt = Figure(
        plot_width=100,
        plot_height=50,
        toolbar_location=None,
    )

    if (status_param.success == True):
        print('Successful Entry to the landing page')
        cite = Label(text='Success',
                     render_mode='css',
                     text_color='white',
                     border_line_color='green',
                     background_fill_color='green')
    else:
        print('Inside fail')
        cite = Label(text='False',
                     render_mode='css',
                     text_color='white',
                     border_line_color='red',
                     background_fill_color='red')
    error_plt.add_layout(cite)
    error_plt.add_layout(
        Label(text='Success',
              render_mode='css',
              text_color='white',
              border_line_color='green',
              background_fill_color='green'))

    Ncell_input = TextInput(value='72', title='No. of cells')
    Irrad_input = TextInput(value='800', title='Irradiance')
    Temp_input = TextInput(value='25', title='Temperature (Celcius)')
    Isc_input = TextInput(value='9.25', title='I_sc at STC')
    Im_input = TextInput(value='8.76', title='I_m')
    Voc_input = TextInput(value='45.9', title='V_oc')
    Vm_input = TextInput(value='37.2', title='V_m')
    Isc_N_input = TextInput(value='7.47', title='I_sc at NOTC(G=800, T=45C)')
    Data_input = TextInput(value='100', title='Data Size')
    submit = Button(label='Submit', button_type='success')
    download_button_STC = Button(label='Download data (STC)')
    download_button_GT = Button(label='Download data (Translated)')

    def get_inputs():
        return (float(Ncell_input.value), float(Irrad_input.value),
                float(Temp_input.value), float(Voc_input.value),
                float(Isc_input.value), float(Vm_input.value),
                float(Im_input.value), float(Isc_N_input.value),
                float(Data_input.value))

    def update_plot(event):
        N, G, T, V, I, Vm, Im, I_N, datapoints = get_inputs()
        print('#' * 30)
        print('Updating the plot')
        print('#' * 30)
        updated_data = iv.iv_data(N, G, T, V, I, Vm, Im, I_N, datapoints)
        source.data = updated_data[0]
        source_translated.data = updated_data[1]
        res_source.data = updated_data[2]
        global status_param
        status_param = updated_data[3]
        print(status_param)
        if (status_param.success == True):
            print('Inside success')
            cite = Label(text='Successful Parameter Extraction',
                         render_mode='css',
                         text_color='white',
                         border_line_color='green',
                         background_fill_color='green')
        else:
            print('Inside fail')
            cite = Label(text='Parameter extraction not converging',
                         render_mode='css',
                         text_color='white',
                         border_line_color='red',
                         background_fill_color='red')
        error_plt = Figure(
            plot_width=100,
            plot_height=50,
            toolbar_location=None,
        )

        error_plt.add_layout(cite)
        layout.children[2].children[1] = error_plt

    def update_success():
        if (status_param.success == True):
            print('Inside success')
            cite = Label(text='Success',
                         render_mode='css',
                         text_color='white',
                         border_line_color='green',
                         background_fill_color='green')
        else:
            print('Inside fail')
            cite = Label(text='False',
                         render_mode='css',
                         text_color='white',
                         border_line_color='red',
                         background_fill_color='red')
        error_plt = Figure(
            plot_width=100,
            plot_height=50,
            toolbar_location=None,
        )

        error_plt.add_layout(cite)
        layout.children[2].children[1] = error_plt

    submit.on_click(update_plot)
    download_button_STC.js_on_click(
        CustomJS(args=dict(source=source),
                 code=open(join(dirname(__file__), "download.js")).read()))
    download_button_GT.js_on_click(
        CustomJS(args=dict(source=source_translated),
                 code=open(join(dirname(__file__), "download.js")).read()))

    #doc.add_periodic_callback(update_success, 1000)

    layout = row(
        plot,
        column(Ncell_input, Irrad_input, Temp_input, Isc_input, Im_input,
               Voc_input, Vm_input, Isc_N_input, Data_input, submit,
               download_button_STC, download_button_GT),
        column(sig_plot, error_plt))
    return (layout)
Example #22
0
from __future__ import print_function

from bokeh.util.browser import view
from bokeh.document import Document
from bokeh.embed import file_html
from bokeh.resources import INLINE

from bokeh.models import CustomJS, WidgetBox
from bokeh.models.widgets import (
    Button, Toggle, Dropdown, CheckboxGroup, RadioGroup, CheckboxButtonGroup, RadioButtonGroup,
)

button = Button(label="Button (enabled) - has click event", button_type="primary")
button.js_on_click(CustomJS(code="console.log('button: click', this.toString())"))

button_disabled = Button(label="Button (disabled) - no click event", button_type="primary", disabled=True)
button_disabled.js_on_click(CustomJS(code="console.log('button_disabled: click', this.toString())"))

toggle_inactive = Toggle(label="Toggle button (initially inactive)", button_type="success")
toggle_inactive.js_on_click(CustomJS(code="console.log('toggle_inactive: ' + this.active, this.toString())"))

toggle_active = Toggle(label="Toggle button (initially active)", button_type="success", active=True)
toggle_active.js_on_click(CustomJS(code="console.log('toggle_active: ' + this.active, this.toString())"))

menu = [("Item 1", "item_1_value"), ("Item 2", "item_2_value"), None, ("Item 3", "item_3_value")]

dropdown = Dropdown(label="Dropdown button", button_type="warning", menu=menu)
dropdown.js_on_click(CustomJS(code="console.log('dropdown: ' + this.value, this.toString())"))

dropdown_disabled = Dropdown(label="Dropdown button (disabled)", button_type="warning", disabled=True, menu=menu)
dropdown_disabled.js_on_click(CustomJS(code="console.log('dropdown_disabled: ' + this.value, this.toString())"))
Example #23
0
def create_vp_plot(data):
    ds = ColumnDataSource(data)
    # tools_to_show = "box_zoom, pan,save, hover, reset, wheel_zoom"
    var_label = '@{' + str(data.columns[0] + '}')
    try:
        var_tooltip_label = str(data.variable_metadata['long_name'])
    except KeyError:
        var_tooltip_label = str(data.variable_metadata['standard_name'])
    try:
        units = list({'unit', 'units'}.intersection(data.variable_metadata))[0]
        x_axis_label = " ".join(
            [var_tooltip_label, '[', data.variable_metadata[units], ']'])
    except IndexError:
        print('no units found')
        x_axis_label = var_tooltip_label
    p = figure(toolbar_location="above",
               tools="crosshair,box_zoom, pan,save, reset, wheel_zoom",
               x_axis_type="linear",
               x_axis_label=x_axis_label)
    p.sizing_mode = 'stretch_width'
    if len(data.dataset_metadata['dimension']) == 2:
        try:
            vertical_level, time_level = data.dataset_metadata['dimension']
        except KeyError:
            vertical_level, time_level = ('obsdepth', 'time')
    else:
        vertical_level = data.dataset_metadata['dimension'][0]
    try:
        var_tooltip_label = str(data.variable_metadata['long_name'])
    except KeyError:
        var_tooltip_label = str(data.variable_metadata['standard_name'])
    # if " " in var_label:
    #     var_label = '@{' + var_label + '}'
    # else:
    #     var_label = var_label
    # var_label = var_label
    hover = HoverTool(tooltips=[("Depth", "@" + vertical_level),
                                (var_tooltip_label, var_label)])

    p.add_tools(hover)
    p.y_range.flipped = True
    p.min_border_left = 80
    p.min_border_right = 80
    p.background_fill_color = "SeaShell"
    p.background_fill_alpha = 0.5
    line_renderer = p.line(data.columns[0],
                           vertical_level,
                           source=ds,
                           line_alpha=0.6, color='RoyalBlue',
                           )
    point_renderer = p.circle(data.columns[0],
                              vertical_level,
                              source=ds,
                              color='RoyalBlue',
                              size=3,
                              fill_alpha=0.5,
                              fill_color='white',
                              legend_label=data.columns[0],
                              )
    p.legend.location = "top_left"
    p.legend.click_policy = "hide"
    if len(list(data.columns)) >= 2:
        # Div
        html_text = get_datetime_string(list(data.columns)[0])
        par = Div(text=html_text)
        # Slider Labels
        end_label = Div(text=list(data.columns)[-1])
        start_label = Div(text=list(data.columns)[0])
        # Buttons
        left_btn = Button(label='<', width=30)
        right_btn = Button(label='>', width=30)
        # Spacer
        sp = Spacer(width=50)
        # Slider Labels
        end_label = Div(text=list(data.columns)[-1].split('T')[0] + \
                             '<br>' \
                             + list(data.columns)[-1].split('T')[1],
                        style={'text-align': 'right'})
        start_label = Div(text=list(data.columns)[0].split('T')[0] + \
                               '<br>' \
                               + list(data.columns)[0].split('T')[1],
                          style={'text-align': 'left'})

        select = Select(title="Profile-record:",
                        options=list(data.columns),
                        value=list(data.columns)[0])
        slider = Slider(title="Profile #",
                        value=0,
                        start=0,
                        end=len(data.columns) - 1,
                        step=1,
                        show_value=True,
                        tooltips=False)  #

        select_handler = CustomJS(args=dict(line_renderer=line_renderer,
                                            point_renderer=point_renderer,
                                            slider=slider,
                                            par=par),
                                  code="""
           line_renderer.glyph.x = {field: cb_obj.value};
           point_renderer.glyph.x = {field: cb_obj.value};
           slider.value = cb_obj.options.indexOf(cb_obj.value);
           var date_time = cb_obj.value.split("T");
           var date = date_time[0];
           var time = date_time[1];
           par.text = `<ul style="text-align:left;"><li>Date: <b>`+date+`</b></li><li>Time: <b>`+time+`</b></li></ul>`;
        """)
        select.js_on_change('value', select_handler)
        slider_handler = CustomJS(args=dict(select=select),
                                  code="""
           select.value = select.options[cb_obj.value];
        """)

        slider.js_on_change('value', slider_handler)

        # Left button cb
        left_btn_args = dict(slider=slider)
        left_btn_handler = """
        if(slider.value > slider.start) {
            slider.value = slider.value - 1;
            slider.change.emit();
        }
        """
        left_btn_callback = CustomJS(args=left_btn_args, code=left_btn_handler)
        left_btn.js_on_click(left_btn_callback)

        # Right button cb
        right_btn_args = dict(slider=slider)
        right_btn_handler = """
        if(slider.value <= slider.end - 1) {
            slider.value = slider.value + 1;
            slider.change.emit();
        }
        """
        right_btn_callback = CustomJS(args=right_btn_args, code=right_btn_handler)
        right_btn.js_on_click(right_btn_callback)

        # buttons = row(left_btn, right_btn)
        # inputs = row(sp,slider,buttons, par)
        # return column(select, slider, p, par, sizing_mode="stretch_width")
        # return column(p, select, inputs, sizing_mode="stretch_width")
        # Set up layouts and add to document
        # slider_wrapper = layout([
        #    [slider],
        #    [start_label, Spacer(sizing_mode="stretch_width"), end_label]
        # ])
        slider_wrapper = layout([
            [sp, sp, slider, left_btn, right_btn, par],
            [sp, start_label, sp, sp, end_label, sp, sp],
        ])
        # buttons = row(left_btn, right_btn)
        # inputs = row(sp, start_label, left_btn, sp, slider, sp, right_btn, end_label, par)

        return column(select, p, slider_wrapper, sizing_mode="stretch_width")
    else:
        return column(p, sizing_mode="stretch_width")
Example #24
0
## live time delta
time_slider = Slider(start=0.1, end=24, value=4, step=.1,
                     title="time delta (hours)", width=300)
time_slider.on_change('value_throttled', refresh_plot)

## streaming refresh time
stream_slider = Slider(start=1, end=60, value=10, step=1,
                       title="refresh (seconds)", width=300)
stream_slider.on_change('value_throttled', refresh_stream)

## force update_data()
live_button = Button(width=130, margin=[15, 10, 15, 10], label="live", button_type="primary")
live_button.on_click(plot_data)

history_button = Button(width=130, margin=[15, 10, 15, 10], label="history", button_type="default")
history_button.js_on_click(CustomJS(code=""" window.location.href='./history'; """))

tz_text = Paragraph(text=f"timezone: {timezone}", width=340)

controls = column(row(live_button, history_button),
                  instrum_select,
                  time_slider,
                  stream_slider,
                  tz_text)

# plot
plot_data()
stream = curdoc().add_periodic_callback(stream_data, stream_slider.value * 1000)

# periodically refresh plot
timeout = curdoc().add_periodic_callback(plot_data, 1024 * 1000)
Example #25
0
        bipot.sweep = "Anodic"


def update_voltammetry_mode(attr, old, new):
    if new is 0:
        bipot.mode = bipot.SINGLE
        Voltage_WE2.visible = False
    elif new is 1:
        bipot.mode = bipot.DUAL
        Voltage_WE2.visible = True

"""Callback Assignments"""
callback_update_plot = None
callback_acquire_data_fake = None
Connect.on_click(callback_Connect_eLoaD_BLE)
Save.js_on_click(callback_Save)
Start.on_click(callback_Start)
Random_test.on_click(callback_Random_4)
Gain.on_change('value', update_gain)
Scan_rate.on_change('value', update_scan_rate)
Segments.on_change('value', update_segments)
Voltage_Start.on_change('value', update_v1_start)
Voltage_WE2.on_change('value', update_v2)
Voltage_Window.on_change('value', update_v1_window)
Sweep_direction.on_change('active', update_sweep)
Voltammetry_Mode.on_change('active', update_voltammetry_mode)

#---------------------------#
#    Callbacks (Threads)    #
#---------------------------#
#Plotting has no priority, also slower
Example #26
0
def set_up_widgets(p, source, source1, source2, source3, source4, source5, df,
                   all_dates, text_dsn):
    '''Set up widgets needed after an initial dsn is entered'''
    dsn = text_dsn.value
    # Set up widgets
    text_title = TextInput(title="Title:", value="{} Data".format(dsn))
    text_save = TextInput(title="Save As:", value=dsn)

    max_for_dsn = df.timestamp.max()
    min_day = date_of_file(
        all_dates[0])  # works if sorted, needs to be formatted...
    max_day = date_of_file(all_dates[-1])

    plus_one = max_for_dsn + timedelta(days=1)
    calendar = DatePicker(title="Day:",
                          value=date(plus_one.year, plus_one.month,
                                     plus_one.day),
                          max_date=max_day,
                          min_date=min_day)
    button = Button(label="Update", button_type="success")

    columns = [
        TableColumn(field="day",
                    title="Date",
                    formatter=DateFormatter(format="%m/%d/%Y")),
        TableColumn(field="hr",
                    title="Avg HR",
                    formatter=NumberFormatter(format="0.0")),
        TableColumn(field="o2",
                    title="Avg O2",
                    formatter=NumberFormatter(format="0.0")),
        TableColumn(field="temp",
                    title="Avg Temp",
                    formatter=NumberFormatter(format="0.0"))
    ]

    # table_title = Div(text="""Daily Averages:""", width=200)
    # daily_avg = get_daily_avgs(df_full)
    # data =  {
    #     'day' : daily_avg.index,
    #     'hr' : daily_avg.heart_rate_avg,
    #     'o2' : daily_avg.oxygen_avg,
    #     'temp' : daily_avg.skin_temperature
    # }
    # table_source = ColumnDataSource(data=data)
    # data_table = DataTable(source=table_source, columns=columns, width=280, height=180, index_position=None)
    # export_png(data_table, filename="table.png")
    # save_table = Button(label='Save Daily Averages Table', button_type="primary")

    # Set up callbacks
    def update_title(attrname, old, new):
        p.title.text = text_title.value

    def update_save(attrname, old, new):
        p.tools[0].save_name = text_save.value

    def update():
        text_dsn.value = text_dsn.value.strip(" ")  # Get rid of extra space
        # Make sure time is valid

        update_data(p,
                    source,
                    source1,
                    source2,
                    source3,
                    source4,
                    source5,
                    df,
                    text_dsn.value,
                    all_dates,
                    date=str(calendar.value))

        # Title/save update dsn
        text_title.value = text_dsn.value + " Data"
        text_save.value = text_dsn.value

    def save():
        export_png(data_table,
                   filename="{}_averages.png".format(text_dsn.value))

    text_title.on_change('value', update_title)
    text_save.on_change('value', update_save)

    button.on_click(update)
    button.js_on_click(CustomJS(args=dict(p=p), code="""p.reset.emit()"""))

    # save_table.on_click(save)

    # Set up layouts and add to document
    inputs = widgetbox(text_title, text_save, calendar,
                       button)  #, table_title, data_table, save_table)

    curdoc().add_root(row(inputs, p, width=1300))
Example #27
0
        'salary': current.salary,
        'years_experience': current.years_experience,
    }


slider = RangeSlider(title="Max Salary",
                     start=10000,
                     end=110000,
                     value=(10000, 50000),
                     step=1000,
                     format="0,0")
slider.on_change('value', lambda attr, old, new: update())

button = Button(label="Download", button_type="success")
button.js_on_click(
    CustomJS(args=dict(source=source),
             code=open(join(dirname(__file__), "download.js")).read()))

columns = [
    TableColumn(field="name", title="Employee Name"),
    TableColumn(field="salary",
                title="Income",
                formatter=NumberFormatter(format="$0,0.00")),
    TableColumn(field="years_experience", title="Experience (years)")
]

data_table = DataTable(source=source, columns=columns, width=800)

controls = column(slider, button)

curdoc().add_root(row(controls, data_table))
Example #28
0
            console.log("Clicked button")
            timeslider.value = timeslider.start
            console.log("Set to beginning")
            step_length_ms = 300
            num_steps = end-1
            inc = 1
            
            playback_interval = setInterval(function(){
                timeslider.value = timeslider.value+inc;
                console.log(timeslider.value);
            }, step_length_ms)
            setTimeout(function(){clearInterval(playback_interval)}, step_length_ms*num_steps)

        """)
    
playbutton.js_on_click(animateSlider)



#################################################### BAR PLOT ####################################################

fruits = ['Apples', 'Pears', 'Nectarines', 'Plums', 'Grapes', 'Strawberries']
counts = [5, 3, 4, 2, 4, 6]

barplot = figure(x_range=fruits, plot_height=250, title="Fruit Counts",
           toolbar_location=None, tools="")

barplot.vbar(x=fruits, top=counts, width=0.9)

barplot.xgrid.grid_line_color = None
barplot.y_range.start = 0
Example #29
0
from bokeh.models import CustomJS
from bokeh.models.layouts import WidgetBox
from bokeh.models.widgets import (
    Button,
    Toggle,
    Dropdown,
    CheckboxGroup,
    RadioGroup,
    CheckboxButtonGroup,
    RadioButtonGroup,
)

button = Button(label="Button (enabled) - has click event",
                button_type="primary")
button.on_click(lambda: print('button: click'))
button.js_on_click(
    CustomJS(code="console.log('button: click', this.toString())"))

button_disabled = Button(label="Button (disabled) - no click event",
                         button_type="primary",
                         disabled=True)
button_disabled.on_click(lambda: print('button_disabled: click'))
button_disabled.js_on_click(
    CustomJS(code="console.log('button_disabled: click', this.toString())"))

toggle_inactive = Toggle(label="Toggle button (initially inactive)",
                         button_type="success")
toggle_inactive.on_click(lambda value: print('toggle_inactive: %s' % value))
toggle_inactive.js_on_click(
    CustomJS(
        code="console.log('toggle_inactive: ' + this.active, this.toString())")
)
Example #30
0

def button2_cb():
    global p
    global mysource
    start = mysource.data["time"][0]
    end = mysource.data["time"][-1]
    p.x_range = DataRange1d(start, end)


def button3_cb():
    print("button3 blick")


p.line(x="time", y="y", source=mysource)
#p.line([1,2,3,4],[1,2,3,4])

button = Button(label="stream")
button.on_click(button_cb)

button2 = Button(label="set something")
button.on_click(button2_cb)

button3 = Button(label="reset")

button3.js_on_click(CustomJS(args=dict(p=p), code="""
    p.reset.emit()
"""))
button3.on_click(button3_cb)
curdoc().add_root(row([p, button, button2, button3]))
curdoc().add_periodic_callback(update, 1000)