def get_select(desc, values, default=None, labels=None): # pylint: disable=unused-argument if default is None: # by default, make all selections active default = list(range(len(values))) if labels is None: labels = list(map(str, values)) # misuse tags to store values without mapping to str group = CheckboxButtonGroup(labels=labels, active=default, tags=values) group.on_change('active', on_filter_change) return group
class RetrievalResultPlot: def __init__(self, z, p, retrieval): self.z = z self.p = p y = z self.retrieval = retrieval self.retrieval_quantities = retrieval.retrieval_quantities self.figures = dict([(rq, ProfilePlot(self.z, self.p, rq.name, "rq_plot_" + rq.name, width=400)) for rq in self.retrieval_quantities]) self.status = dict([(rq, True) for rq in self.retrieval_quantities]) self.sources_x = dict([(rq, []) for rq in self.retrieval_quantities]) self.sources_xa = dict([(rq, []) for rq in self.retrieval_quantities]) self.sources_x0 = dict([(rq, []) for rq in self.retrieval_quantities]) self.lines_x = dict([(rq, []) for rq in self.retrieval_quantities]) self.lines_xa = dict([(rq, []) for rq in self.retrieval_quantities]) self.lines_x0 = dict([(rq, []) for rq in self.retrieval_quantities]) # # Get retrieval results as list. # if type(self.retrieval.results) is list: results = self.retrieval.results else: results = [self.retrieval.results] self.colors = Inferno[len(results) + 2][1:-1] # # Add plots for each retrieval quantity. # for i, rr in enumerate(self.retrieval.results): for rq in self.retrieval_quantities: xa = rr.get_result(rq, attribute="xa") x = rr.get_result(rq, attribute="x") x0 = rr.get_result(rq, attribute="x0") if xa is None: continue self.sources_x[rq] += [ColumnDataSource(data=dict(x=x, y=y))] self.sources_xa[rq] += [ColumnDataSource(data=dict(x=xa, y=y))] self.sources_x0[rq] += [ColumnDataSource(data=dict(x=x0, y=y))] fig = self.figures[rq] fig.add_quantity(x, line_kwargs=dict(line_color=self.colors[i], line_width=2)) if i == 0: fig.add_quantity(xa, line_kwargs=dict( line_dash="dashed", line_color=self.colors[i], line_width=2)) #fig.add_quantity(x0, line_kwargs = dict(line_dash = "dashdot", # line_color = self.colors[i], # line_width = 2)) self.plots = row(*[self.figures[k].doc for k in self.figures], name="retrieval_quantities") def update_plots(attrname, old, new): state = self.checks.active plots = curdoc().get_model_by_name('retrieval_quantities') print(state) for i, rq in enumerate(self.retrieval_quantities): if i in state: if self.status[rq] == True: continue else: self.status[rq] = True plots.children.append(self.figures[rq].doc) else: if self.status[rq] == False: continue else: fig = curdoc().get_model_by_name("rq_plot_" + rq.name) self.status[rq] = False plots.children.remove(fig) print(plots.children) print(self.status) # # Checkbox button to hide plots # labels = [rq.name for rq in self.retrieval.retrieval_quantities] active = list(range(len(labels))) self.checks = CheckboxButtonGroup(labels=labels, active=active) self.checks.on_change("active", update_plots) def make_doc(self): title = Div(text="<h2>Retrieved quantities</h2>") c = column(title, self.checks, self.plots) return c
PROPERTY_TYPE_SELECT = MultiSelect(title='Property Type:', value=[], options=FILTER_PROPERTIES[c.PT]) PROPERTY_TYPE_SELECT.on_change(c.VALUE, update_data) NEIGHBOURHOOD_SELECT = MultiSelect(title='Neighbourhood:', value=[], options=FILTER_PROPERTIES[c.NC]) NEIGHBOURHOOD_SELECT.on_change(c.VALUE, update_data) # Checkbox Group (Multi Select) Widgets NG_LIST = FILTER_PROPERTIES[c.NGC] NEIGHBOURHOOD_GROUP = CheckboxButtonGroup(labels=NG_LIST, active=list(range(0, len(NG_LIST)))) NEIGHBOURHOOD_GROUP.on_change(c.ACTIVE, update_data) RT_LIST = FILTER_PROPERTIES[c.RT] ROOM_TYPE_GROUP = CheckboxButtonGroup(labels=FILTER_PROPERTIES[c.RT], active=list(range(0, len(RT_LIST)))) ROOM_TYPE_GROUP.on_change(c.ACTIVE, update_data) # Single Select Widgets PROPERTY_TYPE_HOST = Select(title='Property Type:', value=c.EMPTY_STRING, options=[c.EMPTY_STRING] + FILTER_PROPERTIES[c.PT]) N_HOST = Select(title='Neighbourhood:', value=c.EMPTY_STRING, options=[c.EMPTY_STRING] + FILTER_PROPERTIES[c.NC]) NG_HOST = Select(title='Neighbourhood Group:', value=c.EMPTY_STRING,
other_source.data = empty_dict if 1 in button_group.active: speed_source.data = gen_dict(speed) else: speed_source.data = empty_dict if 2 in button_group.active: drunk_source.data = gen_dict(drunk) else: drunk_source.data = empty_dict slider.on_change('value', update_hour) toggle.on_change('active', update_hour) button_group.on_change('active', update_hour) callback = CustomJS(args=dict(other=other_circles, speed=speed_circles, drunk=drunk_circles), code=""" other.glyph.radius = { value: cb_obj.get('value')*125 } other.data_source.trigger('change') speed.glyph.radius = { value: cb_obj.get('value')*125 } speed.data_source.trigger('change') drunk.glyph.radius = { value: cb_obj.get('value')*125 } drunk.data_source.trigger('change') """)
('Num.of.flights: ', '@number_of_flights'), ]) tooltips_selected = OrderedDict([ ('Name', '@name'), ]) p.add_tools( HoverTool(tooltips=tooltips, renderers=[circle_renderer])) p.add_tools( HoverTool(tooltips=tooltips_selected, renderers=[circle_renderer_selected])) controls = [reviews, genre, min_year, alpha] for control in controls: control.on_change('value', lambda attr, old, new: update()) cb_group_le10.on_change('active', lambda attr, old, new: update()) cb_group_10_15.on_change('active', lambda attr, old, new: update()) cb_group_15_20.on_change('active', lambda attr, old, new: update()) cb_group_20_25.on_change('active', lambda attr, old, new: update()) cb_group_ge25.on_change('active', lambda attr, old, new: update()) controls.append(cb_group_le10) controls.append(cb_group_10_15) controls.append(cb_group_15_20) controls.append(cb_group_20_25) controls.append(cb_group_ge25) source_hist = ColumnDataSource({'top': [], 'left': [], 'right': []}) p2 = figure(plot_width=800, plot_height=350) p2.title.text = 'Histogram' p2.quad(top='top', bottom=0, left='left', right='right', alpha=0.4, source=source_hist)
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
}) checkbox_button = CheckboxButtonGroup( labels=['Show x-axis label', 'Show y-axis label']) def checkbox_button_click(attr, old, new): active_checkbox = checkbox_button.active ##Getting checkbox value in list ## Get first checkbox value and show x-axis label if len(active_checkbox) != 0 and (0 in active_checkbox): plot_figure.xaxis.axis_label = 'X-Axis' else: plot_figure.xaxis.axis_label = None ## Get second checkbox value and show y-axis label if len(active_checkbox) != 0 and (1 in active_checkbox): plot_figure.yaxis.axis_label = 'Y-Axis' else: plot_figure.yaxis.axis_label = None checkbox_button.on_change('active', checkbox_button_click) layout = row(checkbox_button, plot_figure) curdoc().add_root(layout) curdoc().title = "Checkbox Button Bokeh Server"
s = outputNames[ka] outputs[s]['dsource'].data = dict(x=x, y=y) outputs[s]['lsource'].data = dict(x=[x[0]], y=[y[0]]) outputs[s]['psource'].data = dict(x=numpy.append(x, x[::-1]), y=numpy.append(lowerband, upperband[::-1])) outputs[s]['line'].visible = False outputs[s]['patch'].visible = False outputs[s]['label'].visible = False vsource.data = dict(x=[slider[last['slider']]['value'], slider[last['slider']]['value']], y=[last['vmin'], last['vmax']]) for s in slider: slider[s]['slider'].on_change('value', lambda attrname, old, new, nets=nets, svar=s: update_data(attrname, old, new, nets, svar)) out_buttons.on_change('active', lambda attrname, old, new, nets=nets, svar='__buttons__': update_data(attrname, old, new, nets, svar)) cases_dropdown.on_change('value', lambda attrname, old, new, nets=nets, svar='__cases__': update_data(attrname, old, new, nets, svar)) # Set up layouts and add to document if len(cases)>1: controls = widgetbox(*([cases_dropdown]+[slider[s]['slider'] for s in sorted(list(slider.keys()),key=lambda x:mapper_function(x).lower())])) else: controls = widgetbox(*[slider[s]['slider'] for s in sorted(list(slider.keys()),key=lambda x:mapper_function(x).lower())]) curdoc().add_root(out_buttons) curdoc().add_root(row(controls, column(plot, hold_button))) curdoc().title = title # refresh before starting update_data(None, None, None, nets, list(slider.keys())[0])
def density_tab(doc): def make_dataset(param_list, range_start, range_end, bandwidth): xs = [] ys = [] colors = [] labels = [] for i, param in enumerate(param_list): subset = webs[param].drop(labels=[8]).transpose().iloc[0] # subset = subset.between(range_start,range_end) # subset= webs[(webs[param] >= range_start) and (webs[para] <= range_end)] # subset = webs[param].between(range_start,range_end) #subset = subset[subset[param].between(range_start,range_end)] kde = gaussian_kde(subset, bw_method=bandwidth) # Evenly space x values x = np.linspace(range_start, range_end, 100) y = kde.pdf(x) # Append the values to plot xs.append(list(x)) ys.append(list(y)) # Append the colors and label colors.append(para_colors[i]) labels.append(param) new_src = ColumnDataSource(data={'x':xs, 'y':ys, 'color':colors, 'label':labels}) return new_src def make_plot(src): p = figure(plot_width = 700, plot_height = 700, title = 'Density Plot Parameters', x_axis_label = 'Performance Metric Probability Distribution', y_axis_label = 'Number of Websites') p.multi_line('x', 'y', color = 'color', legend = 'label', line_width = 3, source = src) hover = HoverTool(tooltips=[('parameter','@label'), #('Distribution', '@src'), #('Density', '@ys'), ], line_policy = 'next') p.add_tools(hover) p = style(p) return p def update(attr, old, new): parameters_to_plot = [param_selection.labels[i] for i in param_selection.active] if bandwidth_choose.active == []: bandwidth = None else: bandwidth = bandwidth_select.value new_src = make_dataset(parameters_to_plot, range_start = range_select.value[0], range_end = range_select.value[1], bandwidth = bandwidth) src.data.update(new_src.data) def style(p): # Title p.title.align = 'center' p.title.text_font_size = '20pt' p.title.text_font = 'serif' # Axis titles p.xaxis.axis_label_text_font_size = '14pt' p.xaxis.axis_label_text_font_style = 'bold' p.yaxis.axis_label_text_font_size = '14pt' p.yaxis.axis_label_text_font_style = 'bold' # Tick labels p.xaxis.major_label_text_font_size = '12pt' p.yaxis.major_label_text_font_size = '12pt' return p # Parameter and colors available_parameters = list(webs.columns.get_level_values(0).drop_duplicates())[1:] available_parameters.sort() para_colors = Category20_16 para_colors.sort() param_selection = CheckboxGroup(labels = available_parameters, active = [0,1]) param_selection.on_change('active', update) range_select = RangeSlider(start = 0, end = 1, value = (0,1), step = 0.0025, title = 'Range of Parameter') range_select.on_change('value', update) initial_parameter = [param_selection.labels[i] for i in param_selection.active] # Bandwidth of kernel bandwidth_select = Slider(start = 0.1, end = 5, step = 0.1, value = 0.5, title = 'Bandwidth for Density Plot') bandwidth_select.on_change('value', update) bandwidth_choose = CheckboxButtonGroup( labels = ['Choose Bandwidth (Else Auto)'], active = []) bandwidth_choose.on_change('active', update) # Make the density data source src = make_dataset(initial_parameter, range_start = range_select.value[0], range_end = range_select.value[1], bandwidth = bandwidth_select.value) p = make_plot(src) p = style(p) controls = WidgetBox(param_selection, range_select, bandwidth_select, bandwidth_choose) layout = row(controls, p) doc.title = "Density" doc.add_root(layout)
""" if 0 in nyquist_button.active: reveal_solution() else: hide_solution() # create plots initialize() # add callback behaviour f_input.on_change('value', on_function_changed) sample_fun_input_f.on_change('value', sample_fun_input_changed) t0_input.on_change('value', on_parameters_changed) N_input.on_change('value', on_parameters_changed) nyquist_button.on_change('active', on_nyquist_button_changed) #Description description_filename = join(dirname(__file__), "description.html") description = LatexDiv(text=open(description_filename).read(), render_as_text=False, width=1250) # create layout controls = [f_input, sample_fun_input_f, t0_input, N_input, nyquist_button] controls_box = widgetbox(controls, width=650) # all controls curdoc().add_root( column( description, row(column(plot_original, controls_box),
plot_figure = figure(title='Checkbox Button Group',plot_height=450, plot_width=600, tools="save,reset", toolbar_location="below") plot_figure.scatter('x', 'y', source=source, size=10,color={'field': 'z', 'transform': color_mapper}) checkbox_button = CheckboxButtonGroup(labels=['Show x-axis label','Show y-axis label']) def checkbox_button_click(attr,old,new): active_checkbox=checkbox_button.active ##Getting checkbox value in list ## Get first checkbox value and show x-axis label if len(active_checkbox)!=0 and (0 in active_checkbox): plot_figure.xaxis.axis_label='X-Axis' else: plot_figure.xaxis.axis_label = None ## Get second checkbox value and show y-axis label if len(active_checkbox)!=0 and (1 in active_checkbox): plot_figure.yaxis.axis_label='Y-Axis' else: plot_figure.yaxis.axis_label = None checkbox_button.on_change('active',checkbox_button_click) layout=row(checkbox_button, plot_figure) curdoc().add_root(layout) curdoc().title = "Checkbox Button Bokeh Server"
Set1 = Set1[7] # Create plots, set title title = "Sequence distribution of sample: {}".format(stats['sampleid']) p1 = make_plot_hist(title, stats) p2 = make_plot_kde(title, stats) # Spacer for correct alignments leftmetrics = Spacer(width=500) topwidgetbox = Spacer(width=400, height=50) topmetrics = Spacer(width=600, height=70) # First set of radiobuttons text1 = PreText(text="View histogram for:") buttons1 = CheckboxButtonGroup(name="Active plots:", labels=["Reads", "Contigs", "Genes, complete", "Genes, truncated"], active=[0]) buttons1.on_change('active',update_hist) # Second set of radiobuttons text2 = PreText(text="View KD-estimation for:") buttons2 = CheckboxButtonGroup(name="Active plots:", labels=["Reads", "Contigs", "Genes, complete", "Genes, truncated"], active=[0]) buttons2.on_change('active',update_kde) # Sliders and selection inputs sliderx = Slider(title="X scale", value=0, start=-100, end=100, step=10) yaxis = Select(title="Y axis type", value='log', options=['log','linear']) # Gather controls in controls, put the two figures in tabs and create csv table controls = column(topwidgetbox, widgetbox(text1, buttons1, yaxis, sliderx, text2, buttons2, width=400)) tabs = Tabs(tabs=[p1, p2]) # Metric table (right)
def update(attr, old, new): def sort(attr, old, new): did = False res = [] temp = [] for i in checkbox_button_group.active: for line in range(df_new.shape[0]): #print(df_new[df_new.columns.values[4]][line]) if button_labels[i] == df_new[ df_new.columns.values[4]][line]: temp.append(line) did = True if button_labels[i] == df_new[ df_new.columns.values[5]][line]: temp.append(line) did = True if did == True: res = [ item for item in df_new.index.values.tolist() if item not in temp ] df_new_new = df_new.drop(res).reset_index(drop=True) source.data = { df_new_new.columns.values[column]: df_new_new[df_new_new.columns.values[column]] for column in range(df_new_new.shape[1]) } df_new = df_initial for i in checkbox_group.active: df = pd.read_excel(join(dirname(__file__), 'docs', files[i]), skiprows=5, usecols=[0, 1, 3, 4, 5, 6, 9]) df[df.columns.values[6]] = df[df.columns.values[6]].fillna('') for line in df[df.columns.values[6]].index: if df.loc[line, df.columns.values[6]] != '': df.loc[line, df.columns.values[6]] = ' '.join(directions[i][1:]) df_new = pd.merge(df_new, df, how='outer', on=df.columns.values.tolist()) df_new = df_new.sort_values(by=df_new.columns.values[6], ascending=False) df_new = df_new.drop_duplicates(df_new.columns.values[1], keep='first') df_new = df_new.sort_values(by=df_new.columns.values[0]) df_new = df_new.drop(df_new.columns.values[0], axis=1).reset_index(drop=True) button_labels = pd.concat([ df_new[df_new.columns.values[4]], df_new[df_new.columns.values[5]] ]).unique().tolist() del button_labels[button_labels.index('')] checkbox_button_group = CheckboxButtonGroup(labels=button_labels, width=1000) control_button = widgetbox(checkbox_button_group) l.children[0] = control_button checkbox_button_group.on_change('active', sort) source.data = { df_new.columns.values[column]: df_new[df_new.columns.values[column]] for column in range(df_new.shape[1]) }
line_source.data["num_shootings"][i] for i in selected ] num_offenses = [line_source.data["num_offenses"][i] for i in selected] mean_line.location = mean(num_offenses) mean_shootings.location = mean(num_shootings) def update_graphs(): update_heatmap() update_top10() update_line() selected_months.on_change('value_throttled', lambda attr, old, new: update_graphs()) selected_districts.on_change('active', lambda attr, old, new: update_graphs()) line_source.selected.on_change('indices', lambda attr, old, new: update_selection()) update_graphs() controls = row(widgetbox(selected_months), widgetbox(selected_districts), sizing_mode='stretch_width') curdoc().add_root(controls) curdoc().add_root( layout([[num_offenses, num_shootings], [top10, heatmap]], sizing_mode='stretch_width'))
animals = data['animal'].unique().tolist() animals.sort() animal_select = Select(title='Animal', options=animals, value=animals[0]) animal_select.on_change('value', lambda attr, old, new: animal_changed()) date_select = MultiSelect(title='Dates', size=10) date_select.on_change('value', lambda attr, old, new: update_plot()) groupby_options = { 'masker level': 'masker_level', 'sensation level': 'sens_level', 'target center frequency': 'target_fc', } groupby_select = CheckboxButtonGroup(labels=list(groupby_options.keys()), active=[0]) groupby_select.on_change('active', lambda attr, old, new: update_plot()) animal_trials = ColumnDataSource() animal_trials_plot = figure(title='number of trials', tools="", width=1000, height=150) animal_trials_plot.xaxis.axis_label = 'Session' animal_trials_plot.yaxis.axis_label = 'Number of trials' animal_trials_plot.line('session', 'trials', source=animal_trials) animal_fa = ColumnDataSource() animal_fa_plot = figure(title='False alarm rate', tools="", width=1000, height=150, y_range=(0, 1)) animal_fa_plot.xaxis.axis_label = 'Session' animal_fa_plot.yaxis.axis_label = 'FA rate' animal_fa_plot.line('session', 'fa', source=animal_fa)
def modify_plot(doc): ####################################################################################################################### # Update the checkbox values ## Checkbox for hour of the day values def update_hour(atrr, old, new): data_to_plot = [int(checkbox_group_hour.labels[i]) for i in checkbox_group_hour.active] new_data = data[data.pickup_hour.isin(data_to_plot)] source.data = dict( latp = new_data[latitude_column[0]].tolist(), lonp = new_data[longitude_column[0]].tolist(), latd = new_data[latitude_column[1]].tolist(), lond = new_data[longitude_column[1]].tolist(), size = new_data[size_column].tolist(), color = new_data[color_column].tolist() ) hours = data.pickup_hour.unique().tolist() hours.sort() str1 = [str(i) for i in hours] checkbox_group_hour = CheckboxButtonGroup(labels = str1, active=[0, 1]) ## Adding a slider for the hour also as another option def update_hour_slider(atrr, old, new): hour = slider_hour.value new_data = data[data.pickup_hour == hour] source.data = dict( latp = new_data[latitude_column[0]].tolist(), lonp = new_data[longitude_column[0]].tolist(), latd = new_data[latitude_column[1]].tolist(), lond = new_data[longitude_column[1]].tolist(), size = new_data[size_column].tolist(), color = new_data[color_column].tolist() ) slider_hour = Slider(title='Hour of the day', start = 0, end = 23, step = 1, value = 17) ## Checkbox for weekday values def update_weekday(atrr, old, new): data_to_plot = [checkbox_group_weekday.labels[i] for i in checkbox_group_weekday.active] new_data = data[data.pickup_weekday.isin(data_to_plot)] source.data = dict( latp = new_data[latitude_column[0]].tolist(), lonp = new_data[longitude_column[0]].tolist(), latd = new_data[latitude_column[1]].tolist(), lond = new_data[longitude_column[1]].tolist(), size = new_data[size_column].tolist(), color = new_data[color_column].tolist() ) weekdays = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'] checkbox_group_weekday = CheckboxButtonGroup(labels = weekdays, active=[0, 1]) ######################################################################################################### # CREATE THE PLOT # Assigning map options map_options = GMapOptions(lat = data[latitude_column[0]].mean(), lng = data[longitude_column[0]].mean(), map_type = 'roadmap', zoom = 10) assert len(latitude_column) == len(longitude_column), "latitude and longitude list should be same" # Pickup plot plotP = GMapPlot(x_range = Range1d(), y_range = Range1d(), map_options = map_options, plot_width = 500, plot_height = 400) # Dropoff plot plotD = GMapPlot(x_range = Range1d(), y_range = Range1d(), map_options = map_options, plot_width = 500, plot_height = 400) # ASsigning the Google API keys plotP.api_key = api_key plotD.api_key = api_key source = ColumnDataSource( data = dict( latp = data[latitude_column[0]].tolist(), lonp = data[longitude_column[0]].tolist(), latd = data[latitude_column[1]].tolist(), lond = data[longitude_column[1]].tolist(), size = data[size_column].tolist(), color = data[color_column].tolist() ) ) plotP.title.text = "NYC taxi pickup locations {}".format( data.pickup_datetime.dt.year.unique().tolist()) plotD.title.text = "NYC taxi dropoff locations {}".format( data.dropoff_datetime.dt.year.unique().tolist()) #RdYlGn5, RdBu4 # Add color mapper for the color bar color_mapper = LinearColorMapper(palette = "RdYlGn8", low = np.percentile(data[color_column], 1), high = np.percentile(data[color_column], 99)) # Add the scatter points circleP = Circle(x = "lonp", y = "latp", fill_alpha = 0.8, size = "size", fill_color={'field': 'color', 'transform': color_mapper}, line_color = None) circleD = Circle(x = "lond", y = "latd", fill_alpha = 0.8, size = "size", fill_color={'field': 'color', 'transform': color_mapper}, line_color = None) # Only the user selected scatter points will be highlighted #selected_circle = Circle(fill_alpha = 1) #, fill_color = "firebrick", line_color = None) nonselected_circle = Circle(fill_alpha = 0.1, fill_color = "grey", line_color= None) ############### plotP.add_glyph(source, circleP, nonselection_glyph = nonselected_circle)#, selection_glyph = selected_circle, ) plotD.add_glyph(source, circleD, nonselection_glyph = nonselected_circle)#, selection_glyph = selected_circle, ) # Add color bar. ADding to only one of the plots becaue their x and y axis are scaled together color_bar = ColorBar(color_mapper = color_mapper, ticker = BasicTicker(), label_standoff = 12, border_line_color = None, location = (0,0), title = color_column) plotD.add_layout(color_bar, 'right') # Add the basic interactive tools plotP.add_tools(PanTool(), WheelZoomTool(), BoxSelectTool(), ResetTool(), SaveTool()) plotD.add_tools(PanTool(), WheelZoomTool(), BoxSelectTool(), ResetTool(), SaveTool()) ######################################################################################################### #plots.append(plot) # Keep the ranges same for both plots so that when one plot is zoomed in the other will too # For now switching this off because when zooming in or panning one plot the points in other plot were swaying off # their original geo locations #plotD.x_range = plotP.x_range #plotD.y_range = plotP.y_range # Create the layout with widgets and actual plots if slider: rowl = row(plotP, plotD) layout = column(checkbox_group_weekday, widgetbox(slider_hour), rowl)#) slider_hour.on_change('value', update_hour_slider) else: rowl = row(plotP, plotD) layout = column(checkbox_group_hour, checkbox_group_weekday, rowl)#row(plotP, plotD)) checkbox_group_hour.on_change('active', update_hour) checkbox_group_weekday.on_change('active', update_weekday) # add the layout to curdoc doc.add_root(layout) #output_file("../data/interim/images/interactive_JFK_trips.html") output_notebook()
def modify_doc(symbol): global nearestExpiryDate df = optionUtility.getProcessedOptionChainData(symbol) nearestExpiryDate = optionUtility.nearestExpiryDate expiryDates = [nearestExpiryDate, "All Above"] latestData[symbol] = df allSources = {} def update(attr, old, new): selected_expiryDate = expiry_date_selector.value #selectedStrikePrice = allUniqueStrikePrice[strikePrice_selector.active]; activeStrikePriceIndexes = strikePrice_selector.active # will take top of selected if number is greater activeStrikePriceIndexes.sort() # starting one will be selected index = 0 selectedStrikeNumber = activeStrikePriceIndexes.__sizeof__() processed = [] #print(activeStrikePriceIndexes) for source in allWorkingSources: if (index > (selectedStrikeNumber - 1)): break # in case less number of strike is selected don't through error strikeIndex = activeStrikePriceIndexes[index] selectedStrikePrice = allUniqueStrikePrice[strikeIndex] new_src = 0 new_src = dashboard_tool.make_dataset(int(selectedStrikePrice), selected_expiryDate, symbol, isForTodayOnly) source.data.update(new_src.data) index = index + 1 processed.append(selectedStrikePrice) #print(selectedStrikePrice) # shown prices are these.. #print(processed, activeStrikePriceIndexes); allUniqueStrikePrice = latestData[symbol]['strikePrice'].apply( str).unique().tolist() ATMStrikeindex = int(np.floor(len(allUniqueStrikePrice) / 2)) expiry_date_selector = Select(value=nearestExpiryDate, options=expiryDates) strikePrice_selector = CheckboxButtonGroup( labels=allUniqueStrikePrice, active=[ ATMStrikeindex - 2, ATMStrikeindex - 1, ATMStrikeindex, ATMStrikeindex + 1, ATMStrikeindex + 2 ]) # in case multiple to be shown at once# # strikePrice_selector = RadioButtonGroup( # labels=allUniqueStrikePrice, active=ATMStrikeindex); # strikePrice_selector.on_change('active', update) expiry_date_selector.on_change('value', update) selected_expiryDate = expiry_date_selector.value #selectedStrikePrice = allUniqueStrikePrice[strikePrice_selector.active]; activeStrikePriceIndexes = strikePrice_selector.active allplots = [] allWorkingSources = [] for oneindex in activeStrikePriceIndexes: selectedStrikePrice = allUniqueStrikePrice[oneindex] src = dashboard_tool.make_dataset(int(selectedStrikePrice), selected_expiryDate, symbol, isForTodayOnly) allSources[selectedStrikePrice] = src allWorkingSources.append(src) p = dashboard_tool.make_plot(src, selectedStrikePrice) allplots.append(p) allplotslayout = column(allplots) layout = column(row(expiry_date_selector, strikePrice_selector), allplotslayout) tab = Panel(child=layout, title=symbol) return tab
other_source.data = empty_dict if 1 in button_group.active: speed_source.data = gen_dict(speed) else: speed_source.data = empty_dict if 2 in button_group.active: drunk_source.data = gen_dict(drunk) else: drunk_source.data = empty_dict slider.on_change('value', update_hour) toggle.on_change('active', update_hour) button_group.on_change('active', update_hour) callback = CustomJS(args=dict(other=other_circles, speed=speed_circles, drunk=drunk_circles), code=""" other.glyph.radius = { value: cb_obj.get('value')*125 } other.data_source.trigger('change') speed.glyph.radius = { value: cb_obj.get('value')*125 } speed.data_source.trigger('change') drunk.glyph.radius = { value: cb_obj.get('value')*125 } drunk.data_source.trigger('change') """) size_slider = Slider(title="Dot Size", start=1, end=100, orientation="horizontal", value=100, step=1, callback=callback, callback_policy="mouseup")
types, counts = zip(*sorted(Counter(cars_ar).items())) for i, type_check in enumerate(car_type_list): if type_check in types: count_changer.append(counts[holdcount]) holdcount += 1 else: count_changer.append(0) int_source.data['Count'] = count_changer else: int_source.data['Count'] = np.zeros(7) p.xaxis.major_tick_line_color = None p.xaxis.minor_tick_line_color = None p.yaxis.major_tick_line_color = None p.yaxis.minor_tick_line_color = None p.xaxis.major_label_text_font_size = '0pt' p.yaxis.major_label_text_font_size = '0pt' """ p_int.yaxis.major_label_orientation = np.pi / 2 p_int.xaxis.major_label_orientation = -np.pi / 6 p_int.xaxis.axis_label = 'Traffic Through Select Points (For Given)' """ source.on_change('selected', update) CBG.on_change('active', update) curdoc().add_root(column(row(p, p_int), CBG))
TableColumn(field="rank", title="Global Rank"), TableColumn(field="company", title="Company"), TableColumn(field="freq", title="Frequency Count"), TableColumn(field="london", title="London Registered Company") ] table = DataTable(source=table_source, columns=columns, width=800, sortable=True) years.on_change('value', lambda attr, old, new: update()) months.on_change('value', lambda attr, old, new: update()) data_choice.on_change('active', lambda attr, old, new: update()) cities.on_change('value', lambda attr, old, new: update()) cities2.on_change('value', lambda attr, old, new: update()) london_filter.on_change('active', lambda attr, old, new: update()) topic_choice.on_change('value', lambda attr, old, new: update()) search_word.on_change('value', lambda attr, old, new: update()) pca_slider.on_change('value', lambda attr, old, new: update()) update() ############# # Structure # ############# saplot = column(space, sa_title, p, select) head = row(data_choice, sizing_mode='scale_width') b1 = row(london_filter, london_filter_txt) b = column(space, space, sacity_title, sizing_mode='scale_width') mid = row(cities, cities2)
class Query: def __init__(self, sources, categories, dvhs, rad_bio, roi_viewer, time_series, correlation, regression, mlc_analyzer, custom_title, data_tables): self.sources = sources self.selector_categories = categories.selector self.range_categories = categories.range self.correlation_variables = categories.correlation_variables self.dvhs = dvhs self.rad_bio = rad_bio self.roi_viewer = roi_viewer self.time_series = time_series self.correlation = correlation self.regression = regression self.mlc_analyzer = mlc_analyzer self.uids = {n: [] for n in GROUP_LABELS} self.allow_source_update = True self.current_dvh = [] self.anon_id_map = [] self.colors = itertools.cycle(palette) # !!!!!!!!!!!!!!!!!!!!!!!!!!!! # Selection Filter UI objects # !!!!!!!!!!!!!!!!!!!!!!!!!!!! category_options = list(self.selector_categories) category_options.sort() # Add Current row to source self.add_selector_row_button = Button(label="Add Selection Filter", button_type="primary", width=200) self.add_selector_row_button.on_click(self.add_selector_row) # Row self.selector_row = Select(value='1', options=['1'], width=50, title="Row") self.selector_row.on_change('value', self.selector_row_ticker) # Category 1 self.select_category1 = Select(value="ROI Institutional Category", options=category_options, width=300, title="Category 1") self.select_category1.on_change('value', self.select_category1_ticker) # Category 2 cat_2_sql_table = self.selector_categories[ self.select_category1.value]['table'] cat_2_var_name = self.selector_categories[ self.select_category1.value]['var_name'] self.category2_values = DVH_SQL().get_unique_values( cat_2_sql_table, cat_2_var_name) self.select_category2 = Select(value=self.category2_values[0], options=self.category2_values, width=300, title="Category 2") self.select_category2.on_change('value', self.select_category2_ticker) # Misc self.delete_selector_row_button = Button(label="Delete", button_type="warning", width=100) self.delete_selector_row_button.on_click(self.delete_selector_row) self.group_selector = CheckboxButtonGroup( labels=["Group 1", "Group 2"], active=[0], width=180) self.group_selector.on_change('active', self.ensure_selector_group_is_assigned) self.selector_not_operator_checkbox = CheckboxGroup(labels=['Not'], active=[]) self.selector_not_operator_checkbox.on_change( 'active', self.selector_not_operator_ticker) # !!!!!!!!!!!!!!!!!!!!!!!!!!!! # Range Filter UI objects # !!!!!!!!!!!!!!!!!!!!!!!!!!!! category_options = list(self.range_categories) category_options.sort() # Add Current row to source self.add_range_row_button = Button(label="Add Range Filter", button_type="primary", width=200) self.add_range_row_button.on_click(self.add_range_row) # Row self.range_row = Select(value='', options=[''], width=50, title="Row") self.range_row.on_change('value', self.range_row_ticker) # Category self.select_category = Select(value=options.SELECT_CATEGORY_DEFAULT, options=category_options, width=240, title="Category") self.select_category.on_change('value', self.select_category_ticker) # Min and max self.text_min = TextInput(value='', title='Min: ', width=150) self.text_min.on_change('value', self.min_text_ticker) self.text_max = TextInput(value='', title='Max: ', width=150) self.text_max.on_change('value', self.max_text_ticker) # Misc self.delete_range_row_button = Button(label="Delete", button_type="warning", width=100) self.delete_range_row_button.on_click(self.delete_range_row) self.group_range = CheckboxButtonGroup(labels=["Group 1", "Group 2"], active=[0], width=180) self.group_range.on_change('active', self.ensure_range_group_is_assigned) self.range_not_operator_checkbox = CheckboxGroup(labels=['Not'], active=[]) self.range_not_operator_checkbox.on_change( 'active', self.range_not_operator_ticker) self.query_button = Button(label="Query", button_type="success", width=100) self.query_button.on_click(self.update_data) # define Download button and call download.js on click menu = [("All Data", "all"), ("Lite", "lite"), ("Only DVHs", "dvhs"), ("Anonymized DVHs", "anon_dvhs")] self.download_dropdown = Dropdown(label="Download", button_type="default", menu=menu, width=100) self.download_dropdown.callback = CustomJS( args=dict(source=sources.dvhs, source_rxs=sources.rxs, source_plans=sources.plans, source_beams=sources.beams), code=open(join(dirname(dirname(__file__)), "download.js")).read()) self.layout = column( Div(text="<b>DVH Analytics v%s</b>" % '0.5.10'), row(custom_title['1']['query'], Spacer(width=50), custom_title['2']['query'], Spacer(width=50), self.query_button, Spacer(width=50), self.download_dropdown), Div(text="<b>Query by Categorical Data</b>", width=1000), self.add_selector_row_button, row(self.selector_row, Spacer(width=10), self.select_category1, self.select_category2, self.group_selector, self.delete_selector_row_button, Spacer(width=10), self.selector_not_operator_checkbox), data_tables.selection_filter, Div(text="<hr>", width=1050), Div(text="<b>Query by Numerical Data</b>", width=1000), self.add_range_row_button, row(self.range_row, Spacer(width=10), self.select_category, self.text_min, Spacer(width=30), self.text_max, Spacer(width=30), self.group_range, self.delete_range_row_button, Spacer(width=10), self.range_not_operator_checkbox), data_tables.range_filter) def get_query(self, group=None): if group: if group == 1: active_groups = [1] elif group == 2: active_groups = [2] else: active_groups = [1, 2] # Used to accumulate lists of query strings for each table # Will assume each item in list is complete query for that SQL column queries = {'Plans': [], 'Rxs': [], 'Beams': [], 'DVHs': []} # Used to group queries by variable, will combine all queries of same variable with an OR operator # e.g., queries_by_sql_column['Plans'][key] = list of strings, where key is sql column queries_by_sql_column = { 'Plans': {}, 'Rxs': {}, 'Beams': {}, 'DVHs': {} } for active_group in active_groups: # Accumulate categorical query strings data = self.sources.selectors.data for r in data['row']: r = int(r) if data['group'][r - 1] in {active_group, 3}: var_name = self.selector_categories[data['category1'][ r - 1]]['var_name'] table = self.selector_categories[data['category1'][ r - 1]]['table'] value = data['category2'][r - 1] if data['not_status'][r - 1]: operator = "!=" else: operator = "=" query_str = "%s %s '%s'" % (var_name, operator, value) # Append query_str in query_by_sql_column if var_name not in queries_by_sql_column[table].keys(): queries_by_sql_column[table][var_name] = [] queries_by_sql_column[table][var_name].append(query_str) # Accumulate numerical query strings data = self.sources.ranges.data for r in data['row']: r = int(r) if data['group'][r - 1] in {active_group, 3}: var_name = self.range_categories[data['category'][ r - 1]]['var_name'] table = self.range_categories[data['category'][r - 1]]['table'] value_low, value_high = data['min'][r - 1], data['max'][r - 1] if data['category'][r - 1] != 'Simulation Date': value_low, value_high = float(value_low), float( value_high) # Modify value_low and value_high so SQL interprets values as dates, if applicable if var_name in {'sim_study_date', 'birth_date'}: value_low = "'%s'" % value_low value_high = "'%s'" % value_high if data['not_status'][r - 1]: query_str = var_name + " NOT BETWEEN " + str( value_low) + " AND " + str(value_high) else: query_str = var_name + " BETWEEN " + str( value_low) + " AND " + str(value_high) # Append query_str in query_by_sql_column if var_name not in queries_by_sql_column[table]: queries_by_sql_column[table][var_name] = [] queries_by_sql_column[table][var_name].append(query_str) for table in queries: temp_str = [] for v in queries_by_sql_column[table].keys(): # collect all constraints for a given sql column into one list q_by_sql_col = [q for q in queries_by_sql_column[table][v]] # combine all constraints for a given sql column with 'or' operators temp_str.append("(%s)" % ' OR '.join(q_by_sql_col)) queries[table] = ' AND '.join(temp_str) print(str(datetime.now()), '%s = %s' % (table, queries[table]), sep=' ') # Get a list of UIDs that fit the plan, rx, and beam query criteria. DVH query criteria will not alter the # list of UIDs, therefore dvh_query is not needed to get the UID list print(str(datetime.now()), 'getting uids', sep=' ') uids = get_study_instance_uids(plans=queries['Plans'], rxs=queries['Rxs'], beams=queries['Beams'])['union'] # uids: a unique list of all uids that satisfy the criteria # queries['DVHs']: the dvh query string for SQL return uids, queries['DVHs'] # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! # Functions for Querying by categorical data # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! def update_select_category2_values(self): new = self.select_category1.value table_new = self.selector_categories[new]['table'] var_name_new = self.selector_categories[new]['var_name'] new_options = DVH_SQL().get_unique_values(table_new, var_name_new) self.select_category2.options = new_options self.select_category2.value = new_options[0] def ensure_selector_group_is_assigned(self, attr, old, new): if not self.group_selector.active: self.group_selector.active = [-old[0] + 1] self.update_selector_source() def update_selector_source(self): if self.selector_row.value: r = int(self.selector_row.value) - 1 group = sum([i + 1 for i in self.group_selector.active]) group_labels = ['1', '2', '1 & 2'] group_label = group_labels[group - 1] not_status = ['', 'Not' ][len(self.selector_not_operator_checkbox.active)] patch = { 'category1': [(r, self.select_category1.value)], 'category2': [(r, self.select_category2.value)], 'group': [(r, group)], 'group_label': [(r, group_label)], 'not_status': [(r, not_status)] } self.sources.selectors.patch(patch) def add_selector_row(self): if self.sources.selectors.data['row']: temp = self.sources.selectors.data for key in list(temp): temp[key].append('') temp['row'][-1] = len(temp['row']) self.sources.selectors.data = temp new_options = [str(x + 1) for x in range(len(temp['row']))] self.selector_row.options = new_options self.selector_row.value = new_options[-1] self.select_category1.value = options.SELECT_CATEGORY1_DEFAULT self.select_category2.value = self.select_category2.options[0] self.selector_not_operator_checkbox.active = [] else: self.selector_row.options = ['1'] self.selector_row.value = '1' self.sources.selectors.data = dict(row=[1], category1=[''], category2=[''], group=[], group_label=[''], not_status=['']) self.update_selector_source() clear_source_selection(self.sources, 'selectors') def select_category1_ticker(self, attr, old, new): self.update_select_category2_values() self.update_selector_source() def select_category2_ticker(self, attr, old, new): self.update_selector_source() def selector_not_operator_ticker(self, attr, old, new): self.update_selector_source() def selector_row_ticker(self, attr, old, new): if self.sources.selectors.data[ 'category1'] and self.sources.selectors.data['category1'][-1]: r = int(self.selector_row.value) - 1 category1 = self.sources.selectors.data['category1'][r] category2 = self.sources.selectors.data['category2'][r] group = self.sources.selectors.data['group'][r] not_status = self.sources.selectors.data['not_status'][r] self.select_category1.value = category1 self.select_category2.value = category2 self.group_selector.active = [[0], [1], [0, 1]][group - 1] if not_status: self.selector_not_operator_checkbox.active = [0] else: self.selector_not_operator_checkbox.active = [] def update_selector_row_on_selection(self, attr, old, new): if new: self.selector_row.value = self.selector_row.options[min(new)] def delete_selector_row(self): if self.selector_row.value: new_selectors_source = self.sources.selectors.data index_to_delete = int(self.selector_row.value) - 1 new_source_length = len( self.sources.selectors.data['category1']) - 1 if new_source_length == 0: clear_source_data(self.sources, 'selector') self.selector_row.options = [''] self.selector_row.value = '' self.group_selector.active = [0] self.selector_not_operator_checkbox.active = [] self.select_category1.value = options.SELECT_CATEGORY1_DEFAULT self.select_category2.value = self.select_category2.options[0] else: for key in list(new_selectors_source): new_selectors_source[key].pop(index_to_delete) for i in range(index_to_delete, new_source_length): new_selectors_source['row'][i] -= 1 self.selector_row.options = [ str(x + 1) for x in range(new_source_length) ] if self.selector_row.value not in self.selector_row.options: self.selector_row.value = self.selector_row.options[-1] self.sources.selectors.data = new_selectors_source clear_source_selection(self.sources, 'selectors') # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! # Functions for Querying by numerical data # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! def add_range_row(self): if self.sources.ranges.data['row']: temp = self.sources.ranges.data for key in list(temp): temp[key].append('') temp['row'][-1] = len(temp['row']) self.sources.ranges.data = temp new_options = [str(x + 1) for x in range(len(temp['row']))] self.range_row.options = new_options self.range_row.value = new_options[-1] self.select_category.value = options.SELECT_CATEGORY_DEFAULT self.group_range.active = [0] self.range_not_operator_checkbox.active = [] else: self.range_row.options = ['1'] self.range_row.value = '1' self.sources.ranges.data = dict(row=['1'], category=[''], min=[''], max=[''], min_display=[''], max_display=[''], group=[''], group_label=[''], not_status=['']) self.update_range_titles(reset_values=True) self.update_range_source() clear_source_selection(self.sources, 'ranges') def update_range_source(self): if self.range_row.value: table = self.range_categories[self.select_category.value]['table'] var_name = self.range_categories[ self.select_category.value]['var_name'] r = int(self.range_row.value) - 1 group = sum([i + 1 for i in self.group_range.active ]) # a result of 3 means group 1 & 2 group_labels = ['1', '2', '1 & 2'] group_label = group_labels[group - 1] not_status = ['', 'Not'][len(self.range_not_operator_checkbox.active)] if self.select_category.value == 'Simulation Date': min_value = str(parse(self.text_min.value).date()) min_display = min_value max_value = str(parse(self.text_max.value).date()) max_display = max_value else: try: min_value = float(self.text_min.value) except ValueError: try: min_value = float(DVH_SQL().get_min_value( table, var_name)) except TypeError: min_value = '' try: max_value = float(self.text_max.value) except ValueError: try: max_value = float(DVH_SQL().get_max_value( table, var_name)) except TypeError: max_value = '' if min_value or min_value == 0.: min_display = "%s %s" % ( str(min_value), self.range_categories[ self.select_category.value]['units']) else: min_display = 'None' if max_value or max_value == 0.: max_display = "%s %s" % ( str(max_value), self.range_categories[ self.select_category.value]['units']) else: max_display = 'None' patch = { 'category': [(r, self.select_category.value)], 'min': [(r, min_value)], 'max': [(r, max_value)], 'min_display': [(r, min_display)], 'max_display': [(r, max_display)], 'group': [(r, group)], 'group_label': [(r, group_label)], 'not_status': [(r, not_status)] } self.sources.ranges.patch(patch) self.group_range.active = [[0], [1], [0, 1]][group - 1] self.text_min.value = str(min_value) self.text_max.value = str(max_value) def update_range_titles(self, reset_values=False): table = self.range_categories[self.select_category.value]['table'] var_name = self.range_categories[ self.select_category.value]['var_name'] min_value = DVH_SQL().get_min_value(table, var_name) self.text_min.title = 'Min: ' + str( min_value) + ' ' + self.range_categories[ self.select_category.value]['units'] max_value = DVH_SQL().get_max_value(table, var_name) self.text_max.title = 'Max: ' + str( max_value) + ' ' + self.range_categories[ self.select_category.value]['units'] if reset_values: self.text_min.value = str(min_value) self.text_max.value = str(max_value) def range_row_ticker(self, attr, old, new): if self.sources.ranges.data['category'] and self.sources.ranges.data[ 'category'][-1]: r = int(new) - 1 category = self.sources.ranges.data['category'][r] min_new = self.sources.ranges.data['min'][r] max_new = self.sources.ranges.data['max'][r] group = self.sources.ranges.data['group'][r] not_status = self.sources.ranges.data['not_status'][r] self.allow_source_update = False self.select_category.value = category self.text_min.value = str(min_new) self.text_max.value = str(max_new) self.update_range_titles() self.group_range.active = [[0], [1], [0, 1]][group - 1] self.allow_source_update = True if not_status: self.range_not_operator_checkbox.active = [0] else: self.range_not_operator_checkbox.active = [] def select_category_ticker(self, attr, old, new): if self.allow_source_update: self.update_range_titles(reset_values=True) self.update_range_source() def min_text_ticker(self, attr, old, new): if self.allow_source_update: self.update_range_source() def max_text_ticker(self, attr, old, new): if self.allow_source_update: self.update_range_source() def range_not_operator_ticker(self, attr, old, new): if self.allow_source_update: self.update_range_source() def delete_range_row(self): if self.range_row.value: new_range_source = self.sources.ranges.data index_to_delete = int(self.range_row.value) - 1 new_source_length = len(self.sources.ranges.data['category']) - 1 if new_source_length == 0: clear_source_data(self.sources, 'ranges') self.range_row.options = [''] self.range_row.value = '' self.group_range.active = [0] self.range_not_operator_checkbox.active = [] self.select_category.value = options.SELECT_CATEGORY_DEFAULT self.text_min.value = '' self.text_max.value = '' else: for key in list(new_range_source): new_range_source[key].pop(index_to_delete) for i in range(index_to_delete, new_source_length): new_range_source['row'][i] -= 1 self.range_row.options = [ str(x + 1) for x in range(new_source_length) ] if self.range_row.value not in self.range_row.options: self.range_row.value = self.range_row.options[-1] self.sources.ranges.data = new_range_source clear_source_selection(self.sources, 'ranges') def ensure_range_group_is_assigned(self, attr, old, new): if not self.group_range.active: self.group_range.active = [-old[0] + 1] self.update_range_source() def update_range_row_on_selection(self, attr, old, new): if new: self.range_row.value = self.range_row.options[min(new)] # main update function def update_data(self): global BAD_UID BAD_UID = {n: [] for n in GROUP_LABELS} old_update_button_label = self.query_button.label old_update_button_type = self.query_button.button_type self.query_button.label = 'Updating...' self.query_button.button_type = 'warning' print(str(datetime.now()), 'Constructing query for complete dataset', sep=' ') uids, dvh_query_str = self.get_query() print(str(datetime.now()), 'getting dvh data', sep=' ') self.current_dvh = DVH(uid=uids, dvh_condition=dvh_query_str) if self.current_dvh.count: print(str(datetime.now()), 'initializing source data ', self.current_dvh.query, sep=' ') self.time_series.update_current_dvh_group( self.update_dvh_data(self.current_dvh)) if not options.LITE_VIEW and \ (options.OPTIONAL_TABS['Time-Series'] or options.OPTIONAL_TABS['Correlation'] or options.OPTIONAL_TABS['Regression']): print(str(datetime.now()), 'updating correlation data') self.correlation.update_data(self.correlation_variables) print(str(datetime.now()), 'correlation data updated') self.dvhs.update_source_endpoint_calcs() if not options.LITE_VIEW: self.dvhs.calculate_review_dvh() self.rad_bio.initialize() self.time_series.y_axis.value = '' self.roi_viewer.update_mrn() try: self.mlc_analyzer.update_mrn() except: pass else: print(str(datetime.now()), 'empty dataset returned', sep=' ') self.query_button.label = 'No Data' self.query_button.button_type = 'danger' time.sleep(2.5) self.query_button.label = old_update_button_label self.query_button.button_type = old_update_button_type # updates beam ColumnSourceData for a given list of uids def update_beam_data(self, uids): cond_str = "study_instance_uid in ('" + "', '".join(uids) + "')" beam_data = QuerySQL('Beams', cond_str) groups = self.get_group_list(beam_data.study_instance_uid) anon_id = [ self.anon_id_map[beam_data.mrn[i]] for i in range(len(beam_data.mrn)) ] attributes = [ 'mrn', 'beam_dose', 'beam_energy_min', 'beam_energy_max', 'beam_mu', 'beam_mu_per_deg', 'beam_mu_per_cp', 'beam_name', 'beam_number', 'beam_type', 'scan_mode', 'scan_spot_count', 'control_point_count', 'fx_count', 'fx_grp_beam_count', 'fx_grp_number', 'gantry_start', 'gantry_end', 'gantry_rot_dir', 'gantry_range', 'gantry_min', 'gantry_max', 'collimator_start', 'collimator_end', 'collimator_rot_dir', 'collimator_range', 'collimator_min', 'collimator_max', 'couch_start', 'couch_end', 'couch_rot_dir', 'couch_range', 'couch_min', 'couch_max', 'radiation_type', 'ssd', 'treatment_machine' ] for i in ['min', 'mean', 'median', 'max']: for j in ['area', 'complexity', 'cp_mu', 'x_perim', 'y_perim']: attributes.append('%s_%s' % (j, i)) data = {attr: getattr(beam_data, attr) for attr in attributes} data['anon_id'] = anon_id data['group'] = groups if len(data['group']) != len(data['anon_id']): data['group'] = ['unknown'] * len(data['anon_id']) data['uid'] = beam_data.study_instance_uid self.sources.beams.data = data # updates plan ColumnSourceData for a given list of uids def update_plan_data(self, uids): cond_str = "study_instance_uid in ('" + "', '".join(uids) + "')" plan_data = QuerySQL('Plans', cond_str) # Determine Groups groups = self.get_group_list(plan_data.study_instance_uid) anon_id = [ self.anon_id_map[plan_data.mrn[i]] for i in range(len(plan_data.mrn)) ] attributes = [ 'mrn', 'age', 'birth_date', 'dose_grid_res', 'fxs', 'patient_orientation', 'patient_sex', 'physician', 'rx_dose', 'sim_study_date', 'total_mu', 'tx_modality', 'tx_site', 'heterogeneity_correction', 'complexity' ] data = {attr: getattr(plan_data, attr) for attr in attributes} data['anon_id'] = anon_id data['group'] = groups data['uid'] = plan_data.study_instance_uid self.sources.plans.data = data # updates rx ColumnSourceData for a given list of uids def update_rx_data(self, uids): cond_str = "study_instance_uid in ('" + "', '".join(uids) + "')" rx_data = QuerySQL('Rxs', cond_str) groups = self.get_group_list(rx_data.study_instance_uid) anon_id = [ self.anon_id_map[rx_data.mrn[i]] for i in range(len(rx_data.mrn)) ] attributes = [ 'mrn', 'plan_name', 'fx_dose', 'rx_percent', 'fxs', 'rx_dose', 'fx_grp_count', 'fx_grp_name', 'fx_grp_number', 'normalization_method', 'normalization_object' ] data = {attr: getattr(rx_data, attr) for attr in attributes} data['anon_id'] = anon_id data['group'] = groups data['uid'] = rx_data.study_instance_uid self.sources.rxs.data = data def get_group_list(self, uids): groups = [] for r in range(len(uids)): if uids[r] in self.uids['1']: if uids[r] in self.uids['2']: groups.append('Group 1 & 2') else: groups.append('Group 1') else: groups.append('Group 2') return groups def update_dvh_data(self, dvh): dvh_group_1, dvh_group_2 = [], [] group_1_constraint_count, group_2_constraint_count = group_constraint_count( self.sources) if group_1_constraint_count and group_2_constraint_count: extra_rows = 12 elif group_1_constraint_count or group_2_constraint_count: extra_rows = 6 else: extra_rows = 0 print(str(datetime.now()), 'updating dvh data', sep=' ') line_colors = [ color for j, color in itertools.izip(range(dvh.count + extra_rows), self.colors) ] x_axis = np.round( np.add(np.linspace(0, dvh.bin_count, dvh.bin_count) / 100., 0.005), 3) print(str(datetime.now()), 'beginning stat calcs', sep=' ') if self.dvhs.radio_group_dose.active == 1: stat_dose_scale = 'relative' x_axis_stat = dvh.get_resampled_x_axis() else: stat_dose_scale = 'absolute' x_axis_stat = x_axis if self.dvhs.radio_group_volume.active == 0: stat_volume_scale = 'absolute' else: stat_volume_scale = 'relative' print(str(datetime.now()), 'calculating patches', sep=' ') if group_1_constraint_count == 0: self.uids['1'] = [] clear_source_data(self.sources, 'patch_1') clear_source_data(self.sources, 'stats_1') else: print(str(datetime.now()), 'Constructing Group 1 query', sep=' ') self.uids['1'], dvh_query_str = self.get_query(group=1) dvh_group_1 = DVH(uid=self.uids['1'], dvh_condition=dvh_query_str) self.uids['1'] = dvh_group_1.study_instance_uid stat_dvhs_1 = dvh_group_1.get_standard_stat_dvh( dose_scale=stat_dose_scale, volume_scale=stat_volume_scale) if self.dvhs.radio_group_dose.active == 1: x_axis_1 = dvh_group_1.get_resampled_x_axis() else: x_axis_1 = np.add( np.linspace(0, dvh_group_1.bin_count, dvh_group_1.bin_count) / 100., 0.005) self.sources.patch_1.data = { 'x_patch': np.append(x_axis_1, x_axis_1[::-1]).tolist(), 'y_patch': np.append(stat_dvhs_1['q3'], stat_dvhs_1['q1'][::-1]).tolist() } self.sources.stats_1.data = { 'x': x_axis_1.tolist(), 'min': stat_dvhs_1['min'].tolist(), 'q1': stat_dvhs_1['q1'].tolist(), 'mean': stat_dvhs_1['mean'].tolist(), 'median': stat_dvhs_1['median'].tolist(), 'q3': stat_dvhs_1['q3'].tolist(), 'max': stat_dvhs_1['max'].tolist() } if group_2_constraint_count == 0: self.uids['2'] = [] clear_source_data(self.sources, 'patch_2') clear_source_data(self.sources, 'stats_2') else: print(str(datetime.now()), 'Constructing Group 2 query', sep=' ') self.uids['2'], dvh_query_str = self.get_query(group=2) dvh_group_2 = DVH(uid=self.uids['2'], dvh_condition=dvh_query_str) self.uids['2'] = dvh_group_2.study_instance_uid stat_dvhs_2 = dvh_group_2.get_standard_stat_dvh( dose_scale=stat_dose_scale, volume_scale=stat_volume_scale) if self.dvhs.radio_group_dose.active == 1: x_axis_2 = dvh_group_2.get_resampled_x_axis() else: x_axis_2 = np.add( np.linspace(0, dvh_group_2.bin_count, dvh_group_2.bin_count) / 100., 0.005) self.sources.patch_2.data = { 'x_patch': np.append(x_axis_2, x_axis_2[::-1]).tolist(), 'y_patch': np.append(stat_dvhs_2['q3'], stat_dvhs_2['q1'][::-1]).tolist() } self.sources.stats_2.data = { 'x': x_axis_2.tolist(), 'min': stat_dvhs_2['min'].tolist(), 'q1': stat_dvhs_2['q1'].tolist(), 'mean': stat_dvhs_2['mean'].tolist(), 'median': stat_dvhs_2['median'].tolist(), 'q3': stat_dvhs_2['q3'].tolist(), 'max': stat_dvhs_2['max'].tolist() } print(str(datetime.now()), 'patches calculated', sep=' ') if self.dvhs.radio_group_dose.active == 0: x_scale = ['Gy'] * (dvh.count + extra_rows + 1) self.dvhs.plot.xaxis.axis_label = "Dose (Gy)" else: x_scale = ['%RxDose'] * (dvh.count + extra_rows + 1) self.dvhs.plot.xaxis.axis_label = "Relative Dose (to Rx)" if self.dvhs.radio_group_volume.active == 0: y_scale = ['cm^3'] * (dvh.count + extra_rows + 1) self.dvhs.plot.yaxis.axis_label = "Absolute Volume (cc)" else: y_scale = ['%Vol'] * (dvh.count + extra_rows + 1) self.dvhs.plot.yaxis.axis_label = "Relative Volume" # new_endpoint_columns = [''] * (dvh.count + extra_rows + 1) x_data, y_data = [], [] for n in range(dvh.count): if self.dvhs.radio_group_dose.active == 0: x_data.append(x_axis.tolist()) else: x_data.append(np.divide(x_axis, dvh.rx_dose[n]).tolist()) if self.dvhs.radio_group_volume.active == 0: y_data.append( np.multiply(dvh.dvh[:, n], dvh.volume[n]).tolist()) else: y_data.append(dvh.dvh[:, n].tolist()) y_names = ['Max', 'Q3', 'Median', 'Mean', 'Q1', 'Min'] # Determine Population group (blue (1) or red (2)) dvh_groups = [] for r in range(len(dvh.study_instance_uid)): current_uid = dvh.study_instance_uid[r] current_roi = dvh.roi_name[r] if dvh_group_1: for r1 in range(len(dvh_group_1.study_instance_uid)): if dvh_group_1.study_instance_uid[ r1] == current_uid and dvh_group_1.roi_name[ r1] == current_roi: dvh_groups.append('Group 1') if dvh_group_2: for r2 in range(len(dvh_group_2.study_instance_uid)): if dvh_group_2.study_instance_uid[ r2] == current_uid and dvh_group_2.roi_name[ r2] == current_roi: if len(dvh_groups) == r + 1: dvh_groups[r] = 'Group 1 & 2' else: dvh_groups.append('Group 2') if len(dvh_groups) < r + 1: dvh_groups.append('error') dvh_groups.insert(0, 'Review') for n in range(6): if group_1_constraint_count > 0: dvh.mrn.append(y_names[n]) dvh.roi_name.append('N/A') x_data.append(x_axis_stat.tolist()) current = stat_dvhs_1[y_names[n].lower()].tolist() y_data.append(current) dvh_groups.append('Group 1') if group_2_constraint_count > 0: dvh.mrn.append(y_names[n]) dvh.roi_name.append('N/A') x_data.append(x_axis_stat.tolist()) current = stat_dvhs_2[y_names[n].lower()].tolist() y_data.append(current) dvh_groups.append('Group 2') # Adjust dvh object to include stats data attributes = [ 'rx_dose', 'volume', 'surface_area', 'min_dose', 'mean_dose', 'max_dose', 'dist_to_ptv_min', 'dist_to_ptv_median', 'dist_to_ptv_mean', 'dist_to_ptv_max', 'dist_to_ptv_centroids', 'ptv_overlap', 'cross_section_max', 'cross_section_median', 'spread_x', 'spread_y', 'spread_z', 'toxicity_grade' ] if extra_rows > 0: dvh.study_instance_uid.extend(['N/A'] * extra_rows) dvh.institutional_roi.extend(['N/A'] * extra_rows) dvh.physician_roi.extend(['N/A'] * extra_rows) dvh.roi_type.extend(['Stat'] * extra_rows) if group_1_constraint_count > 0: for attr in attributes: getattr(dvh, attr).extend(calc_stats(getattr(dvh_group_1, attr))) if group_2_constraint_count > 0: for attr in attributes: getattr(dvh, attr).extend(calc_stats(getattr(dvh_group_2, attr))) # Adjust dvh object for review dvh dvh.dvh = np.insert(dvh.dvh, 0, 0, 1) dvh.count += 1 dvh.mrn.insert(0, self.dvhs.select_reviewed_mrn.value) dvh.study_instance_uid.insert(0, '') dvh.institutional_roi.insert(0, '') dvh.physician_roi.insert(0, '') dvh.roi_name.insert(0, self.dvhs.select_reviewed_dvh.value) dvh.roi_type.insert(0, 'Review') dvh.rx_dose.insert(0, 0) dvh.volume.insert(0, 0) dvh.surface_area.insert(0, '') dvh.min_dose.insert(0, '') dvh.mean_dose.insert(0, '') dvh.max_dose.insert(0, '') dvh.dist_to_ptv_min.insert(0, 'N/A') dvh.dist_to_ptv_mean.insert(0, 'N/A') dvh.dist_to_ptv_median.insert(0, 'N/A') dvh.dist_to_ptv_max.insert(0, 'N/A') dvh.dist_to_ptv_centroids.insert(0, 'N/A') dvh.ptv_overlap.insert(0, 'N/A') dvh.cross_section_max.insert(0, 'N/A') dvh.cross_section_median.insert(0, 'N/A') dvh.spread_x.insert(0, 'N/A') dvh.spread_y.insert(0, 'N/A') dvh.spread_z.insert(0, 'N/A') dvh.toxicity_grade.insert(0, -1) line_colors.insert(0, options.REVIEW_DVH_COLOR) x_data.insert(0, [0]) y_data.insert(0, [0]) # anonymize ids self.anon_id_map = {mrn: i for i, mrn in enumerate(list(set(dvh.mrn)))} anon_id = [self.anon_id_map[dvh.mrn[i]] for i in range(len(dvh.mrn))] print(str(datetime.now()), "writing sources.dvhs.data", sep=' ') groups = [['unknown'] * len(dvh.mrn), dvh_groups][len(dvh.mrn) == len(dvh_groups)] self.sources.dvhs.data = { 'mrn': dvh.mrn, 'anon_id': anon_id, 'group': groups, 'uid': dvh.study_instance_uid, 'roi_institutional': dvh.institutional_roi, 'roi_physician': dvh.physician_roi, 'roi_name': dvh.roi_name, 'roi_type': dvh.roi_type, 'rx_dose': dvh.rx_dose, 'volume': dvh.volume, 'surface_area': dvh.surface_area, 'min_dose': dvh.min_dose, 'mean_dose': dvh.mean_dose, 'max_dose': dvh.max_dose, 'dist_to_ptv_min': dvh.dist_to_ptv_min, 'dist_to_ptv_mean': dvh.dist_to_ptv_mean, 'dist_to_ptv_median': dvh.dist_to_ptv_median, 'dist_to_ptv_max': dvh.dist_to_ptv_max, 'dist_to_ptv_centroids': dvh.dist_to_ptv_centroids, 'ptv_overlap': dvh.ptv_overlap, 'cross_section_max': dvh.cross_section_max, 'cross_section_median': dvh.cross_section_median, 'spread_x': dvh.spread_x, 'spread_y': dvh.spread_y, 'spread_z': dvh.spread_z, 'x': x_data, 'y': y_data, 'color': line_colors, 'x_scale': x_scale, 'y_scale': y_scale, 'toxicity_grade': dvh.toxicity_grade } print(str(datetime.now()), 'begin updating beam, plan, rx data sources', sep=' ') self.update_beam_data(dvh.study_instance_uid) self.update_plan_data(dvh.study_instance_uid) self.update_rx_data(dvh.study_instance_uid) print(str(datetime.now()), 'all sources set', sep=' ') return {'1': dvh_group_1, '2': dvh_group_2}
def main(): """ Main-Methode, wird am Anfang aufgerufen. """ # Daten aus den Argumenten auslesen dataFiles = read_arguments() files_list = dataFiles[0] index_file = dataFiles[1] colors = dataFiles[2] # Eingestellte Werte in der Anwendung chromosom = "1" start = "10400" end = "11000" raw_algorithm = [0] sample_class_diff = 0 line = False error = True absolute_bar = True color_input_list = [] # Figure definieren, auf der alles abgebildet wird p = figure(height=500, width=1000, name='plot') # Bei jedem Update der Widgets wird diese aufgerufen def start_routine(): """ Startet die passenden Methoden zum Veraendern der Grafik. """ nonlocal chromosom, start, end, sample_class_diff, raw_algorithm, p # Entfernen der alten Figur if final_gridplot.children[0].name == 'plot': final_gridplot.children.remove(final_gridplot.children[0]) # Anlegen einer neuen Figur, die die neuen Daten uebergeben bekommt p = figure(width=1000, height=500, name='plot') # setzen von sample und difference, je nachdem was gerade aktiv ist sample = True difference = False # sample ist aktiv, difference muss dann auf False gesetzt werden if sample_class_diff == 0: sample = True difference = False # Klasse ist aktiv elif sample_class_diff == 1: sample = False difference = False # Unterschied wurde ausgewaehlt, da dieser nur mit Klassen angezeigt # wird, muss sample ebenfalls auf False gesetzt werden else: sample = False difference = True # Bei Farbauswahl wird die Farbe dementsprechend angepasst for i, color_string in enumerate(color_input_list): color = color_string.value.split(",") try: color[0] = int(color[0]) color[1] = int(color[1]) color[2] = int(color[2]) except ValueError: error_message.text = ("Bitte eine Zahl" + " zwischen 0 und 255 eingeben.") return if (color[0] < 0 or color[0] > 255 or color[1] < 0 or color[1] > 255 or color[2] < 0 or color[2] > 255): error_message.text = "Eine Zahl zwischen 0 und 255 eingeben." return colors[i] = (color[0], color[1], color[2]) # Sollen Rohdaten angezeigt werden if 0 in raw_algorithm: sumed_data = prepare_data(chromosom, start, end, True, sample, files_list, index_file, error_message) if sumed_data is None: # Einfuegen der Figur final_gridplot.children.insert(0, p) return calculated_methylation = calculate_methylation_level(sumed_data) calculated_data = calculated_methylation[0] cpg_position = calculated_methylation[1] display_data_raw(calculated_data, cpg_position, difference, line, error, absolute_bar, p, colors) # Sollen Algorithmendaten angezeigt werden if 1 in raw_algorithm: pre_data = prepare_data(chromosom, start, end, False, sample, files_list, index_file, error_message) prepared_data = pre_data[1] cpg_position_samples = [] # Dictionary fuer Index Positionen anlegen for index_sample in pre_data[0]: # Soll bei Null liegen index_value = [0 for i in index_sample] cpg_position = { 'index_position': index_sample, 'index_position_value': index_value } cpg_position_samples.append(cpg_position) if prepared_data is None: # Einfuegen der Figur final_gridplot.children.insert(0, p) return calculated_data = make_data_algorithm(prepared_data[0], prepared_data[1], prepared_data[2]) display_data_algorithm(calculated_data, cpg_position_samples, p, difference, error, colors, line) # Einfuegen der Figur final_gridplot.children.insert(0, p) # Restliche Widgets fuer Bedienung definieren def changes_raw_algorithm(attr, old, new): """ Bei Veraenderungen bei der checkbox_raw_algorithm startet start_routine() Params: attr (str) : Gibt an, welches Attribut veraendert wurde old (bokeh.core.property.containers.PropertyValueList) : Liste der alten Werte new (bokeh.core.property.containers.PropertyValueList) : Liste der nun aktiven Werte """ nonlocal raw_algorithm raw_algorithm = [] for x in new: raw_algorithm.append(x) start_routine() def changes_sample_class_diff(attr, old, new): """ Bei Veraenderungen bei der radio_button_sample_class startet start_routine() Params: attr (str) : Gibt an, welches Attribut veraendert wurde old (bokeh.core.property.containers.PropertyValueList) : Liste der alten Werte new (bokeh.core.property.containers.PropertyValueList) : Liste der nun aktiven Werte """ nonlocal sample_class_diff sample_class_diff = new start_routine() def changes_chromosom(attr, old, new): """ Bei Veraenderungen bei choose_chromosom startet start_routine() Params: attr (str) : Gibt an, welches Attribut veraendert wurde old (bokeh.core.property.containers.PropertyValueList) : Liste der alten Werte new (bokeh.core.property.containers.PropertyValueList) : Liste der nun aktiven Werte """ nonlocal chromosom chromosom = new start_routine() def changes_start(attr, old, new): """ Bei Veraenderungen bei start_value startet start_routine() Params: attr (str) : Gibt an, welches Attribut veraendert wurde old (bokeh.core.property.containers.PropertyValueList) : Liste der alten Werte new (bokeh.core.property.containers.PropertyValueList) : Liste der nun aktiven Werte """ nonlocal start start = new start_routine() def changes_end(attr, old, new): """ Bei Veraenderungen bei end_value startet start_routine() Params: attr (str) : Gibt an, welches Attribut veraendert wurde old (bokeh.core.property.containers.PropertyValueList) : Liste der alten Werte new (bokeh.core.property.containers.PropertyValueList) : Liste der nun aktiven Werte """ nonlocal end end = new start_routine() def changes_line(attr, old, new): """ Bei Veraenderungen von checkbox_button_line_circle startet start_routine() Params: attr (str) : Gibt an, welches Attribut veraendert wurde old (bokeh.core.property.containers.PropertyValueList) : Liste der alten Werte new (bokeh.core.property.containers.PropertyValueList) : Liste der nun aktiven Werte """ nonlocal line if not new: line = False else: line = True start_routine() def changes_error(attr, old, new): """ Bei Veraenderungen von checkbox_button_error startet start_routine() Params: attr (str) : Gibt an, welches Attribut veraendert wurde old (bokeh.core.property.containers.PropertyValueList) : Liste der alten Werte new (bokeh.core.property.containers.PropertyValueList) : Liste der nun aktiven Werte """ nonlocal error if not new: error = False else: error = True start_routine() def changes_absolute_bar(attr, old, new): """ Bei Veraenderungen von checkbox_button_error startet start_routine() Params: attr (str) : Gibt an, welches Attribut veraendert wurde old (bokeh.core.property.containers.PropertyValueList) : Liste der alten Werte new (bokeh.core.property.containers.PropertyValueList) : Liste der nun aktiven Werte """ nonlocal absolute_bar if not new: absolute_bar = False else: absolute_bar = True start_routine() def changes_color(attr, old, new): """ Startet die Routine, um die Farbwerte neu anzupassen """ start_routine() # Auswahl zwischen Rohdaten, Klassen und Klassenunterschied checkbox_raw_algorithm = CheckboxButtonGroup( labels=['Rohdaten', 'Algorithmus'], active=[0]) checkbox_raw_algorithm.on_change('active', changes_raw_algorithm) # Auswahl zwischen Sample und Klassen radio_button_sample_class = RadioButtonGroup( labels=['Sample', 'Klassen', 'Unterschied'], active=0) radio_button_sample_class.on_change('active', changes_sample_class_diff) # Auswahl fuer Liniendarstellung checkbox_button_line_circle = CheckboxButtonGroup(labels=["Linie"]) checkbox_button_line_circle.on_change('active', changes_line) # Auswahl fuer Fehlerdarstellung checkbox_button_error = CheckboxButtonGroup(labels=["Fehler"], active=[0]) checkbox_button_error.on_change('active', changes_error) # Auswahl fuer Darstellung der absoluten Daten checkbox_button_absolute = CheckboxButtonGroup(labels=["Absolute Werte"], active=[0]) checkbox_button_absolute.on_change('active', changes_absolute_bar) #DropDown Menue fuer Chromosomenauswahl, Start- und Endauswahl chromosoms = list(index_file.keys()) choose_chromosom = Select(title='Chromosom', value="1", options=chromosoms) choose_chromosom.on_change('value', changes_chromosom) start_value = TextInput(value='10400', title="Start") start_value.on_change('value', changes_start) end_value = TextInput(value='11000', title="Ende") end_value.on_change('value', changes_end) # Fuer das Setzen der Farbwerte for i, color_value in enumerate(colors): color_input = TextInput( value=(str(color_value[0]) + "," + str(color_value[1]) + "," + str(color_value[2])), title="Farbwert " + str(i)) color_input.on_change('value', changes_color) color_input_list.append(color_input) # Textfelder fuer Fehlermeldungen in der Anwendung error_message = Div(text="", width=300, height=10) final_gridplot = layout(children=[ p, [ column( widgetbox(checkbox_raw_algorithm, radio_button_sample_class, choose_chromosom)), widgetbox(checkbox_button_line_circle, checkbox_button_error, checkbox_button_absolute), row(widgetbox(start_value, end_value)), error_message ], color_input_list ], toolbar_location='left') curdoc().add_root(final_gridplot)
def players_performance_tab(player_info_df, player_stats_df, results_df): def create_ds(team, positions): """Returns DataFrame filtered team and positions. :param team: str. If 'None' is passed, all teams are selected. :param positions: list of str. :returns: DataFrame. """ # Default Values SIZE = 8 SIZES = [s for s in range(5, 38, 4)] COLOR = 'blueviolet' MAX_COLORS = len(Category20_20) if team == 'All': ds = pd.DataFrame( joined_player_df[joined_player_df['position'].isin(positions)]) else: ds = pd.DataFrame( joined_player_df[(joined_player_df['position'].isin(positions)) & (joined_player_df['team'] == team)]) # Add sizes if size.value != 'None': if len(ds[size.value].unique()) > len(SIZES): groups = pd.qcut(ds[size.value].values, len(SIZES), duplicates='drop') else: groups = pd.Categorical(ds[size.value].values) ds['Size'] = np.array([SIZES[x] for x in groups.codes]) else: ds['Size'] = SIZE # Add colors if color.value != 'None': if len(ds[color.value].unique()) > MAX_COLORS: groups = pd.qcut(ds[color.value].values, MAX_COLORS, duplicates='drop') else: groups = pd.Categorical(ds[color.value].values) ds['Color'] = np.array([Category20_20[x] for x in groups.codes]) else: ds['Color'] = COLOR return ds def plot_stats(): """Creates and returns a figure.""" pos = [positions[i] for i in select_position.active] team = select_team.value ds = create_ds(team, pos) source = ColumnDataSource(ds) p = figure(plot_height=600, plot_width=800, title=f'{x.value} vs {y.value}', tools='pan,box_zoom,reset') p.circle(x=x.value, y=y.value, size='Size', color='Color', alpha=0.5, source=source, hover_color='navy') hover = HoverTool(tooltips=[('Player', '@name'), ( 'Team', '@team'), (f'{x.value}', f'@{{{x.value}}}'), ( f'{y.value}', f'@{{{y.value}}}'), (f'Opponent', f'@Opponent')]) if size.value != 'None': hover.tooltips.append((f'{size.value}', f'@{{{size.value}}}')) if color.value != 'None': hover.tooltips.append((f'{color.value}', f'@{{{color.value}}}')) hover.point_policy = 'follow_mouse' p.add_tools(hover) p.xaxis.axis_label = x.value p.yaxis.axis_label = y.value return p def update(atrrname, old, new): layout.children[1] = plot_stats() # Create merged dataFrame of players stats and info joined_player_df = pd.merge(player_stats_df, player_info_df, on='pid', how='inner') # joined_player_df.drop(columns=['index_x'], inplace=True) # Add columns: result (w/l/d), opponent joined_player_df['Opponent'] = joined_player_df.apply(get_opponent, args=(results_df, ), axis=1) joined_player_df['result'] = joined_player_df.apply(get_gw_match_result, args=(results_df, ), axis=1) # Data filtering widgets by Team and Position teams = ['All'] + sorted(list(player_info_df['team'].unique())) select_team = Select(title='Filter by Team', value='All', options=teams) select_team.on_change('value', update) positions = ['GK', 'Defender', 'Midfielder', 'Forward'] select_position = CheckboxButtonGroup(labels=positions, active=[0, 1, 2, 3]) select_position.on_change('active', update) # Select stats to plot columns = [ x for x in sorted(player_stats_df.columns) if x not in ['index', 'pid', 'gameweek', 'season'] ] x = Select(title='X Axis', value='minutes', options=columns) x.on_change('value', update) y = Select(title='Y Axis', value='passes', options=columns) y.on_change('value', update) size = Select(title='Add Size Dimension', value='None', options=['None'] + columns) size.on_change('value', update) color = Select(title='Add Color Segmentation', value='None', options=['None', 'result', 'gameweek', 'position']) color.on_change('value', update) widgets = widgetbox([select_team, select_position, x, y, size, color]) layout = row(widgets, plot_stats()) tab = Panel(child=layout, title='Players Performances') return tab
def density_tab(flights): # Dataset for density plot based on carriers, range of delays, # and bandwidth for density estimation def make_dataset(carrier_list, range_start, range_end, bandwidth): xs = [] ys = [] colors = [] labels = [] for i, carrier in enumerate(carrier_list): subset = flights[flights['name'] == carrier] subset = subset[subset['arr_delay'].between( range_start, range_end)] kde = gaussian_kde(subset['arr_delay'], bw_method=bandwidth) # Evenly space x values x = np.linspace(range_start, range_end, 100) # Evaluate pdf at every value of x y = kde.pdf(x) # Append the values to plot xs.append(list(x)) ys.append(list(y)) # Append the colors and label colors.append(airline_colors[i]) labels.append(carrier) new_src = ColumnDataSource(data={ 'x': xs, 'y': ys, 'color': colors, 'label': labels }) return new_src def make_plot(src): p = figure(plot_width=700, plot_height=700, title='Density Plot of Arrival Delays by Airline', x_axis_label='Delay (min)', y_axis_label='Density') p.multi_line('x', 'y', color='color', legend='label', line_width=3, source=src) # Hover tool with next line policy hover = HoverTool(tooltips=[('Carrier', '@label'), ('Delay', '$x'), ('Density', '$y')], line_policy='next') # Add the hover tool and styling p.add_tools(hover) p = style(p) return p def update(attr, old, new): # List of carriers to plot carriers_to_plot = [ carrier_selection.labels[i] for i in carrier_selection.active ] # If no bandwidth is selected, use the default value if bandwidth_choose.active == []: bandwidth = None # If the bandwidth select is activated, use the specified bandwith else: bandwidth = bandwidth_select.value new_src = make_dataset(carriers_to_plot, range_start=range_select.value[0], range_end=range_select.value[1], bandwidth=bandwidth) src.data.update(new_src.data) def style(p): # Title p.title.align = 'center' p.title.text_font_size = '20pt' p.title.text_font = 'serif' # Axis titles p.xaxis.axis_label_text_font_size = '14pt' p.xaxis.axis_label_text_font_style = 'bold' p.yaxis.axis_label_text_font_size = '14pt' p.yaxis.axis_label_text_font_style = 'bold' # Tick labels p.xaxis.major_label_text_font_size = '12pt' p.yaxis.major_label_text_font_size = '12pt' return p # Carriers and colors available_carriers = sorted(set(flights['name'])) airline_colors = Category20_16 airline_colors.sort() # Carriers to plot carrier_selection = CheckboxGroup(labels=available_carriers, active=[0, 1]) carrier_selection.on_change('active', update) # Range to plot range_select = RangeSlider(start=-60, end=180, value=(-60, 120), step=5, title='Delay Range (min)') range_select.on_change('value', update) # Initial carriers and data source initial_carriers = [ carrier_selection.labels[i] for i in carrier_selection.active ] # Bandwidth of kernel bandwidth_select = Slider(start=0.1, end=5, step=0.1, value=0.5, title='Bandwidth for Density Plot') bandwidth_select.on_change('value', update) # Whether to set the bandwidth or have it done automatically bandwidth_choose = CheckboxButtonGroup( labels=['Choose Bandwidth (Else Auto)'], active=[]) bandwidth_choose.on_change('active', update) # Make the density data source src = make_dataset(initial_carriers, range_start=range_select.value[0], range_end=range_select.value[1], bandwidth=bandwidth_select.value) # Make the density plot p = make_plot(src) # Add style to the plot p = style(p) # Put controls in a single element controls = WidgetBox(carrier_selection, range_select, bandwidth_select, bandwidth_choose) # Create a row layout layout = row(controls, p) # Make a tab with the layout tab = Panel(child=layout, title='Density Plot') return tab
def timeseries_tab(ts, hist_ts): # Set up plot def make_lineplot(source): ts_list = source.column_names ts_list.remove('index') ts_list.remove('time') ttp = [("Time", "$x"), ("Value", "$y")] plot = figure(plot_height=400, plot_width=600, tooltips=ttp, title="Plot Name", x_axis_label="Axis label", y_axis_label="Axis label", tools="hover, pan, zoom_in, zoom_out, reset, save") for i, name in enumerate(ts_list): plot.line('time', name, source=source, line_width=3, line_color=ts_colors[i], legend_label=name) plot.legend.location = "top_right" plot.legend.click_policy = "hide" plot.title.text_font_size = '14pt' plot.xaxis.axis_label_text_font_size = '12pt' plot.xaxis.axis_label_text_font_style = 'bold' plot.yaxis.axis_label_text_font_size = '12pt' plot.yaxis.axis_label_text_font_style = 'bold' return plot # Set up callbacks def update_title(attrname, old, new): plot.title.text = text.value def update_x_ax_label(attrname, old, new): plot.xaxis.axis_label = text2.value def update_y_ax_label(attrname, old, new): plot.yaxis.axis_label = text3.value def update_window(attrname, old, new): if window_select.value == 0: raw_source = ColumnDataSource(data=ts) source.data.update(raw_source.data) else: if rolling_method.value == "Mean": # Apply moving average to pandas dataframe, export to CDS type. ts_rmean = rolling_mean(ts, window=window_select.value) new_source = ColumnDataSource(data=ts_rmean) else: # Apply moving std to pandas dataframe, export to CDS type. ts_rstd = rolling_std(ts, window=window_select.value) new_source = ColumnDataSource(data=ts_rstd) source.data.update(new_source.data) # Set up widgets text = TextInput(title="Title of Plot", value='Plot Name') text.on_change('value', update_title) text2 = TextInput(title="x-axis Label", value='Axis Label') text2.on_change('value', update_x_ax_label) text3 = TextInput(title="y-axis Label", value='Axis Label') text3.on_change('value', update_y_ax_label) rolling_method = Select(value='Mean', title='Statistic', options=['Mean', 'Std. Dev.']) rolling_method.on_change('value', update_window) window_select = Slider(start=0, end=50, step=1, value=10, title='Window Size') window_select.on_change('value', update_window) div1 = Div(text="""<b>Plot Attributes:</b> <br> Modify axis labels. <br>""") div2 = Div(text="""<b>Rolling Window Functions:</b> <br> Specify the size and statistic for a rolling window function. <br>""") div3 = Div(text="""<b>Data Distribution:</b> <br> Examine the distribution of time series data points. <br>""") source = ColumnDataSource(data=ts) plot = make_lineplot(source) # Set up layouts and add to document # Put controls in a single element. lineplot_controls = WidgetBox(text, div1, text2, text3, div2, window_select, rolling_method) # Make plot with histogram # Find maximum range of ts. hist_ts_range = hist_ts.apply(lambda x: x.max() - x.min()) range_max = hist_ts_range.max() # Function to make a dataset for histogram based on a list of # timeseries, using a default histogram bin width of 5 def make_dataset(timeseries_list, bin_width=5): # Dataframe to hold information df_to_plot = pd.DataFrame(columns=['proportion', 'left', 'right', 'f_proportion', 'f_interval', 'name', 'color']) # Iterate through all the TS. for i, timeseries_name in enumerate(timeseries_list): # Subset to the carrier subset = hist_ts[timeseries_name] # Create a histogram with default 5 minute bins arr_hist, edges = np.histogram(subset, bins=int(range_max / bin_width)) # Divide the counts by the total to get a proportion arr_df = pd.DataFrame({'proportion': arr_hist / np.sum(arr_hist), 'left': edges[:-1], 'right': edges[1:]}) # Format the proportion arr_df['f_proportion'] = ['%0.5f' % proportion for proportion in arr_df['proportion']] # Format the interval arr_df['f_interval'] = ['%d to %d units' % (left, right) for left, right in zip(arr_df['left'], arr_df['right'])] # Assign the carrier for labels arr_df['name'] = timeseries_name # Color each carrier differently arr_df['color'] = Category20_16[i] # Add to the overall dataframe df_to_plot = df_to_plot.append(arr_df) # Overall dataframe df_to_plot = df_to_plot.sort_values(['name', 'left']) return ColumnDataSource(df_to_plot) def style(hist): # Title hist.title.align = 'left' hist.title.text_font_size = '14pt' # Axis titles hist.xaxis.axis_label_text_font_size = '12pt' hist.xaxis.axis_label_text_font_style = 'bold' hist.yaxis.axis_label_text_font_size = '12pt' hist.yaxis.axis_label_text_font_style = 'bold' # Tick labels hist.xaxis.major_label_text_font_size = '12pt' hist.yaxis.major_label_text_font_size = '12pt' return hist def make_plot(hist_src): # Blank plot with correct labels hist = figure(plot_width=700, plot_height=700, title='Histogram of Times Series Data Points', x_axis_label='Bin width', y_axis_label='Proportion') # Quad glyphs to create a histogram hist.quad(source=hist_src, bottom=0, top='proportion', left='left', right='right', color='color', fill_alpha=0.7, hover_fill_color='color', legend='name', hover_fill_alpha=1.0, line_color='black') # Hover tool with vline mode hover = HoverTool(tooltips=[('Times Series', '@name'), ('x', '@f_interval'), ('Proportion', '@f_proportion')], mode='vline') hist.add_tools(hover) # Styling. hist = style(hist) return hist def update(attr, old, new): hist_ts_to_plot = [hist_ts_selection.labels[i] for i in hist_ts_selection.active] new_hist_src = make_dataset(hist_ts_to_plot, bin_width=binwidth_select.value) hist_src.data.update(new_hist_src.data) # Widgets for interactivity. # Carriers and colors available_hist_ts = hist_ts.columns.tolist() available_hist_ts.sort() hist_ts_selection = CheckboxButtonGroup(labels=available_hist_ts, active=[0, 1]) hist_ts_selection.on_change('active', update) binwidth_select = Slider(start=1, end=10, step=1, value=5, title='Bin Width') binwidth_select.on_change('value', update) # Call to set initial dataset. print(hist_ts_selection.labels, hist_ts_selection.active) # Initial ts and data source initial_hist_ts = available_hist_ts hist_src = make_dataset(initial_hist_ts, bin_width=binwidth_select.value) hist = make_plot(hist_src) # Put controls in a single element. histogram_controls = WidgetBox(div3, hist_ts_selection, binwidth_select) # Create a row layout grid = gridplot([[lineplot_controls, plot], [histogram_controls, hist]], plot_width=500, plot_height=500) # Make a tab with the layout tab = Panel(child=grid, title='Time Series Plots') return tab
# select_linac[2].on_change('value', plot.update_source) avg_len_input = TextInput(title='Avg. Len:', value='10', width=100) avg_len_input.on_change('value', plot.update_source) percentile_input = TextInput(title='Percentile:', value='90', width=100) percentile_input.on_change('value', plot.update_source) start_date_picker = DatePicker(title='Start Date:', value=plot.x[0]) end_date_picker = DatePicker(title='End Date:', value=plot.x[-1]) start_date_picker.on_change('value', plot.update_source) end_date_picker.on_change('value', plot.update_source) gamma_options = ['5.0%/3.0mm', '3.0%/3.0mm', '3.0%/2.0mm', 'Any'] checkbox_button_group = CheckboxButtonGroup(labels=gamma_options, active=[3]) checkbox_button_group.on_change('active', plot.update_source) text = {key: Div() for key in [1, 2]} plot.update_source(None, None, None) layout = column(row(select_y, avg_len_input, percentile_input), row(start_date_picker, end_date_picker), row(Div(text='Gamma Criteria: '), checkbox_button_group), text[1], text[2], row(Spacer(width=10), plot.fig), Spacer(height=50), row(Spacer(width=10), plot.histogram), Spacer(height=50), row(Spacer(width=10), ichart.figure), row(ichart.div_center_line, ichart.div_ucl, ichart.div_lcl)) curdoc().add_root(layout) curdoc().title = "ArcCheck Trending"
range_select.on_change('value', update) # Initial carriers and data source initial_carriers = [carrier_selection.labels[i] for i in carrier_selection.active] # Bandwidth of kernel bandwidth_select = Slider(start=0.1, end=5, step=0.1, value=0.5, title='Bandwidth for Density Plot') bandwidth_select.on_change('value', update) # Whether to set the bandwidth or have it done automatically bandwidth_choose = CheckboxButtonGroup( labels=['Choose Bandwidth (Else Auto)'], active=[]) bandwidth_choose.on_change('active', update) # FUNDS_EARMARKED_FOR_GOAL fund_input = TextInput(value="100000", title="Funds for Goal:") contribution_input = TextInput(value="1000", title="Contribution Amount:") income_input = TextInput(value="100000", title="Annual Salary:") fga_input = TextInput(value="100000", title="Future Goal Amount:") retirementage_select = Slider(start = 20, end = 100, step = 1, value = 1, title = 'Projected Retirement Age') #retirementage_select.on_change('value', update)
class Interface: def __init__(self): self.grepolis = Grepolis() imgRessource = [] for v in ["Bois", "Pierre", "Argent"]: r = "static/" + v + ".png" d = dict(url=[r]) imgRessource.append(Image(d)) colRess = column(*[img.figure for img in imgRessource]) self.inputRess = [ TextInput(value="", title=el + " :", width=150) for el in ["Bois", "Pierre", "Argent"] ] colinputRess = column(*self.inputRess) imgDieu = [] for v in ["Athena", "Artemis", "Hades", "Zeus", "Poseidon", "Hera"]: r = "static/" + v + ".png" d = dict(url=[r]) imgDieu.append(Image(d, multiplier=3)) rowDieu = [HFill(5)] for img in imgDieu: rowDieu.append(HFill(5)) rowDieu.append(img.figure) rowDieu = row(*rowDieu) imgAtt = [] for v in ["Att_hack", "Att_sharp", "Att_distance"]: r = "static/" + v + ".png" d = dict(url=[r]) imgAtt.append(Image(d)) colAtt = column(*[img.figure for img in imgAtt]) self.inputAtt = [ TextInput(value="", title=el + " :", width=150) for el in ["Contondantes", "Blanches", "De Jet"] ] colinputAtt = column(*self.inputAtt) imgDef = [] for v in ["Def_hack", "Def_sharp", "Def_distance"]: r = "static/" + v + ".png" d = dict(url=[r]) imgDef.append(Image(d)) colDef = column(*[img.figure for img in imgDef]) self.inputDef = [ TextInput(value="", title=el + " :", width=150) for el in ["Contondantes", "Blanches", "De Jet"] ] rowinputDef = column(*self.inputDef) imgOther = [] for v in ["Vitesse", "Butin", "Faveur"]: r = "static/" + v + ".png" d = dict(url=[r]) imgOther.append(Image(d)) colOther = column(*[img.figure for img in imgOther]) self.inputFavBut = [ TextInput(value="", title=el + " :", width=150) for el in ["Vitesse", "Butin", "Faveur"] ] self.inputOther = column(*self.inputFavBut) self.imgUnit = [] for v in [ "Combattant", "Frondeur", "Archer", "Hoplite", "Cavalier", "Char", "Envoye", "Centaure", "Pegase" ]: r = "static/" + v + ".jpg" d = dict(url=[r]) self.imgUnit.append(Image(d, multiplier=2)) rowUnit = row(HFill(10), *[img.figure for img in self.imgUnit]) imgDefAtt = [] for v in ["Pop", "Attaque", "Defense"]: r = "static/" + v + ".png" d = dict(url=[r]) imgDefAtt.append(Image(d)) rowInputUnit = [HFill(10)] self.unitInput = [ TextInput(value="", title=el + " :", width=80) for el in [ "Combattant", "Frondeur", "Archer", "Hoplite", "Cavalier", "Char", "Envoye", "Centaure", "Pegase" ] ] for inp in self.unitInput: rowInputUnit.append(inp) rowInputUnit.append(HFill(30)) rowInputUnit = row(HFill(10), *rowInputUnit) self.selectUnit = CheckboxButtonGroup(labels=[ "Combattant", "Frondeur", "Archer", "Hoplite", "Cavalier", "Char", "Envoye", "Centaure", "Pegase" ], active=[i for i in range(9)]) self.selectUnit.on_change("active", self.updateSelectUnit) self.Dieu = RadioButtonGroup( labels=["Athena", "Artemis", "Hades", "Zeus", "Poseidon", "Hera"], active=0, width=1110) self.Dieu.on_change('active', self.updateUnit) self.attdef = RadioButtonGroup(labels=["Attaque", "Defense"], active=0, width=200) self.attdef.on_change('active', self.switchAttDef) self.typeAtt = RadioGroup( labels=["Armes Contondantes", "Armes Blanches", "Armes de Jet"], active=0, width=150) self.typeAtt.on_change('active', self.process2) self.imgFaveur = Image(dict(url=["static/" + "Faveur" + ".png"])) self.launch = Button(label="Lancer") self.launch.on_click(self.process) self.inputPop = TextInput(value="1500", title="Population : ", width=120) self.inputPop.on_change("value", self.process2) self.inputFav = TextInput(value="1500", title="Faveur Max : ", width=120) self.inputFav.on_change("value", self.process2) rowPop = row(HFill(10), self.typeAtt, imgDefAtt[1].figure, self.attdef, HFill(30), imgDefAtt[2].figure, HFill(50), imgDefAtt[0].figure, self.inputPop, HFill(50), self.imgFaveur.figure, self.inputFav, HFill(50)) self.doc = column( rowDieu, self.Dieu, VFill(20), rowPop, VFill(20), self.selectUnit, rowUnit, rowInputUnit, VFill(20), row(HFill(50), colRess, colinputRess, HFill(40), colAtt, colinputAtt, HFill(40), colDef, rowinputDef, HFill(40), colOther, self.inputOther)) #curdoc().add_root(column(rowDieu,self.Dieu,VFill(20),rowPop,VFill(20),self.selectUnit,rowUnit,rowInputUnit,VFill(20),row(HFill(50),colRess,colinputRess,HFill(40),colAtt,colinputAtt,HFill(40),colDef,rowinputDef,HFill(40),colOther,self.inputOther))) self.process(None) #curdoc().title = "Grepolis" def updateUnit(self, attrname, old, new): L = ["Athena", "Artemis", "Hades", "Zeus", "Poseidon", "Hera"] print(self.selectUnit.active) if L[new] == "Poseidon": self.imgUnit[-1].figure.visible = False self.unitInput[-1].visible = False self.selectUnit.active = [1, 2, 3, 4, 5, 6, 7] else: self.imgUnit[-1].figure.visible = True self.unitInput[-1].visible = True self.selectUnit.active = [1, 2, 3, 4, 5, 6, 7, 8] self.grepolis.setDieu(L[new]) unit = Add(L[new]) self.selectUnit.labels = [ "Combattant", "Frondeur", "Archer", "Hoplite", "Cavalier", "Char", "Envoye" ] + unit for i, v in enumerate(unit): r = "static/" + v + ".jpg" d = dict(url=[r]) self.imgUnit[-2 + i].update(d) self.unitInput[-2 + i].title = v + " : " self.process(None) def process2(self, attrname, old, new): self.process(None) def switchAttDef(self, attrname, old, new): if self.attdef.active == 0: self.typeAtt.disabled = False else: self.typeAtt.disabled = True self.process(None) def updateSelectUnit(self, attrname, old, new): N = len(self.selectUnit.labels) active = self.selectUnit.active zeros = [i for i in range(N) if i not in active] for inp in [self.unitInput[i] for i in zeros]: inp.value = str(0) self.process(None) def process(self, attrname): try: pop = int(self.inputPop.value) favmax = int(self.inputFav.value) active = self.selectUnit.active type = self.typeAtt.active if self.attdef.active == 0: X, Att, Def, Prix, Speed, Pops, butin = self.grepolis.optimAttaque( pop=pop, favmax=favmax, active=active, type=type) else: X, Att, Def, Prix, Speed, Pops, butin = self.grepolis.optimDefense( pop=pop, favmax=favmax, active=active) for v, inp in zip(X, [self.unitInput[i] for i in active]): inp.value = str(v) for v, inp in zip(Att, self.inputAtt): inp.value = str(v) + " /u - " + str(int(v * pop)) for v, inp in zip(Def, self.inputDef): inp.value = str(v) + " /u - " + str(int(v * pop)) for v, inp in zip(Prix, self.inputRess): inp.value = str(v) + " /u - " + str(int(v * pop)) for i, (v, inp) in enumerate( zip([Speed, butin, Prix[3]], self.inputFavBut)): #add = "" #if i > 0: # add = + " /u - " +str(int(v*pop)) #print(v,add) inp.value = str(v) + " /u - " + str(int( v * pop)) if i != 0 else str(v) except: pass
def attention_tab(beers): # Dataset for density plot based on Genres and range of ratings # and bandwidth for density estimation def make_dataset( genre_list, range_start, range_end, bandwidth ): xs = [] ys = [] colors = [] labels = [] for i, genre in enumerate(genre_list): subset = beers[beers['style_genre'] == genre] subset = subset[subset['ratings'].between(range_start, range_end)] kde = gaussian_kde(subset['ratings'], bw_method=bandwidth) # Evenly space x values x = np.linspace(range_start, range_end, 6500) # Evaluate pdf at every value of x y = kde.pdf(x) # Append the values to plot xs.append(list(x)) ys.append(list(y)) # Append the colors and label colors.append(genre_colors[i]) labels.append(genre) new_src = ColumnDataSource(data={'x': xs, 'y': ys, 'color': colors, 'label': labels}) return new_src def make_plot(src): p = figure(plot_width = 700, plot_height = 650, title = 'Distribution of Beer Genre Attention', x_axis_label = 'Attention of Genre (Number of Ratings of Beer)', y_axis_label = 'Density') p.multi_line('x', 'y', color = 'color', legend = 'label', line_width = 3, source = src) # Hover tool with next line policy hover = HoverTool(tooltips=[('Genre', '@label'), ('Ratings', '$x'), ('Density', '$y')], line_policy = 'next') # Add the hover tool and styling p.add_tools(hover) p = p_style(p) return p def update(attr, old, new): # List of genres to plot genres_to_plot = [genre_selection.labels[i] for i in genre_selection.active] # If no bandwidth is selected, use the default value if bandwidth_choose.active == []: bandwidth = None # If the bandwidth select is activated, use the specified bandwith else: bandwidth = bandwidth_select.value new_src = make_dataset(genres_to_plot, range_start = range_select.value[0], range_end = range_select.value[1], bandwidth = bandwidth) src.data.update(new_src.data) def p_style(p): # Title p.title.align = 'center' p.title.text_font_size = '20pt' p.title.text_font = 'serif' # Axis titles p.xaxis.axis_label_text_font_size = '14pt' p.xaxis.axis_label_text_font_style = 'bold' p.yaxis.axis_label_text_font_size = '14pt' p.yaxis.axis_label_text_font_style = 'bold' # Tick labels p.xaxis.major_label_text_font_size = '12pt' p.yaxis.major_label_text_font_size = '12pt' return p # genres and colors available_genres = list(set(beers['style_genre'])) available_genres.sort() genre_colors = Category20_16 genre_colors.sort() # Genres to plot genre_selection = CheckboxGroup(labels=available_genres, active = [0, 1]) genre_selection.on_change('active', update) range_select = RangeSlider(start = 0, end = 500, value = (0, 200), step = 50, title = 'Range of Attention (Number of Ratings)') range_select.on_change('value', update) # intial genres and data source initial_genres = [genre_selection.labels[i] for i in genre_selection.active] # Bandwidth of kernel bandwidth_select = Slider(start = 0.1, end = 5, step = 0.1, value = 2, title = 'Bandwidth for Density Plot') bandwidth_select.on_change('value', update) # Whether to set the bandwidth or have it done automatically bandwidth_choose = CheckboxButtonGroup( labels=['Choose Bandwidth (Else Auto)'], active = []) bandwidth_choose.on_change('active', update) # Make the density data source src = make_dataset(initial_genres, range_start = range_select.value[0], range_end = range_select.value[1], bandwidth = bandwidth_select.value) sidetext = Div( text="""Please use the filters below to adjust the <b>Attention Density Plot</b> as needed.""", width=250, height=50) # Make the density plot p = make_plot(src) # Add style to the plot p = p_style(p) # Put controls in a single element controls = WidgetBox(sidetext, genre_selection, range_select, bandwidth_select, bandwidth_choose) # Create a row layout layout = row(controls, p) # Make a tab with the layout tab = Panel(child=layout, title = 'Distribution of Beer Genre Attention') return tab
def load_page(experiment_df, experiment_db): ########## bokeh plots ########## # general plot tools plot_tools = 'wheel_zoom, pan, reset, save, hover' hover = HoverTool(tooltips=[("(x,y)", "($x, $y)")]) # progress curve plots global raw_source raw_source = ColumnDataSource(data=dict(x=[], y=[], yr=[], yfit=[])) global raw raw = figure(title="Initial Rate Fit", x_axis_label="Time", y_axis_label="Signal", plot_width=350, plot_height=300, tools=plot_tools) raw.circle('x', 'y', size=2, source=raw_source, color='gray', selection_color="black", alpha=0.6, nonselection_alpha=0.2, selection_alpha=0.6) raw.line('x', 'yfit', source=raw_source, color='red') global warning_source warning_source = ColumnDataSource(data=dict( x=[0], y=[0], t=[ 'Please enter transform equation! \nMust convert signal to [substrate] \nin Schnell-Mendoza mode (e.g. via \nx/6.22/0.45/0.001 for sample data). \nNote: this transform may need \nto be inverted through multiplying \nby -1 when analyzing experiments \nthat measure increasing product \nconcentration over time)' ])) global warning warning = raw.text(x='x', y='y', text='t', text_font_size='12pt', angle=0, source=warning_source) warning.visible = False global circles_source circles_source = ColumnDataSource( data=dict(x=[-.05, -.05, 1.6, 1.6], y=[0, 0.6, 0, 0.6])) global circles circles = raw.circle(x='x', y='y', alpha=0., source=circles_source) circles.visible = False global resi resi = figure(title="Initial Rate Fit Residuals", x_axis_label="Time", y_axis_label="Residual", plot_width=700, plot_height=200, tools='wheel_zoom,pan,reset') resi.yaxis.formatter = BasicTickFormatter(precision=2, use_scientific=True) resi.circle('x', 'yr', size=5, source=raw_source, color='grey', alpha=0.6) # model plot for titration experiments global model_data_source model_data_source = ColumnDataSource( data=dict(xt=[], yt=[], n=[], ct=[], et=[])) global model_plot_source model_plot_source = ColumnDataSource( data=dict(xp=[], yp=[], l=[], u=[], cp=[], ep=[])) global model_fit_source model_fit_source = ColumnDataSource(data=dict(x=[], y=[])) global varea_source varea_source = ColumnDataSource(data=dict(x=[], r1=[], r2=[])) global model model = figure(title='Model Fit', x_axis_label='Concentration', y_axis_label='Rate', plot_width=350, plot_height=300, tools=plot_tools) model.circle('xp', 'yp', size=8, source=model_plot_source, color='cp', alpha=0.6) model.add_layout( Whisker(source=model_plot_source, base='xp', upper='u', lower='l')) model.line('x', 'y', source=model_fit_source, line_width=3, color='black', alpha=0.8) model.varea('x', 'r1', 'r2', source=varea_source, color='grey', alpha=0.3) ########## bokeh widgets ########## # button for selecting progress curve fitting routine global fit_button fit_button = RadioButtonGroup(labels=[ 'Maximize Slope Magnitude', 'Linear Fit', 'Logarithmic Fit', 'Schnell-Mendoza' ], active=0, width=375) fit_button.on_change('active', widget_callback) # button for selecting progress curve fitting routine global scalex_box scalex_box = CheckboxButtonGroup( labels=["transform x-axis to Log10 scale"], active=[]) scalex_box.on_change('active', widget_callback) # dropdown menu for selecting titration experiment model global model_select model_select = Select( title='Choose Model', value='Michaelis-Menten', options=['Michaelis-Menten', 'pEC50/pIC50', 'High-Throughput Screen'], width=350) model_select.on_change('value', widget_callback) # dropdown menu for selecting blank sample to subtract from remaining titration samples global subtract_select subtract_select = Select(title='Select Blank Sample for Subtraction', value='', options=list(experiment_df)[1:] + [''], width=350) subtract_select.on_change('value', widget_callback) # dropdown menu for selecting titration sample to plot in current view global sample_select sample_select = Select(title='Y Axis Sample', value=list(experiment_df)[-1], options=list(experiment_df)[1:], width=350) sample_select.on_change('value', sample_callback) # text input box for transforming slopes to rates global transform_input transform_input = TextInput(value='', title="Enter Transform Equation", width=350) transform_input.on_change('value', widget_callback) # text input box for setting delay time in logarithmic progress curve fitting global offset_input offset_input = TextInput(value='', title="Enter Time Between Mixing and First Read", width=350) offset_input.on_change('value', widget_callback) # text input boxes for fixing EC/IC50 parameters global bottom_fix bottom_fix = TextInput(value='', title="Fix pIC50/pEC50 Bottom") bottom_fix.on_change('value', widget_callback) global top_fix top_fix = TextInput(value='', title="Fix pIC50/pEC50 Top") top_fix.on_change('value', widget_callback) global slope_fix slope_fix = TextInput(value='', title="Fix pIC50/pEC50 Hill Slope") slope_fix.on_change('value', widget_callback) # text input boxes for progress curve xrange selection global start_time start_time = TextInput(value=str( experiment_df[list(experiment_df)[0]].values[0]), title="Enter Start Time") global end_time end_time = TextInput(value=str( experiment_df[list(experiment_df)[0]].values[-1]), title='Enter End Time') start_time.on_change('value', xbox_callback) end_time.on_change('value', xbox_callback) # range slider to select threshold for hit detection in HTS mode global threshold_slider threshold_slider = Slider(start=0, end=5, value=2, step=0.1, title='HTS Hit Threshold (Standard Deviation)', width=350) threshold_slider.on_change('value', threshold_callback) # range slider to update plots according to progress cuve xrange selection xmin = experiment_df[experiment_df.columns[0]].values[0] xmax = experiment_df[experiment_df.columns[0]].values[-1] global range_slider range_slider = RangeSlider( start=xmin, end=xmax, value=(xmin, xmax), step=experiment_df[experiment_df.columns[0]].values[1] - xmin, title='Fine Tune X-Axis Range', width=650) range_slider.on_change('value', slider_callback) # button to upload local data file global file_source file_source = ColumnDataSource(data=dict(file_contents=[], file_name=[])) file_source.on_change('data', file_callback) try: output_filename = 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=350) upload_button.callback = CustomJS(args=dict(file_source=file_source), code=open( join(dirname(__file__), "upload.js")).read()) # table containing rate fits and errors template = """ <div style="background:<%=ct%>"; color="white";> <%= value %></div> """ formatter = HTMLTemplateFormatter(template=template) columns = [ TableColumn(field='n', title='Sample'), TableColumn(field='yt', title='Slope (Initial Rate)', formatter=formatter), TableColumn(field='et', title='Std. Error') ] global rate_table rate_table = DataTable(source=model_data_source, columns=columns, width=350, height=250, selectable=True, editable=True) # tables containing model fits and errors global mm_source mm_source = ColumnDataSource(dict(label=[], Km=[], Vmax=[])) columns = [ TableColumn(field='label', title=''), TableColumn(field='Vmax', title='Vmax'), TableColumn(field='Km', title='Km') ] global mm_table mm_table = DataTable(source=mm_source, columns=columns, width=350, height=75, selectable=True, editable=True) global ic_source ic_source = ColumnDataSource( dict(label=[], Bottom=[], Top=[], Slope=[], p50=[])) columns = [ TableColumn(field='label', title=''), TableColumn(field='Bottom', title='Bottom'), TableColumn(field='Top', title='Top'), TableColumn(field='Slope', title='Slope'), TableColumn(field='p50', title='pEC/IC50') ] global ic_table ic_table = DataTable(source=ic_source, columns=columns, width=350, height=75, selectable=True, editable=True) # button for copying rate data table to clipboard global copy_button copy_button = Button(label="Copy Table to Clipboard", button_type="primary", width=350) copy_button.callback = CustomJS(args=dict(source=model_data_source), code=open( join(dirname(__file__), "copy.js")).read()) # button for downloading rate data table to local csv file global download_button download_button = Button(label="Download Table to CSV", button_type="primary", width=350) download_button.callback = CustomJS(args=dict(source=model_data_source, file_name=output_filename), code=open( join(dirname(__file__), "download.js")).read()) ########## document formatting ######### desc = Div(text=open(join(dirname(__file__), "description.html")).read(), width=1400) advanced = Div( text="""<strong>Advanced Settings for \npEC/IC50 Analysis</strong>""") widgets = widgetbox(model_select, sample_select, subtract_select, transform_input, offset_input, advanced, scalex_box, bottom_fix, top_fix, slope_fix) table = widgetbox(rate_table) main_row = row( column(upload_button, widgets), column(fit_button, row(raw, model), resi, row(start_time, end_time), range_slider), column(download_button, copy_button, table, mm_table, ic_table, threshold_slider)) sizing_mode = 'scale_width' l = layout([[desc], [main_row]], sizing_mode=sizing_mode) update() curdoc().clear() curdoc().add_root(l) curdoc().title = "ICEKAT"
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"
'flags': df_slice['all_flags'], 'single_flag': df_slice['single_flag'], 'sim_age': df_slice['sim_age'] }).data slider = RangeSlider(start=0, end=30, value=(0, 30), step=1, title='Simulated Age') slider.on_change('value', callback) buttons = CheckboxButtonGroup(labels=buttonlabels, active=[0, 1, 2, 3, 4, 5, 6]) buttons.on_change('active', callback) select = Select(title='Vectorization', value='Bag of Words', options=['Bag of Words', 'Doc2Vec']) select.on_change('value', callback) tooltips = [('Comment', '@text'), ('Flags', '@flags'), ('Age (d)', '@sim_age')] n_obs = df.shape[0] manif = 't-SNE' title = '{} visualization of {} observations'.format(manif, n_obs) p = figure(plot_width=figsize[0], plot_height=figsize[1], title=title,
def density_tab(flights): # Dataset for density plot based on carriers, range of delays, # and bandwidth for density estimation def make_dataset(carrier_list, range_start, range_end, bandwidth): xs = [] ys = [] colors = [] labels = [] for i, carrier in enumerate(carrier_list): subset = flights[flights['name'] == carrier] subset = subset[subset['arr_delay'].between(range_start, range_end)] kde = gaussian_kde(subset['arr_delay'], bw_method=bandwidth) # Evenly space x values x = np.linspace(range_start, range_end, 100) # Evaluate pdf at every value of x y = kde.pdf(x) # Append the values to plot xs.append(list(x)) ys.append(list(y)) # Append the colors and label colors.append(airline_colors[i]) labels.append(carrier) new_src = ColumnDataSource(data={'x': xs, 'y': ys, 'color': colors, 'label': labels}) return new_src def make_plot(src): p = figure(plot_width = 700, plot_height = 700, title = 'Density Plot of Arrival Delays by Airline', x_axis_label = 'Delay (min)', y_axis_label = 'Density') p.multi_line('x', 'y', color = 'color', legend = 'label', line_width = 3, source = src) # Hover tool with next line policy hover = HoverTool(tooltips=[('Carrier', '@label'), ('Delay', '$x'), ('Density', '$y')], line_policy = 'next') # Add the hover tool and styling p.add_tools(hover) p = style(p) return p def update(attr, old, new): # List of carriers to plot carriers_to_plot = [carrier_selection.labels[i] for i in carrier_selection.active] # If no bandwidth is selected, use the default value if bandwidth_choose.active == []: bandwidth = None # If the bandwidth select is activated, use the specified bandwith else: bandwidth = bandwidth_select.value new_src = make_dataset(carriers_to_plot, range_start = range_select.value[0], range_end = range_select.value[1], bandwidth = bandwidth) src.data.update(new_src.data) def style(p): # Title p.title.align = 'center' p.title.text_font_size = '20pt' p.title.text_font = 'serif' # Axis titles p.xaxis.axis_label_text_font_size = '14pt' p.xaxis.axis_label_text_font_style = 'bold' p.yaxis.axis_label_text_font_size = '14pt' p.yaxis.axis_label_text_font_style = 'bold' # Tick labels p.xaxis.major_label_text_font_size = '12pt' p.yaxis.major_label_text_font_size = '12pt' return p # Carriers and colors available_carriers = list(set(flights['name'])) available_carriers.sort() airline_colors = Category20_16 airline_colors.sort() # Carriers to plot carrier_selection = CheckboxGroup(labels=available_carriers, active = [0, 1]) carrier_selection.on_change('active', update) range_select = RangeSlider(start = -60, end = 180, value = (-60, 120), step = 5, title = 'Range of Delays (min)') range_select.on_change('value', update) # Initial carriers and data source initial_carriers = [carrier_selection.labels[i] for i in carrier_selection.active] # Bandwidth of kernel bandwidth_select = Slider(start = 0.1, end = 5, step = 0.1, value = 0.5, title = 'Bandwidth for Density Plot') bandwidth_select.on_change('value', update) # Whether to set the bandwidth or have it done automatically bandwidth_choose = CheckboxButtonGroup( labels=['Choose Bandwidth (Else Auto)'], active = []) bandwidth_choose.on_change('active', update) # Make the density data source src = make_dataset(initial_carriers, range_start = range_select.value[0], range_end = range_select.value[1], bandwidth = bandwidth_select.value) # Make the density plot p = make_plot(src) # Add style to the plot p = style(p) # Put controls in a single element controls = WidgetBox(carrier_selection, range_select, bandwidth_select, bandwidth_choose) # Create a row layout layout = row(controls, p) # Make a tab with the layout tab = Panel(child=layout, title = 'Density Plot') return tab