class ButtonApp(HBox): extra_generated_classes = [["ButtonApp", "ButtonApp", "HBox"]] button = Instance(Button) controls = Instance(VBoxForm) @classmethod def create(cls): print "creating app..." obj = cls() obj.button = Button(label="Foo", type="success") obj.button.label = "Bar" obj.controls = VBoxForm(children=[obj.button]) obj.children.append(obj.controls) print "created app!" return obj def setup_events(self): # recursively searches the right level? if not self.button: return self.button.on_click(self.changeLabel) def changeLabel(self): print "changing label..." self.button.label = "BarBar" print "changed label!"
class Workspace(PlotObject): varname = String() data_table = Instance(DataTable, has_ref=True) pivot_tables = List(Instance(PivotTable, has_ref=True), has_ref=True) plots = List(Instance(Plot, has_ref=True), has_ref=True) plot_context = Instance(PlotContext, has_ref=True) active_tab = Int(0)
class GlyphRenderer(PlotObject): data_source = Instance(DataSource, has_ref=True) xdata_range = Instance(DataRange1d, has_ref=True) ydata_range = Instance(DataRange1d, has_ref=True) # How to intepret the values in the data_source units = Enum("screen", "data") # Instance of bokeh.glyphs.Glyph; not declaring it explicitly below # because of circular imports. The renderers should get moved out # into another module... glyph = Instance() def vm_serialize(self): # GlyphRenderers need to serialize their state a little differently, # because the internal glyph instance is turned into a glyphspec return { "id": self._id, "data_source": self.data_source, "xdata_range": self.xdata_range, "ydata_range": self.ydata_range, "glyphspec": self.glyph.to_glyphspec() } def finalize(self, models): super(GlyphRenderer, self).finalize(models) ## FIXME: we shouldn't have to do this i think.. if hasattr(self, 'glyphspec'): glyphspec = self.glyphspec del self.glyphspec self.glyph = PlotObject.get_class(glyphspec['type'])(**glyphspec) else: self.glyph = None
class WashmapApp(VBox): parent_model = "VBox" js_model = "WashmapApp" year = Instance(Slider) source = Instance(ColumnDataSource) wat_all = Instance(ColumnDataSource) san_all = Instance(ColumnDataSource) line_source = Instance(ColumnDataSource) @classmethod def create(cls): obj = cls() obj.year = Slider( title="Year", name='year', value=1990, start=1990, end=2012, step=1 ) wat_all_df = get_wat_stats_all_years() san_all_df = get_san_stats_all_years() data = get_data_with_countries(wat_all_df, san_all_df) source = ColumnDataSource(data) source.selected = [30] line_data = get_line_data('Morocco') line_source = ColumnDataSource(line_data) wat_map = construct_water_map_tools(source) wat_line = construct_water_line(line_source) wat_text = construct_water_text(source) wat_key = construct_key(WATER_COLOR_RANGE) san_map = construct_san_map_tools(source) san_line = construct_san_line(line_source) san_text = construct_san_text(source) san_key = construct_key(SANITATION_COLOR_RANGE) obj.source = source obj.line_source = line_source wat_all_df.year = wat_all_df.year.astype(str) san_all_df.year = san_all_df.year.astype(str) obj.wat_all = ColumnDataSource(wat_all_df) obj.san_all = ColumnDataSource(san_all_df) tabs = Tabs( tabs=[ Panel( title="Water", child=layout_components(wat_map, wat_line, wat_text, wat_key) ), Panel( title="Sanitation", child=layout_components(san_map, san_line, san_text, san_key) ) ] ) obj.children = [tabs, obj.year] return obj
class PivotTable(PlotObject): title = String("Pivot Table") description = String("") source = Instance(has_ref=True) data = Dict() fields = List() # List[{name: String, dtype: String}] rows = List() columns = List() values = List() filters = List() manual_update = Bool(True) def setup_events(self): self.on_change('rows', self, 'get_data') self.on_change('columns', self, 'get_data') self.on_change('values', self, 'get_data') self.on_change('filters', self, 'get_data') if not self.fields: self.fields = self.source.fields() if not self.data: self.get_data() def get_data(self, obj=None, attrname=None, old=None, new=None): self.data = self.source.pivot( dict( rows=self.rows, columns=self.columns, values=self.values, filters=self.filters, ))
class CollisionModifier(HasProps): """Models an special type of operation that alters how glyphs interact. Used to handle the manipulation of glyphs for operations, such as stacking. The list of `CompositeGlyph`s can either be input into the `CollisionModifier` as keyword args, or added individually with the `add_glyph` method. """ comp_glyphs = List(Instance(CompositeGlyph), help="""A list of composite glyphs, to apply the modification to.""") name = String(help="""The name of the collision modifier.""") method_name = String( help="""The name of the method that will be utilized on the composite glyphs. This method must exist on all `comp_glyphs`.""") columns = Either(ColumnLabel, List(ColumnLabel), help="""Some collision modifiers might require column labels to apply the operation in relation to.""") def add_glyph(self, comp_glyph): self.comp_glyphs.append(comp_glyph) def apply(self, renderers=None): if len(self.comp_glyphs) == 0: self.comp_glyphs = renderers if len(self.comp_glyphs) > 0: # the first renderer's operation method is applied to the rest getattr(self.comp_glyphs[0], self.method_name)(self.comp_glyphs) else: raise AttributeError( '%s must be applied to available renderers, none found.' % self.__class__.__name__)
class NestedCompositeGlyph(CompositeGlyph): """A composite glyph that consists of other composite glyphs. An important responsibility of any `CompositeGlyph` is to understand the bounds of the glyph renderers that make it up. This class is used to provide convenient properties that return the bounds from the child `CompositeGlyphs`. """ children = List(Instance(CompositeGlyph)) @property def y_max(self): return max([renderer.y_max for renderer in self.children]) @property def y_min(self): return min([renderer.y_min for renderer in self.children]) @property def x_min(self): return min([renderer.x_min for renderer in self.children]) @property def x_max(self): return max([renderer.x_max for renderer in self.children])
class App(PlotObject): data_source = Instance(ColumnDataSource) scatter_plot = Instance(Plot) stats = String() def update(self, **kwargs): super(App, self).update(**kwargs) if self.data_source: self.data_source.on_change('selected', self, 'selection_change') def selection_change(self, obj, attrname, old, new): pandas_df = pd.DataFrame(self.data_source.data) selected = self.data_source.selected if selected: pandas_df = pandas_df.iloc[selected, :] stats = pandas_df.describe() self.stats = str(stats)
class Legend(PlotObject): plot = Instance(Plot, has_ref=True) annotationspec = Dict(has_ref=True) def vm_serialize(self): #ensure that the type of the annotation spec is set result = super(Legend, self).vm_serialize() result['annotationspec']['type'] = 'legend' return result
class MyApp(BokehApplet): plot = Instance(Plot) source = Instance(ColumnDataSource) def create(self, session): """ This function is called once, and is responsible for creating all objects (plots, datasources, etc) """ self.modelform = MyModel() self.modelform.create_inputs(session) self.source = ColumnDataSource(data={'x': [], 'y': []}) self.update_data() self.plot = line('x', 'y', source=self.source, plot_width=400, plot_height=400, title=self.modelform.title) self.children.append(self.modelform) self.children.append(self.plot) self.add_all(session) def input_change(self, obj, attrname, old, new): """ This function is called whenever the input form changes This is responsible for updating the plot, or whatever you want. The signature is obj : the object that changed attrname : the attr that changed old : old value of attr new : new value of attr """ self.update_data() self.plot.title = self.modelform.title def update_data(self): N = 80 x = np.linspace(0, 4 * np.pi, N) y = np.sin(x) logging.debug("PARAMS %s %s", self.modelform.offset, self.modelform.scale) y = self.modelform.offset + y * self.modelform.scale self.source.data = {'x': x, 'y': y}
class Plot(PlotObject): data_sources = List title = String("Bokeh Plot") x_range = Instance(DataRange1d, has_ref=True) y_range = Instance(DataRange1d, has_ref=True) # We shouldn't need to create mappers manually on the Python side #xmapper = Instance(LinearMapper) #ymapper = Instance(LinearMapper) #mapper = Instance(GridMapper) # A list of all renderers on this plot; this includes guides as well # as glyph renderers renderers = List(has_ref=True) tools = List(has_ref=True) # TODO: These don't appear in the CS source, but are created by mpl.py, so # I'm leaving them here for initial compatibility testing. axes = List(has_ref=True) # TODO: How do we want to handle syncing of the different layers? # image = List # underlay = List # glyph = List # overlay = List # annotation = List height = Int(400) width = Int(400) background_fill = Color("white") border_fill = Color("white") canvas_width = Int(400) canvas_height = Int(400) outer_width = Int(400) outer_height = Int(400) border_top = Int(50) border_bottom = Int(50) border_left = Int(50) border_right = Int(50)
class App(HBox): extra_generated_classes = [["App", "App", "HBox"]] plot = Instance(Plot) button = Instance(Button) @classmethod def create(cls): """One-time creation of app's objects. This function is called once, and is responsible for creating all objects (plots, datasources, etc) """ obj = cls() plot = figure(x_range=(-2, 1), y_range=(-1, 1), tools=[], plot_width=450, plot_height=300, toolbar_location=None) plot.line([-0.5, 0.5], [-0.5, 0.5]) obj.plot = plot button = Button(label='click!') obj.button = button obj.children.append(obj.plot) obj.children.append(obj.button) return obj def setup_events(self): super(App, self).setup_events() if not self.button: return self.button.on_click(self.click) def click(self, *args): print('***click***')
class CDX(PlotObject): namespace = Instance(Namespace, has_ref=True) workspaces = List(Instance(Workspace, has_ref=True), has_ref=True) active_workspace = Instance(Workspace, has_ref=True) activeplot = Instance(Plot, has_ref=True) plotlist = Instance(PlotList, has_ref=True) plotcontext = Instance(PlotContext, has_ref=True) # list of to level UI elems
class DataTable(PlotObject): source = Instance(has_ref=True) sort = List() group = List() offset = Int(default=0) length = Int(default=100) maxlength = Int() totallength = Int() tabledata = Dict() filterselected = Bool(default=False) def setup_events(self): self.on_change('sort', self, 'get_data') self.on_change('group', self, 'get_data') self.on_change('length', self, 'get_data') self.on_change('offset', self, 'get_data') self.on_change('filterselected', self, 'get_data') self.source.on_change('selected', self, 'get_data') self.source.on_change('data', self, 'get_data') self.source.on_change('computed_columns', self, 'get_data') if not self.tabledata: self.get_data() def transform(self): return dict( sort=self.sort, group=self.group, offset=self.offset, length=self.length, filterselected=self.filterselected, ) def setselect(self, select): self.source.setselect(select, self.transform()) self.get_data() def select(self, select): self.source.select(select, self.transform()) self.get_data() def deselect(self, deselect): self.source.deselect(deselect, self.transform()) self.get_data() def get_data(self, obj=None, attrname=None, old=None, new=None): data = self.source.get_data(self.transform()) self.maxlength = data.pop('maxlength') self.totallength = data.pop('totallength') self.tabledata = data
class RadialGraph(HasProps): # The start/end angles of the radial plot in degrees start_angle = Float end_angle = Float # The datasources containing ata for the graph _node_source = Instance(DataSource) _edge_source = Instance(DataSource) _session = Any _doc = Any def __init__(self, **kw): super(RadialGraph, self).__init__(**kw) self._node_source = ColumnDataSource(dict(id=[], time=[], relevance=[])) self._edge_source = ColumnDataSource(dict(parent=[], child=[])) self._session = Session() self._doc = Document() def update_data(self, nodes, edges): """ Provides updated data for the datasources.
class Bins(Stat): """A set of many individual Bin stats. Bin counts using: https://en.wikipedia.org/wiki/Freedman%E2%80%93Diaconis_rule """ bin_count = Either(Int, Float) bin_width = Float(default=None, help='Use Freedman-Diaconis rule if None.') bins = List(Instance(Bin)) q1 = Quantile(interval=0.25) q3 = Quantile(interval=0.75) labels = List(String) def __init__(self, values=None, column=None, bins=None, **properties): properties['values'] = values properties['column'] = column properties['bins'] = bins super(Bins, self).__init__(**properties) def update(self): values = self.get_data() self.q1.set_data(values) self.q3.set_data(values) if self.bin_count is None: self.calc_num_bins(values) def calculate(self): binned, bin_edges = pd.cut(self.get_data(), self.bin_count, retbins=True, precision=0) df = pd.DataFrame(dict(values=self.get_data(), bins=binned)) bins = [] for name, group in df.groupby('bins'): bins.append(Bin(bin_label=name, values=group['values'])) self.bins = bins def calc_num_bins(self, values): iqr = self.q3.value - self.q1.value self.bin_width = 2 * iqr * (len(values)**-(1. / 3.)) self.bin_count = np.ceil( (self.values.max() - self.values.min()) / self.bin_width)
class CollisionModifier(HasProps): renderers = List(Instance(CompositeGlyph)) name = String() method_name = String() columns = Either(ColumnLabel, List(ColumnLabel)) def add_renderer(self, renderer): self.renderers.append(renderer) def apply(self, renderers=None): if len(self.renderers) == 0: self.renderers = renderers if len(self.renderers) > 0: # the first renderer's operation method is applied to the rest getattr(self.renderers[0], self.method_name)(self.renderers) else: raise AttributeError( '%s must be applied to available renderers, none found.' % self.__class__.__name__)
class NestedCompositeGlyph(CompositeGlyph): """A composite glyph that consists of other composite glyphs.""" children = List(Instance(CompositeGlyph)) @property def y_max(self): return max([renderer.y_max for renderer in self.children]) @property def y_min(self): return min([renderer.y_min for renderer in self.children]) @property def x_min(self): return min([renderer.x_min for renderer in self.children]) @property def x_max(self): return max([renderer.x_max for renderer in self.children])
class PandasPlotSource(ColumnDataSource): source = Instance(has_ref=True) def __init__(self, *args, **kwargs): super(PandasPlotSource, self).__init__(*args, **kwargs) def setup_events(self): self.on_change('selected', self, 'selection_callback') self.source.on_change('selected', self, 'get_data') self.source.on_change('data', self, 'get_data') self.source.on_change('computed_columns', self, 'get_data') if not self.data: self.get_data() def selection_callback(self, obj=None, attrname=None, old=None, new=None): self.setselect(self.selected) def transform(self): return {} def setselect(self, select): self.source.setselect(select, self.transform()) self.get_data() def select(self, select): self.source.select(select, self.transform()) self.get_data() def deselect(self, deselect): self.source.deselect(deselect, self.transform()) self.get_data() def get_data(self, obj=None, attrname=None, old=None, new=None): data = self.source.get_data(self.transform()) #ugly: self._selected = np.nonzero(data['data']['_selected'])[0] self.maxlength = data.pop('maxlength') self.totallength = data.pop('totallength') self.column_names = data['column_names'] self.data = data['data']
class Bin(Stat): """Represents a single bin of data values and attributes of the bin.""" label = String() start = Float() stop = Float() start_label = String() stop_label = String() center = Float() stat = Instance(Stat, default=Count()) def __init__(self, bin_label, values, **properties): properties['label'] = bin_label properties['start'], properties['stop'] = self.binstr_to_list( bin_label) properties['center'] = (properties['start'] + properties['stop']) / 2.0 properties['values'] = values super(Bin, self).__init__(**properties) @staticmethod def binstr_to_list(bins): """Produce a consistent display of a bin of data.""" value_chunks = bins.split(',') value_chunks = [ val.replace('[', '').replace(']', '').replace('(', '').replace(')', '') for val in value_chunks ] bin_values = [float(value) for value in value_chunks] return bin_values[0], bin_values[1] def update(self): self.stat.set_data(self.values) def calculate(self): self.value = self.stat.value
class Y(PlotObject): t1 = Instance(T, has_ref=True)
class PDEApp(HBox): # ============================================================================== # Only bokeh quantities for layout, data, controls... go here! # ============================================================================== extra_generated_classes = [["PDEApp", "PDEApp", "HBox"]] # layout controls = Instance(VBoxForm) # controllable values value1 = Instance(Slider) value2 = Instance(Slider) # plot plot = Instance(Plot) # data source = Instance(ColumnDataSource) @classmethod def create(cls): # ============================================================================== # creates initial layout and data # ============================================================================== obj = cls() # initialize data source obj.source = ColumnDataSource(data=dict(z=[])) # initialize controls # slider controlling stepsize of the solver obj.value2 = Slider(title="value2", name='value2', value=1, start=-1, end=+1, step=.1) # slider controlling initial value of the ode obj.value1 = Slider(title="value1", name='value1', value=0, start=-1, end=+1, step=.1) # initialize plot toolset = "crosshair,pan,reset,resize,wheel_zoom,box_zoom" # Generate a figure container plot = figure( title_text_font_size="12pt", plot_height=400, plot_width=400, tools=toolset, # title=obj.text.value, title="somestuff", x_range=[-1, 1], y_range=[-1, 1]) # Plot the numerical solution by the x,t values in the source property plot.image( image='z', x=-1, y=-1, dw=2, dh=2, #palette="Spectral11", color_mapper=LinearColorMapper(palette=svg_palette_jet, low=-2, high=2), source=obj.source) obj.plot = plot # calculate data obj.update_data() # lists all the controls in our app obj.controls = VBoxForm(children=[obj.value1, obj.value2]) # make layout obj.children.append(obj.plot) obj.children.append(obj.controls) # don't forget to return! return obj def setup_events(self): # ============================================================================== # Here we have to set up the event behaviour. # ============================================================================== # recursively searches the right level? if not self.value1: return # event registration self.value2.on_change('value', self, 'input_change') self.value1.on_change('value', self, 'input_change') def input_change(self, obj, attrname, old, new): # ============================================================================== # This function is called if input changes # ============================================================================== print "input changed!" self.update_data() def update_data(self): # ============================================================================== # Updated the data respective to input # ============================================================================== print "updating data..." v1 = self.value1.value v2 = self.value2.value N = 200 x, y = np.meshgrid(np.linspace(-1, 1, N), np.linspace(-1, 1, N)) z = v1 * x**2 + v2 * y**2 self.source.data = dict(z=[z.tolist()]) print "data was updated with parameters: v1=" + str( v1) + " and v2=" + str(v2) print "new z:" print z
def test_Instance(self): with self.assertRaises(TypeError): prop = Instance() prop = Instance(Foo) self.assertTrue(prop.is_valid(None)) self.assertFalse(prop.is_valid(False)) self.assertFalse(prop.is_valid(True)) self.assertFalse(prop.is_valid(0)) self.assertFalse(prop.is_valid(1)) self.assertFalse(prop.is_valid(0.0)) self.assertFalse(prop.is_valid(1.0)) self.assertFalse(prop.is_valid(1.0 + 1.0j)) self.assertFalse(prop.is_valid("")) self.assertFalse(prop.is_valid(())) self.assertFalse(prop.is_valid([])) self.assertFalse(prop.is_valid({})) self.assertTrue(prop.is_valid(Foo())) self.assertFalse(prop.is_valid(Bar())) self.assertFalse(prop.is_valid(Baz()))
class Z1(HasProps): t2 = Instance(T, has_ref=True)
class HotelApp(VBox): extra_generated_classes = [["HotelApp", "HotelApp", "VBox"]] jsmodel = "VBox" # input selectr = Instance(Select) #check_group = Instance(RadioGroup) check_group = Instance(CheckboxGroup) # plots plot = Instance(GMapPlot) filler = Instance(Plot) filler2 = Instance(Plot) bar_plot = Instance(Plot) legend_plot = Instance(Plot) legend_filler = Instance(Plot) # data source source = Instance(ColumnDataSource) county_source = Instance(ColumnDataSource) # layout boxes checkbox = Instance(VBox) mainrow = Instance(HBox) statsbox = Instance(VBox) mapbox = Instance(VBox) legendbox = Instance(HBox) totalbox = Instance(VBox) # inputs #ticker1_select = Instance(Select) #ticker2_select = Instance(Select) #input_box = Instance(VBoxForm) def make_inputs(self): with open("states.csv") as f: states = [line.strip().split(',') for line in f.readlines()] self.selectr = Select( name='states', value='Choose A State', options=[s[1] for s in states] + ['Choose A State'], ) labels = ["County Averages", "Hotels"] self.check_group = CheckboxGroup(labels=labels, active=[0, 1], inline=True) ##Filler plot x_range = Range1d(0, 300) y_range = Range1d(0, 12) self.filler = Plot(x_range=x_range, y_range=y_range, title="", plot_width=300, plot_height=12, min_border=0, **PLOT_FORMATS) x_range = Range1d(0, 300) y_range = Range1d(0, 18) self.filler2 = Plot(x_range=x_range, y_range=y_range, title="", plot_width=300, plot_height=14, min_border=0, **PLOT_FORMATS) def make_outputs(self): pass #self.pretext = Paragraph(text="", width=800) def __init__(self, *args, **kwargs): super(HotelApp, self).__init__(*args, **kwargs) self._show_counties = True self._show_hotels = True @classmethod def create(cls): """ This function is called once, and is responsible for creating all objects (plots, datasources, etc) """ # create layout widgets obj = cls() obj.mainrow = HBox() obj.checkbox = VBox(height=50) obj.mapbox = VBox() #obj.bottomrow = HBox() obj.statsbox = VBox(width=500) obj.totalbox = VBox() obj.legendbox = HBox() labels = ["County Average Ratings", "Hotel Locations"] obj.make_inputs() obj.make_outputs() # outputs #obj.pretext = Paragraph(text="", width=500) obj.make_source() obj.make_county_source() lat = 39.8282 lng = -98.5795 zoom = 6 xr = Range1d() yr = Range1d() #obj.make_plots(lat, lng, zoom, xr, yr) obj.make_plots() # layout obj.set_children() return obj @property def selected_df(self): pandas_df = self.df selected = self.source.selected print "seeing if selected!" if selected: idxs = selected['1d']['indices'] pandas_df = pandas_df.iloc[idxs, :] else: pandas_df = pandas_df.iloc[0:0, :] return pandas_df def make_source(self): self.source = ColumnDataSource(data=self.df) self.source.callback = Callback(args=dict(), code=""" var inds = cb_obj.get('selected')['1d'].indices; var theidx = inds[0]; console.log("yep"); console.log(theidx); $.get( "reviews", {id: theidx}, function( response ) { $( "#section2" ).html( response ); }, "html"); console.log("done"); """) def update_source(self): if self.selectr.value is None or self.selectr.value == 'Choose A State': df = hdata else: df = hdata[hdata['state'] == self.selectr.value] new_data = {} for col in df: new_data[col] = df[col] self.source.data = new_data def make_county_source(self): self.county_source = ColumnDataSource(data=self.countydf) def update_county_source(self): if self.selectr.value is None or self.selectr.value == 'Choose A State': df = county_data else: df = county_data[county_data['state'] == self.selectr.value] new_data = {} for col in df: new_data[col] = df[col] self.county_source.data = new_data #for col in df: # self.county_source.data[col] = df[col] def make_plots(self): self.create_map_plot() self.create_legend() self.populate_glyphs() self.make_bar_plot() def create_legend(self): x_range = Range1d(0, 185) y_range = Range1d(0, 130) text_box = Plot(x_range=x_range, y_range=y_range, title="", plot_width=185, plot_height=130, min_border=0, **PLOT_FORMATS) FONT_PROPS_SM['text_font_size'] = '11pt' text_box.add_glyph( Text(x=35, y=9, text=['Low Average Rating'], **FONT_PROPS_SM)) text_box.add_glyph( Rect(x=18, y=18, width=25, height=25, fill_color='#ef4e4d', line_color=None)) text_box.add_glyph( Text(x=35, y=49, text=['Medium Average Rating'], **FONT_PROPS_SM)) text_box.add_glyph( Rect(x=18, y=58, width=25, height=25, fill_color='#14a1af', line_color=None)) text_box.add_glyph( Text(x=35, y=89, text=['High Average Rating'], **FONT_PROPS_SM)) text_box.add_glyph( Rect(x=18, y=98, width=25, height=25, fill_color='#743184', line_color=None)) self.legend_plot = text_box ##Filler plot x_range = Range1d(0, 40) y_range = Range1d(0, 100) self.legend_filler = Plot(x_range=x_range, y_range=y_range, title="", plot_width=40, plot_height=100, min_border=0, **PLOT_FORMATS) def create_map_plot(self): lat = 39.8282 lng = -98.5795 zoom = 6 xr = Range1d() yr = Range1d() x_range = xr y_range = yr #map_options = GMapOptions(lat=39.8282, lng=-98.5795, zoom=6) map_options = GMapOptions(lat=lat, lng=lng, zoom=zoom) #map_options = GMapOptions(lat=30.2861, lng=-97.7394, zoom=15) plot = GMapPlot(x_range=x_range, y_range=y_range, map_options=map_options, plot_width=680, plot_height=600, title=" ") plot.map_options.map_type = "hybrid" xaxis = LinearAxis(axis_label="lon", major_tick_in=0, formatter=NumeralTickFormatter(format="0.000")) plot.add_layout(xaxis, 'below') yaxis = LinearAxis(axis_label="lat", major_tick_in=0, formatter=PrintfTickFormatter(format="%.3f")) plot.add_layout(yaxis, 'left') self.plot = plot def populate_glyphs(self): self.plot.renderers = [] self.plot.tools = [] if self._show_counties: print "showing you the counties" #datasource = ColumnDataSource(county_data) #apatch = Patches(xs=county_xs, ys=county_ys, fill_color='white') #apatch = Patches(xs='xs', ys='ys', fill_color='colors', fill_alpha="alpha") apatch = Patches(xs='xs', ys='ys', fill_color='thecolors', fill_alpha='alpha') self.plot.add_glyph(self.county_source, apatch, name='counties') if self._show_hotels: print "showing you the hotels" circle2 = Circle(x="lon", y="lat", size=10, fill_color="fill2", fill_alpha=1.0, line_color="black") circle = Circle(x="lon", y="lat", size=10, fill_color="fill", fill_alpha=1.0, line_color="black") #print "source is ", self.source['lon'], self.source['lat'], self.source['f1ll'] self.plot.add_glyph(self.source, circle2, nonselection_glyph=circle, name='hotels') #county_xs, county_ys = get_some_counties() rndr = self.plot.renderers[-1] pan = PanTool() wheel_zoom = WheelZoomTool() box_select = BoxSelectTool() box_select.renderers = [rndr] tooltips = "@name" tooltips = "<span class='tooltip-text'>@names</span>\n<br>" tooltips += "<span class='tooltip-text'>Reviews: @num_reviews</span>" hover = HoverTool(tooltips=tooltips, names=['hotels']) tap = TapTool(names=['hotels']) self.plot.add_tools(pan, wheel_zoom, box_select, hover, tap) overlay = BoxSelectionOverlay(tool=box_select) self.plot.add_layout(overlay) def make_bar_plot(self): # create a new plot y_rr = Range1d(start=0.0, end=5.0) TOOLS = "box_select,lasso_select" #x's and y's based on selected_df sdf = self.selected_df[['names', 'ratings']] xvals = [1.0 * i + 0.5 for i in range(0, len(sdf['names']))] rightvals = [1.0 * i + 0.85 for i in range(0, len(sdf['names']))] ratings = [r for r in sdf['ratings']] centers = [0.5 * r for r in ratings] bottoms = [0] * len(ratings) y_text = [y + 1.0 for y in ratings] width = [1.0] * len(ratings) all_names = [] for n in sdf['names']: short_name = n[:20] idx = short_name.rfind(" ") all_names.append(short_name[:idx]) while len(all_names) > 0 and len(all_names) < 5: all_names.append(" ") bar_plot = figure(tools=TOOLS, width=400, height=350, x_range=all_names, y_range=y_rr, title="Average Rating") bar_plot.title_text_color = "black" bar_plot.title_text_font_size = '15pt' bar_plot.title_text_font = 'Avenir' bar_plot.title_text_align = "right" print "all_names ", all_names bar_colors = [] for r in ratings: if r >= 4.0: bar_colors.append("#743184") elif r >= 3.0: bar_colors.append("#14a1af") else: bar_colors.append("#ef4e4d") bar_plot.xaxis.major_label_orientation = pi / 2.3 bar_plot.rect(x=all_names, y=centers, width=width, height=ratings, color=bar_colors, line_color="black") #glyph = Text(x=xvals, y=y_text, text=sdf['names'], angle=pi/4, #text_align="left", text_baseline="middle") #glyphs = [Text(x=x, y=y, text=[n], angle=pi/4, text_align="left", text_baseline="middle") #for x, y, n in zip(xvals, y_text, all_names)] bar_plot.xaxis.major_tick_line_color = None bar_plot.xaxis.minor_tick_line_color = None bar_plot.yaxis.minor_tick_line_color = None bar_plot.xgrid.grid_line_color = None bar_plot.ygrid.grid_line_color = None self.bar_plot = bar_plot def set_children(self): self.children = [self.totalbox] self.totalbox.children = [self.mainrow] self.mainrow.children = [self.statsbox, self.mapbox] self.mapbox.children = [self.plot] #self.checkbox.children = [self.filler, self.check_group, self.filler2] self.statsbox.children = [self.bar_plot, self.legendbox] self.legendbox.children = [self.legend_filler, self.legend_plot] #self.bottomrow.children = [self.pretext] def setup_events(self): super(HotelApp, self).setup_events() if self.source: self.source.on_change('selected', self, 'selection_change') if self.selectr: self.selectr.on_change('value', self, 'input_change') if self.check_group: self.check_group.on_change('active', self, 'check_change') @property def df(self): thedf = return_hotel_data() if self.selectr.value is None or self.selectr.value == 'Choose A State': return thedf else: newdf = thedf[thedf['state'] == self.selectr.value] return newdf @property def countydf(self): thedf = county_data if self.selectr.value is None or self.selectr.value == 'Choose A State': return thedf else: newdf = thedf[thedf['state'] == self.selectr.value] return newdf def selection_change(self, obj, attrname, old, new): #self.make_source() self.update_source() self.make_bar_plot() self.set_children() curdoc().add(self) def check_change(self, obj, attrname, old, new): #Turn on/off the counties/hotel data print "what the heck ", obj, attrname, old, new if 0 in new: self._show_counties = True else: self._show_counties = False if 1 in new: self._show_hotels = True else: self._show_hotels = False self.populate_glyphs() self.set_children() curdoc().add(self) def input_change(self, obj, attrname, old, new): #import pdb;pdb.set_trace() print "source len: ", len(self.source.data['state']) print "county len: ", len(self.county_source.data['names']) self.update_source() self.update_county_source() print "source len: ", len(self.source.data['state']) print "county len: ", len(self.county_source.data['names']) if self.selectr.value is None or self.selectr.value == 'Choose A State': pass else: self.plot.title = self.selectr.value
def test_Instance(self): with self.assertRaises(TypeError): prop = Instance() prop = Instance(Foo) self.assertTrue(prop.is_valid(None)) self.assertFalse(prop.is_valid(False)) self.assertFalse(prop.is_valid(True)) self.assertFalse(prop.is_valid(0)) self.assertFalse(prop.is_valid(1)) self.assertFalse(prop.is_valid(0.0)) self.assertFalse(prop.is_valid(1.0)) self.assertFalse(prop.is_valid(1.0+1.0j)) self.assertFalse(prop.is_valid("")) self.assertFalse(prop.is_valid(())) self.assertFalse(prop.is_valid([])) self.assertFalse(prop.is_valid({})) self.assertTrue(prop.is_valid(Foo())) self.assertFalse(prop.is_valid(Bar())) self.assertFalse(prop.is_valid(Baz()))
class ShoeApp(VBox): extra_generated_classes = [["ShoeApp", "ShoeApp", "VBox"]] jsmodel = "VBox" # plots plot = Instance(Plot) brand_plot = Instance(Plot) legend_plot = Instance(Plot) # data source source = Instance(ColumnDataSource) brand_source = Instance(ColumnDataSource) # select selectr = Instance(Select) selectr_filler = Instance(Plot) # layout boxes bigbox = Instance(VBox) totalbox = Instance(HBox) brandbox = Instance(VBox) selectrbox = Instance(HBox) def __init__(self, *args, **kwargs): super(ShoeApp, self).__init__(*args, **kwargs) @classmethod def create(cls): """ This function is called once, and is responsible for creating all objects (plots, datasources, etc) """ # create layout widgets obj = cls() obj.bigbox = VBox(width=670) obj.totalbox = HBox() obj.brandbox = VBox() obj.selectrbox = HBox() obj.make_source() # outputs obj.make_better_plots() obj.make_inputs() # layout obj.set_children() return obj def make_inputs(self): x_range = Range1d(0, 30) y_range = Range1d(0, 12) self.selectr_filler = Plot(x_range=x_range, y_range=y_range, title="", plot_width=30, plot_height=12, min_border=0, **PLOT_FORMATS) self.selectr = Select( name='brands', value='Select A Brand', options=pop_brands + ['Select A Brand'], ) def make_source(self): self.source = ColumnDataSource(data=self.df) self.source.callback = Callback(args=dict(), code=""" var inds = cb_obj.get('selected')['1d'].indices; var theidx = inds[0]; var d1 = cb_obj.get("data"); var brand = d1["brand"][theidx]; console.log("yep"); console.log(theidx); $.get( "shoes", {id: brand}, function( response ) { console.log("logging rep"); console.log(response); console.log("done logging rep"); $( "#child" ).html( response ); }, "html"); console.log("done"); """) self.make_brand_source() def make_brand_source(self): self.brand_source = ColumnDataSource(data=self.brand_df) def configure_brand_source(self, min_idx=0, max_idx=MAX_IDX): bdf = self.brand_df #min_idx, max_idx = shoes_func.min_max_range(ranges, bdf['price']) min_idx, max_idx = shoes_func.min_max_range(orig_order, bdf['price']) counts = [0] * (max_idx - min_idx + 1) for i in bdf.index: ans = bdf.ix[i] #idx = int(ans['price'] + 100)//100 + 1 idx = int(ans['price'] // 100) print "idx is ", idx print "price is ", ans['price'] #Categorical stuff #xcat.append(ranges[idx-2]) #_shoedf.loc[i, 'brand_y'] = (counts[idx - min_idx] - 0.5*counts[idx - min_idx]) _shoedf.loc[i, 'brand_y'] = (counts[idx - min_idx]) + 0.5 counts[idx - min_idx] = counts[idx - min_idx] + 1 #quad stuff #xvals.append(idx - 0.25) #rightvals.append(idx + 0.25) #bottoms.append(counts[idx]/2) #tops.append(counts[idx] + 0.5) #fills.append(brand_to_color[ans['brand']]) return None def make_better_plots(self): TOOLS = "box_select,lasso_select" tooltips = "<span class='tooltip-text'>Name: @name</span>\n<br>" tooltips += "<span class='tooltip-text'>Brand: @brand</span>\n<br>" tooltips += "<span class='tooltip-text'>Price: @price</span>\n<br>" #hover = HoverTool(tooltips="@num_reviews") #hover = HoverTool(tooltips="@names") hover = HoverTool(tooltips=tooltips) tap = TapTool() #p = figure(tools=TOOLS, width=1100, height=700, x_range=x_rr, y_range=y_rr, title="Price Distribution") #p = figure(tools=TOOLS, width=1100, height=700, title="Price Distribution") #p = figure(tools=TOOLS, width=1100, height=700, x_range=ranges, title="Price Distribution", angle=pi/4) #p = figure(tools=TOOLS, width=1100, height=700, x_range=ranges, title="Price Distribution") p = figure(tools=TOOLS, width=580, height=1000, y_range=ranges, x_axis_location="above", toolbar_location=None) p.yaxis.major_label_orientation = pi / 4 p.yaxis.axis_label_text_font = 'Avenir' #p.quad(left='xvals', right='rightvals', top='tops', bottom='bottoms', color='fills', source=self.dfsource) #p.rect(x='xcat', y='yvals', width='width', height='height', color='fills', source=self.source) p.rect(x='yvals', y='xcat', width='width', height='height', color='fills', source=self.source) p.add_tools(hover, tap) self.plot = p self.make_brand_plot() self.make_legend_plot() def make_legend_plot(self, min_idx=0, max_idx=MAX_IDX): x_range = Range1d(0, 90) y_range = Range1d(0, 295) x_range = Range1d(0, 580) y_range = Range1d(0, 30) text_box = Plot(x_range=x_range, y_range=y_range, title="", plot_width=580, plot_height=30, min_border=0, **PLOT_FORMATS) prices_aves = [ "67 ", "185", "271", "367", "500", "685", "827", "989", "1242", "1354", "1611" ] text_box.add_glyph(Text(x=2, y=1, text=['Ave:'], **FONT_PROPS_SMALLER)) text_box.add_glyph( Text(x=24, y=1, text=['$' + prices_aves[0]], **FONT_PROPS_SMALLER)) text_box.add_glyph( Rect(x=33, y=22, width=23, height=10, fill_color=Spectral11[0], line_color=None)) for i in range(1, 11): text_box.add_glyph( Text(x=(21 + 52 * i), y=1, text=['$' + prices_aves[i]], **FONT_PROPS_SMALLER)) text_box.add_glyph( Rect(x=33 + 52 * i, y=22, width=23, height=10, fill_color=Spectral11[i], line_color=None)) self.legend_plot = text_box def make_brand_plot(self, min_idx=0, max_idx=MAX_IDX): TOOLS = "box_select,lasso_select" tooltips = "<span class='tooltip-text'>Name: @name</span>\n<br>" tooltips += "<span class='tooltip-text'>Brand: @brand</span>\n<br>" tooltips += "<span class='tooltip-text'>Price: @price</span>\n<br>" hover = HoverTool(tooltips=tooltips) bdf = self.brand_df if len(bdf) > 0: title = "Brand: " + self.brand_df['brand'].values[0] else: title = "" brand_ranges = orig_order[min_idx:max_idx + 1] p = figure(tools=TOOLS, width=420, height=400, x_range=brand_ranges, title=title, toolbar_location=None) p.xaxis.major_label_orientation = pi / 4 p.title_text_font = 'Avenir' p.title_text_font_size = '14pt' #p.quad(left='xvals', right='rightvals', top='tops', bottom='bottoms', color='fills', source=self.dfsource) p.rect(x='xcat', y='brand_y', line_color='black', width='width', height='brand_height', color='fills', source=self.brand_source) p.add_tools(hover) self.brand_plot = p def set_children(self): self.children = [self.totalbox] self.totalbox.children = [self.bigbox, self.brandbox] self.bigbox.children = [self.legend_plot, self.plot] self.brandbox.children = [self.selectrbox, self.brand_plot] self.selectrbox.children = [self.selectr_filler, self.selectr] #self.totalbox.children = [self.mainrow, self.bottomrow] #self.mainrow.children = [self.plot] #self.bottomrow.children = [self.hist_plot, self.selectr] #self.mainrow.children = [self.selectr] #self.bottomrow.children = [self.plot] def input_change(self, obj, attrname, old, new): self.make_source() self.make_better_plots() self.set_children() curdoc().add(self) def setup_events(self): super(ShoeApp, self).setup_events() if self.source: self.source.on_change('selected', self, 'selection_change') if self.selectr: self.selectr.on_change('value', self, 'brand_change') def selection_change(self, obj, attrname, old, new): #self.make_brand_plot #self.set_children() #curdoc().add(self) bdf = self.brand_df min_idx, max_idx = shoes_func.min_max_range(ranges, bdf['price']) self.configure_brand_source(min_idx, max_idx) self.make_brand_source() self.make_brand_plot(min_idx, max_idx) self.set_children() curdoc().add(self) def brand_change(self, obj, attrname, old, new): bdf = self.brand_df if self.selectr.value is None or self.selectr.value == 'Select A Brand': return self.update_selected_on_source(self.selectr.value) self.set_children() curdoc().add(self) def update_selected_on_source(self, brand): # {'2d': {'indices': []}, '1d': {'indices': []}, '0d': {'indices': [], 'flag': False}} brand_df = _shoedf[_shoedf['brand'] == brand] new_indices = { '2d': { 'indices': [] }, '1d': { 'indices': [] }, '0d': { 'indices': [], 'flag': False } } for _id in brand_df.index: new_indices['1d']['indices'].append(_id) self.source.selected = new_indices @property def df(self): return _shoedf @property def brand_df(self): pandas_df = self.df selected = self.source.selected if selected['1d']['indices']: idxs = selected['1d']['indices'] sel_brand = pandas_df.iloc[idxs[0], :]['brand'] #pandas_df = pandas_df.iloc[idxs, :] #return _shoedf[_shoedf['brand'] =='manolo blahnik'] return _shoedf[_shoedf['brand'] == sel_brand] else: return pandas_df.iloc[0:0, :]
class PandasPivotTable(PlotObject): source = Instance(has_ref=True) sort = List() group = List() offset = Int(default=0) length = Int(default=100) maxlength = Int() totallength = Int() precision = Dict() tabledata = Dict() filterselected = Bool(default=False) def setup_events(self): self.on_change('sort', self, 'get_data') self.on_change('group', self, 'get_data') self.on_change('length', self, 'get_data') self.on_change('offset', self, 'get_data') self.on_change('precision', self, 'get_data') self.on_change('filterselected', self, 'get_data') self.source.on_change('selected', self, 'get_data') self.source.on_change('data', self, 'get_data') self.source.on_change('computed_columns', self, 'get_data') if not self.tabledata: self.get_data() def format_data(self, jsondata): """inplace manipulation of jsondata """ precision = self.precision for colname, data in jsondata.iteritems(): if colname == '_selected' or colname == '_counts': continue if self.source.metadata.get(colname, {}).get('date'): isdate = True else: isdate = False for idx, val in enumerate(data): if isdate: timeobj = time.localtime(val / 1000.0) data[idx] = time.strftime("%Y-%m-%d %H:%M:%S", timeobj) if isinstance(val, float): data[idx] = "%%.%df" % precision.get(colname, 2) % data[idx] def transform(self): return dict( sort=self.sort, group=self.group, offset=self.offset, length=self.length, filterselected=self.filterselected, ) def setselect(self, select): self.source.setselect(select, self.transform()) self.get_data() def select(self, select): self.source.select(select, self.transform()) self.get_data() def deselect(self, deselect): self.source.deselect(deselect, self.transform()) self.get_data() def get_data(self, obj=None, attrname=None, old=None, new=None): data = self.source.get_data(self.transform()) print data['data']['_selected'] self.maxlength = data.pop('maxlength') self.totallength = data.pop('totallength') self.format_data(data['data']) self.tabledata = data
class X2(PlotObject): y = Instance(Y, has_ref=True) z2 = Instance(Z2, has_ref=True)
class X1(PlotObject): y = Instance(Y, has_ref=True) z1 = Instance(Z1, has_ref=False)
class Z2(PlotObject): t2 = Instance(T, has_ref=True)