class DatetimeAxis(LinearAxis): type = String("datetime_axis") axis_label = String("date") scale = String("time") num_labels = Int(8) char_width = Int(10) fill_ratio = Float(0.3) formats = Dict({"days": ["%m/%d/%Y"]})
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 GridPlot(PlotObject): """ A 2D grid of plots """ __view_model__ = "GridPlotContainer" children = List(List) border_space = Int(0)
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 Grid(GuideRenderer): """ 1D Grid component """ type = String("grid") dimension = Int(0) bounds = String('auto') # Line props grid_props = Include(LineProps, prefix="grid")
def test_Int(self): prop = Int() self.assertTrue(prop.is_valid(None)) # TODO: self.assertFalse(prop.is_valid(False)) # TODO: self.assertFalse(prop.is_valid(True)) self.assertTrue(prop.is_valid(0)) self.assertTrue(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.assertFalse(prop.is_valid(Foo()))
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)
def test_Int(self): prop = Int() self.assertTrue(prop.is_valid(None)) # TODO: self.assertFalse(prop.is_valid(False)) # TODO: self.assertFalse(prop.is_valid(True)) self.assertTrue(prop.is_valid(0)) self.assertTrue(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.assertFalse(prop.is_valid(Foo()))
class GuideRenderer(PlotObject): plot = Instance dimension = Int(0) location = String('min') bounds = String('auto') def __init__(self, **kwargs): super(GuideRenderer, self).__init__(**kwargs) if self.plot is not None: if self not in self.plot.renderers: self.plot.renderers.append(self) def vm_serialize(self): props = self.vm_props(withvalues=True) del props["plot"] return {"id": self._id, "plot": self.plot, "guidespec": props}
class LineGlyph(XyGlyph): """Represents a group of data as a line.""" width = Int(default=2) dash = Enum(DashPattern, default='solid') def __init__(self, x=None, y=None, line_color=None, width=None, dash=None, **kwargs): kwargs['x'] = x kwargs['y'] = y if line_color is not None: kwargs['line_color'] = line_color if width is not None: kwargs['width'] = width if dash is not None: kwargs['dash'] = dash super(LineGlyph, self).__init__(**kwargs) self.setup() def build_source(self): if self.x is None: x = self.y.index data = dict(x_values=x, y_values=self.y) elif self.y is None: y = self.x.index data = dict(x_values=self.x, y_values=y) else: data = dict(x_values=self.x, y_values=self.y) return ColumnDataSource(data) def build_renderers(self): """Yield a `GlyphRenderer` for the group of data.""" glyph = Line(x='x_values', y='y_values', line_color=self.line_color, line_alpha=self.line_alpha, line_width=self.width, line_dash=self.dash) yield GlyphRenderer(glyph=glyph)
class LinearAxis(GuideRenderer): type = String("linear_axis") dimension = Int(0) location = Either(String('min'), Float) bounds = String('auto') axis_label = String axis_label_standoff = Int axis_label_props = Include(TextProps, prefix="axis_label") major_label_standoff = Int major_label_orientation = Either(Enum("horizontal", "vertical"), Int) major_label_props = Include(TextProps, prefix="major_label") # Line props axis_props = Include(LineProps, prefix="axis") tick_props = Include(LineProps, prefix="major_tick") major_tick_in = Int major_tick_out = Int
class GuideRenderer(PlotObject): plot = Instance dimension = Int(0) location = String('min') bounds = String('auto') def __init__(self, **kwargs): super(GuideRenderer, self).__init__(**kwargs) if self.plot is not None: if self not in self.plot.renderers: self.plot.renderers.append(self) def vm_serialize(self): props = self.vm_props(withvalues=True) guide_props = {} for name in ("dimension", "location", "bounds"): if name in props: guide_props[name] = props.pop(name) del props["plot"] props.update({ "id": self._id, "plot": self.plot, "guidespec": guide_props }) return props @classmethod def load_json(cls, attrs, instance=None): """Loads all json into a instance of cls, EXCEPT any references which are handled in finalize """ inst = super(GuideRenderer, cls).load_json(attrs, instance=instance) if hasattr(inst, 'guidespec'): guidespec = inst.guidespec del inst.guidespec inst.update(**guidespec) return inst
class Base(HasProps): x = Int(12) y = String("hello")
class GridPlot(PlotObject): """ A 2D grid of plots """ children = List(List) border_space = Int(0)
def test_Int(self): prop = Int() self.assertTrue(prop.is_valid(None)) # TODO: self.assertFalse(prop.is_valid(False)) # TODO: self.assertFalse(prop.is_valid(True)) self.assertTrue(prop.is_valid(0)) self.assertTrue(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.assertFalse(prop.is_valid(Foo())) try: import numpy as np # TODO: self.assertFalse(prop.is_valid(np.bool8(False))) # TODO: self.assertFalse(prop.is_valid(np.bool8(True))) self.assertTrue(prop.is_valid(np.int8(0))) self.assertTrue(prop.is_valid(np.int8(1))) self.assertTrue(prop.is_valid(np.int16(0))) self.assertTrue(prop.is_valid(np.int16(1))) self.assertTrue(prop.is_valid(np.int32(0))) self.assertTrue(prop.is_valid(np.int32(1))) self.assertTrue(prop.is_valid(np.int64(0))) self.assertTrue(prop.is_valid(np.int64(1))) self.assertTrue(prop.is_valid(np.uint8(0))) self.assertTrue(prop.is_valid(np.uint8(1))) self.assertTrue(prop.is_valid(np.uint16(0))) self.assertTrue(prop.is_valid(np.uint16(1))) self.assertTrue(prop.is_valid(np.uint32(0))) self.assertTrue(prop.is_valid(np.uint32(1))) self.assertTrue(prop.is_valid(np.uint64(0))) self.assertTrue(prop.is_valid(np.uint64(1))) self.assertFalse(prop.is_valid(np.float16(0))) self.assertFalse(prop.is_valid(np.float16(1))) self.assertFalse(prop.is_valid(np.float32(0))) self.assertFalse(prop.is_valid(np.float32(1))) self.assertFalse(prop.is_valid(np.float64(0))) self.assertFalse(prop.is_valid(np.float64(1))) self.assertFalse(prop.is_valid(np.complex64(1.0+1.0j))) self.assertFalse(prop.is_valid(np.complex128(1.0+1.0j))) self.assertFalse(prop.is_valid(np.complex256(1.0+1.0j))) except ImportError: pass
class T(PlotObject): t = Int(0)
class Plot(PlotObject): data_sources = List title = String("Bokeh Plot") x_range = Instance(DataRange1d, has_ref=True) y_range = Instance(DataRange1d, has_ref=True) png = String('') title = String('') # 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 # # annotation = List height = Int(600) width = Int(600) background_fill = Color("white") border_fill = Color("white") canvas_width = Int(400) canvas_height = Int(400) outer_width = Int(400) outer_height = Int(400) min_border_top = Int(50) min_border_bottom = Int(50) min_border_left = Int(50) min_border_right = Int(50) min_border = Int(50) def script_inject(self): return script_inject(self._session, self._id, self.__view_model__) def script_inject_escaped(self): return script_inject(self._session, self._id, self.__view_model__) def vm_props(self, *args, **kw): # FIXME: We need to duplicate the height and width into canvas and # outer height/width. This is a quick fix for the gorpiness, but this # needs to be fixed more structurally on the JS side, and then this # should be revisited on the Python side. if "canvas_width" not in self._changed_vars: self.canvas_width = self.width if "outer_width" not in self._changed_vars: self.outer_width = self.width if "canvas_height" not in self._changed_vars: self.canvas_height = self.height if "outer_height" not in self._changed_vars: self.outer_height = self.height return super(Plot, self).vm_props(*args, **kw)
class IPythonRemoteData(PlotObject): host = String("localhost") port = Int(10020) varname = String() computed_columns = List() metadata = Dict() #hack... we're just using this field right now to trigger events selected = Int(0) data = Int(0) def setselect(self, select, transform): remotedata = self url = "http://%s:%s/array/%s/setselect" % ( remotedata.host, remotedata.port, remotedata.varname) data = transform data['selected'] = select requests.post(url, data=protocol.serialize_json(data)) self.selected = self.selected + 1 def search(self, search): remotedata = self url = "http://%s:%s/array/%s/search" % ( remotedata.host, remotedata.port, remotedata.varname) requests.post(url, data=search) self.selected = self.selected + 1 def select(self, select, transform): remotedata = self url = "http://%s:%s/array/%s/select" % ( remotedata.host, remotedata.port, remotedata.varname) data = transform data['selected'] = select requests.post(url, data=protocol.serialize_json(data)) self.selected = self.selected + 1 def deselect(self, deselect, transform): remotedata = self url = "http://%s:%s/array/%s/deselect" % ( remotedata.host, remotedata.port, remotedata.varname) data = transform data['selected'] = deselect requests.post(url, data=protocol.serialize_json(data)) self.selected = self.selected + 1 def get_data(self, transform): remotedata = self url = "http://%s:%s/array/%s" % (remotedata.host, remotedata.port, remotedata.varname) data = requests.get(url, data=protocol.serialize_json(transform)).json() self.metadata = data.pop('metadata', {}) return data def set_computed_columns(self, computed_columns): remotedata = self url = "http://%s:%s/array/%s/computed" % ( remotedata.host, remotedata.port, remotedata.varname) data = requests.get( url, data=protocol.serialize_json(computed_columns)).json() self.computed_columns = computed_columns self.data += 1 return data
class AnotherModelInTestPushDoc(PlotObject): bar = Int(1)
class RemoteDataSource(PlotObject): host = String("localhost") port = Int(10020) varname = String() computed_columns = List() metadata = Dict() #hack... we're just using this field right now to trigger events selected = Int(0) data = Int(0) # from IPython.kernel import KernelManager # kernel = KernelManager(connection_file="kernel-1.json") # kernel.load_connection_file() # client = kernel.client() # client.start_channels() # client.shell_channel.execute("x = 1", store_history=False) def _url(self, func=None): remotedata = self func = "/" + func if func is not None else "" url = "http://%s:%s/array/%s%s" % \ (remotedata.host, remotedata.port, remotedata.varname, func) return url def _is_ok(self, response): response.raise_for_status() def _trigger_events(self): self.selected = self.selected + 1 def setselect(self, select, transform): data = transform data['selected'] = select json = protocol.serialize_json(data) requests.post(self._url("setselect"), data=json) self._trigger_events() def search(self, search): requests.post(self._url("search"), data=search) self._trigger_events() def select(self, select, transform): data = transform data['selected'] = select json = protocol.serialize_json(data) requests.post(self._url("select"), data=json) self._trigger_events() def deselect(self, deselect, transform): data = transform data['selected'] = deselect requests.post(self._url("selected"), data=protocol.serialize_json(data)) self._trigger_events() def pivot(self, transform): json = protocol.serialize_json(transform) response = requests.post(self._url("pivot"), data=json) self._is_ok(response) data = response.json() self._trigger_events() return data def fields(self): json = protocol.serialize_json({}) response = requests.get(self._url("fields"), data=json) self._is_ok(response) data = response.json() self._trigger_events() return data def get_data(self, transform): json = protocol.serialize_json(transform) response = requests.get(self._url(), data=json) self._is_ok(response) data = response.json() self.metadata = data.pop('metadata', {}) return data def set_computed_columns(self, computed_columns): json = protocol.serialize_json(computed_columns) response = requests.get(self._url("computed"), data=json) self._is_ok(response) data = response.json() self.computed_columns = computed_columns self.data += 1 return data
class Foo(HasProps): x = Int(12) y = String("hello") z = Array(Int, np.array([1, 2, 3])) s = String(None)
class Foo(HasProps): x = Int(12) y = Enum("red", "blue", "green") z = String("blah")
class SomeModelInTestDocument(Model): foo = Int(2) child = Instance(Model)
class AnotherModelInTestDocument(Model): bar = Int(1)
class SomeModelInTestClientServer(PlotObject): foo = Int(2) child = Instance(PlotObject)
class GMapPlot(PlotObject): center_lat = Float center_lng = Float zoom_level = Int(12) data_sources = List title = String("Bokeh Plot") png = String('') title = String('') # 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) x_range = Instance(Range1d, has_ref=True) y_range = Instance(Range1d, has_ref=True) # TODO: How do we want to handle syncing of the different layers? # image = List # underlay = List # glyph = List # # annotation = List height = Int(800) width = Int(800) border_fill = Color("white") canvas_width = Int(800) canvas_height = Int(800) outer_width = Int(800) outer_height = Int(800) min_border_top = Int(50) min_border_bottom = Int(50) min_border_left = Int(50) min_border_right = Int(50) min_border = Int(50) def vm_serialize(self): # GlyphRenderers need to serialize their state a little differently, # because the internal glyph instance is turned into a glyphspec data = super(GMapPlot, self).vm_serialize() data.pop('center_lat', None) data.pop('center_lng', None) data.pop('zoom_level', None) data["map_options"] = { 'lat': self.center_lat, 'lng': self.center_lng, 'zoom': self.zoom_level } self._session.raw_js_snippets(self) return data @classmethod def load_json(cls, attrs, instance=None): """Loads all json into a instance of cls, EXCEPT any references which are handled in finalize """ inst = super(GMapPlot, cls).load_json(attrs, instance=instance) if hasattr(inst, 'map_options'): mo = inst.map_options del inst.map_options inst.center_lat = mo['lat'] inst.center_lng = mo['lng'] inst.zoom_level = mo['zoom'] return inst def get_raw_js(self): return '<script src="https://maps.googleapis.com/maps/api/js?sensor=false"></script>' def script_inject(self): return script_inject(self._session, self._id, self.__view_model__) def script_inject_escaped(self): return script_inject(self._session, self._id, self.__view_model__) def vm_props(self, *args, **kw): # FIXME: We need to duplicate the height and width into canvas and # outer height/width. This is a quick fix for the gorpiness, but this # needs to be fixed more structurally on the JS side, and then this # should be revisited on the Python side. if "canvas_width" not in self._changed_vars: self.canvas_width = self.width if "outer_width" not in self._changed_vars: self.outer_width = self.width if "canvas_height" not in self._changed_vars: self.canvas_height = self.height if "outer_height" not in self._changed_vars: self.outer_height = self.height return super(GMapPlot, self).vm_props(*args, **kw)
class Foo(HasProps): x = Int y = Int()
class SomeModelInTestFunction(Model): foo = Int(2) child = Instance(Model)
class T(self.pObjectClass): t = Int(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 AnotherModelInTestFunction(Model): bar = Int(1)
class SomeModelInTestPushDoc(PlotObject): foo = Int(2) child = Instance(PlotObject)