def create_polar_plot(data, orientation='h', color='black', width=1.0, dash="solid", grid="dot", value_mapper_class=PolarMapper): if (type(data) != ndarray) and (len(data) == 2): data = transpose(array(data)) r_data, t_data = transpose(data) index_data= r_data*cos(t_data) value_data= r_data*sin(t_data) index = ArrayDataSource(index_data, sort_order='ascending') # Typically the value data is unsorted value = ArrayDataSource(value_data) index_range = DataRange1D() index_range.add(index) index_mapper = PolarMapper(range=index_range) value_range = DataRange1D() value_range.add(value) value_mapper = value_mapper_class(range=value_range) plot = PolarLineRenderer(index=index, value=value, index_mapper = index_mapper, value_mapper = value_mapper, orientation = orientation, color = color, line_width = width, line_style = dash, grid_style = grid) return plot
def _get_or_create_datasource(self, name): """ Returns the data source associated with the given name, or creates it if it doesn't exist. """ if name not in self.datasources: data = self.data.get_data(name) if type(data) in (list, tuple): data = array(data) if isinstance(data, ndarray): if len(data.shape) == 1: ds = ArrayDataSource(data, sort_order="none") ds.metadata['name'] = name elif len(data.shape) == 2: ds = ImageData(data=data, value_depth=1) elif len(data.shape) == 3: if data.shape[2] in (3,4): ds = ImageData(data=data, value_depth=int(data.shape[2])) else: raise ValueError("Unhandled array shape in creating new plot: " \ + str(data.shape)) elif isinstance(data, AbstractDataSource): ds = data else: raise ValueError("Couldn't create datasource for data of type " + \ str(type(data))) self.datasources[name] = ds return self.datasources[name]
def _get_or_create_datasource(self, name): """ Returns the data source associated with the given name, or creates it if it doesn't exist. """ if name not in self.datasources: data = self.data.get_data(name) if type(data) in (list, tuple): data = array(data) if isinstance(data, ndarray): if len(data.shape) == 1: ds = ArrayDataSource(data, sort_order="none") ds.metadata['name'] = name elif len(data.shape) == 2: ds = ImageData(data=data, value_depth=1) elif len(data.shape) == 3: if data.shape[2] in (3, 4): ds = ImageData(data=data, value_depth=int(data.shape[2])) else: raise ValueError("Unhandled array shape in creating new plot: " \ + str(data.shape)) elif isinstance(data, AbstractDataSource): ds = data else: raise ValueError("Couldn't create datasource for data of type " + \ str(type(data))) self.datasources[name] = ds return self.datasources[name]
def get_data(self): """get_data() -> (xdata, ydata) Implements AbstractDataSource. Because this class uses structured (gridded) data, this method returns the pair of data axes, instead of, for example, a full mesh-grid. This behavious differs from other data sources. """ if self._xdata is not None: xdata = self._xdata else: xdata = ArrayDataSource(array([])) if self._ydata is not None: ydata = self._ydata else: ydata = ArrayDataSource(array([])) return xdata, ydata
def _create_data_sources(data, index_sort="none"): """ Returns datasources for index and value based on the inputs. Assumes that the index data is unsorted unless otherwise specified. """ if (type(data) == ndarray) or (len(data) == 2): index, value = data if type(index) in (list, tuple, ndarray): index = ArrayDataSource(array(index), sort_order=index_sort) elif not isinstance(index, AbstractDataSource): raise RuntimeError, "Need an array or list of values or a DataSource, got %s instead." % type(index) if type(value) in (list, tuple, ndarray): value = ArrayDataSource(array(value)) elif not isinstance(value, AbstractDataSource): raise RuntimeError, "Need an array or list of values or a DataSource, got %s instead." % type(index) return index, value else: raise RuntimeError, "Unable to create datasources."
def plot(self, data, type="line", name=None, index_scale="linear", value_scale="linear", origin=None, **styles): """ Adds a new sub-plot using the given data and plot style. Parameters ---------- data : string, tuple(string), list(string) The data to be plotted. The type of plot and the number of arguments determines how the arguments are interpreted: one item: (line/scatter) The data is treated as the value and self.default_index is used as the index. If **default_index** does not exist, one is created from arange(len(*data*)) two or more items: (line/scatter) Interpreted as (index, value1, value2, ...). Each index,value pair forms a new plot of the type specified. two items: (cmap_scatter) Interpreted as (value, color_values). Uses **default_index**. three or more items: (cmap_scatter) Interpreted as (index, val1, color_val1, val2, color_val2, ...) type : comma-delimited string of "line", "scatter", "cmap_scatter" The types of plots to add. name : string The name of the plot. If None, then a default one is created (usually "plotNNN"). index_scale : string The type of scale to use for the index axis. If not "linear", then a log scale is used. value_scale : string The type of scale to use for the value axis. If not "linear", then a log scale is used. origin : string Which corner the origin of this plot should occupy: "bottom left", "top left", "bottom right", "top right" styles : series of keyword arguments attributes and values that apply to one or more of the plot types requested, e.g.,'line_color' or 'line_width'. Examples -------- :: plot("my_data", type="line", name="myplot", color=lightblue) plot(("x-data", "y-data"), type="scatter") plot(("x", "y1", "y2", "y3")) Returns ------- [renderers] -> list of renderers created in response to this call to plot() """ if len(data) == 0: return if isinstance(data, basestring): data = (data,) self.index_scale = index_scale self.value_scale = value_scale # TODO: support lists of plot types plot_type = type if name is None: name = self._make_new_plot_name() if origin is None: origin = self.default_origin if plot_type in ("line", "scatter", "polygon", "bar", "filled_line"): # Tie data to the index range if len(data) == 1: if self.default_index is None: # Create the default index based on the length of the first # data series value = self._get_or_create_datasource(data[0]) self.default_index = ArrayDataSource(arange(len(value.get_data())), sort_order="none") self.index_range.add(self.default_index) index = self.default_index else: index = self._get_or_create_datasource(data[0]) if self.default_index is None: self.default_index = index self.index_range.add(index) data = data[1:] # Tie data to the value_range and create the renderer for each data new_plots = [] simple_plot_types = ("line", "scatter") for value_name in data: value = self._get_or_create_datasource(value_name) self.value_range.add(value) if plot_type in simple_plot_types: cls = self.renderer_map[plot_type] # handle auto-coloring request if styles.get("color") == "auto": self._auto_color_idx = \ (self._auto_color_idx + 1) % len(self.auto_colors) styles["color"] = self.auto_colors[self._auto_color_idx] elif plot_type in ("polygon", "filled_line"): cls = self.renderer_map[plot_type] # handle auto-coloring request if styles.get("edge_color") == "auto": self._auto_edge_color_idx = \ (self._auto_edge_color_idx + 1) % len(self.auto_colors) styles["edge_color"] = self.auto_colors[self._auto_edge_color_idx] if styles.get("face_color") == "auto": self._auto_face_color_idx = \ (self._auto_face_color_idx + 1) % len(self.auto_colors) styles["face_color"] = self.auto_colors[self._auto_face_color_idx] elif plot_type == 'bar': cls = self.renderer_map[plot_type] # handle auto-coloring request if styles.get("color") == "auto": self._auto_color_idx = \ (self._auto_color_idx + 1) % len(self.auto_colors) styles["fill_color"] = self.auto_colors[self._auto_color_idx] else: raise ValueError("Unhandled plot type: " + plot_type) if self.index_scale == "linear": imap = LinearMapper(range=self.index_range, stretch_data=self.index_mapper.stretch_data) else: imap = LogMapper(range=self.index_range, stretch_data=self.index_mapper.stretch_data) if self.value_scale == "linear": vmap = LinearMapper(range=self.value_range, stretch_data=self.value_mapper.stretch_data) else: vmap = LogMapper(range=self.value_range, stretch_data=self.value_mapper.stretch_data) plot = cls(index=index, value=value, index_mapper=imap, value_mapper=vmap, orientation=self.orientation, origin = origin, **styles) self.add(plot) new_plots.append(plot) if plot_type == 'bar': # For bar plots, compute the ranges from the data to make the # plot look clean. def custom_index_func(data_low, data_high, margin, tight_bounds): """ Compute custom bounds of the plot along index (in data space). """ bar_width = styles.get('bar_width', cls().bar_width) plot_low = data_low - bar_width plot_high = data_high + bar_width return plot_low, plot_high if self.index_range.bounds_func is None: self.index_range.bounds_func = custom_index_func def custom_value_func(data_low, data_high, margin, tight_bounds): """ Compute custom bounds of the plot along value (in data space). """ plot_low = data_low - (data_high-data_low)*0.1 plot_high = data_high + (data_high-data_low)*0.1 return plot_low, plot_high if self.value_range.bounds_func is None: self.value_range.bounds_func = custom_value_func self.index_range.tight_bounds = False self.value_range.tight_bounds = False self.index_range.refresh() self.value_range.refresh() self.plots[name] = new_plots elif plot_type == "cmap_scatter": if len(data) != 3: raise ValueError("Colormapped scatter plots require (index, value, color) data") else: index = self._get_or_create_datasource(data[0]) if self.default_index is None: self.default_index = index self.index_range.add(index) value = self._get_or_create_datasource(data[1]) self.value_range.add(value) color = self._get_or_create_datasource(data[2]) if not styles.has_key("color_mapper"): raise ValueError("Scalar 2D data requires a color_mapper.") colormap = styles.pop("color_mapper", None) if self.color_mapper is not None and self.color_mapper.range is not None: color_range = self.color_mapper.range else: color_range = DataRange1D() if isinstance(colormap, AbstractColormap): self.color_mapper = colormap if colormap.range is None: color_range.add(color) colormap.range = color_range elif callable(colormap): color_range.add(color) self.color_mapper = colormap(color_range) else: raise ValueError("Unexpected colormap %r in plot()." % colormap) if self.index_scale == "linear": imap = LinearMapper(range=self.index_range, stretch_data=self.index_mapper.stretch_data) else: imap = LogMapper(range=self.index_range, stretch_data=self.index_mapper.stretch_data) if self.value_scale == "linear": vmap = LinearMapper(range=self.value_range, stretch_data=self.value_mapper.stretch_data) else: vmap = LogMapper(range=self.value_range, stretch_data=self.value_mapper.stretch_data) cls = self.renderer_map["cmap_scatter"] plot = cls(index=index, index_mapper=imap, value=value, value_mapper=vmap, color_data=color, color_mapper=self.color_mapper, orientation=self.orientation, origin=origin, **styles) self.add(plot) self.plots[name] = [plot] else: raise ValueError("Unknown plot type: " + plot_type) return self.plots[name]
def _get__ydata(self): return ArrayDataSource(self._data[:, 1])
def _get__xdata(self): return ArrayDataSource(self._data[:, 0])
def recalculate(self): if self.func is not None and self.data_range is not None: newarray = self.func(self.data_range.low, self.data_range.high) ArrayDataSource.set_data(self, newarray) else: self._data = array([], dtype=float)