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 create_scatter_plot(data=[], index_bounds=None, value_bounds=None, orientation="h", color="green", marker="square", marker_size=4, bgcolor="transparent", outline_color="black", border_visible=True, add_grid=False, add_axis=False, index_sort="none"): """ Creates a ScatterPlot from a single Nx2 data array or a tuple of two length-N 1-D arrays. The data must be sorted on the index if any reverse-mapping tools are to be used. Pre-existing "index" and "value" datasources can be passed in. """ index, value = _create_data_sources(data) if index_bounds is not None: index_range = DataRange1D(low=index_bounds[0], high=index_bounds[1]) else: index_range = DataRange1D() index_range.add(index) index_mapper = LinearMapper(range=index_range) if value_bounds is not None: value_range = DataRange1D(low=value_bounds[0], high=value_bounds[1]) else: value_range = DataRange1D() value_range.add(value) value_mapper = LinearMapper(range=value_range) plot = ScatterPlot(index=index, value=value, index_mapper=index_mapper, value_mapper=value_mapper, orientation=orientation, marker=marker, marker_size=marker_size, color=color, bgcolor=bgcolor, outline_color=outline_color, border_visible=border_visible,) if add_grid: add_default_grids(plot, orientation) if add_axis: add_default_axes(plot, orientation) return plot
def to_colormap(self, range=None): """ Returns a ColorMapper instance from this template. """ colormap = ColorMapper(self.segment_map, steps = self.steps) if range: colormap.range = range else: colormap.range = DataRange1D(low = self.range_low_setting, high = self.range_high_setting) return colormap
def create_bar_plot(data=[], index_bounds=None, value_bounds=None, orientation="h", color="red", bar_width=10.0, value_mapper_class=LinearMapper, line_color="black", fill_color="red", line_width=1, bgcolor="transparent", border_visible=False, antialias=True, add_grid=False, add_axis=False): index, value = _create_data_sources(data) if index_bounds is not None: index_range = DataRange1D(low=index_bounds[0], high=index_bounds[1]) else: index_range = DataRange1D() index_range.add(index) index_mapper = LinearMapper(range=index_range) if value_bounds is not None: value_range = DataRange1D(low=value_bounds[0], high=value_bounds[1]) else: value_range = DataRange1D() value_range.add(value) value_mapper = value_mapper_class(range=value_range) # Create the plot plot = BarPlot(index=index, value=value, value_mapper=value_mapper, index_mapper=index_mapper, orientation=orientation, line_color=line_color, fill_color=fill_color, line_width=line_width, bar_width=bar_width, antialias=antialias,) if add_grid: add_default_grids(plot, orientation) if add_axis: add_default_axes(plot, orientation) return plot
def create_line_plot(data=[], index_bounds=None, value_bounds=None, orientation="h", color="red", width=1.0, dash="solid", value_mapper_class=LinearMapper, bgcolor="transparent", border_visible=False, add_grid=False, add_axis=False, index_sort="none"): index, value = _create_data_sources(data, index_sort) if index_bounds is not None: index_range = DataRange1D(low=index_bounds[0], high=index_bounds[1]) else: index_range = DataRange1D() index_range.add(index) index_mapper = LinearMapper(range=index_range) if value_bounds is not None: value_range = DataRange1D(low=value_bounds[0], high=value_bounds[1]) else: value_range = DataRange1D() value_range.add(value) value_mapper = value_mapper_class(range=value_range) plot = LinePlot(index=index, value=value, index_mapper = index_mapper, value_mapper = value_mapper, orientation = orientation, color = color, bgcolor = bgcolor, line_width = width, line_style = dash, border_visible=border_visible) if add_grid: add_default_grids(plot, orientation) if add_axis: add_default_axes(plot, orientation) return plot
def contour_plot(self, data, type="line", name=None, poly_cmap=None, xbounds=None, ybounds=None, origin=None, hide_grids=True, **styles): """ Adds contour plots to this Plot object. Parameters ---------- data : string The name of the data array in self.plot_data, which must be floating point data. type : comma-delimited string of "line", "poly" The type of contour plot to add. If the value is "poly" and no colormap is provided via the *poly_cmap* argument, then a default colormap of 'Spectral' is used. name : string The name of the plot; if omitted, then a name is generated. poly_cmap : string The name of the color-map function to call (in chaco.default_colormaps) or an AbstractColormap instance to use for contour poly plots (ignored for contour line plots) xbounds, ybounds : string, tuple, or ndarray Bounds where this image resides. Bound may be: a) names of data in the plot data; b) tuples of (low, high) in data space, c) 1D arrays of values representing the pixel boundaries (must be 1 element larger than underlying data), or d) 2D arrays as obtained from a meshgrid operation origin : string Which corner the origin of this plot should occupy: "bottom left", "top left", "bottom right", "top right" hide_grids : bool, default True Whether or not to automatically hide the grid lines on the plot 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'. """ if name is None: name = self._make_new_plot_name() if origin is None: origin = self.default_origin value = self._get_or_create_datasource(data) if value.value_depth != 1: raise ValueError("Contour plots require 2D scalar field") if type == "line": cls = self.renderer_map["contour_line_plot"] kwargs = dict(**styles) # if colors is given as a factory func, use it to make a # concrete colormapper. Better way to do this? if "colors" in kwargs: cmap = kwargs["colors"] if isinstance(cmap, FunctionType): kwargs["colors"] = cmap(DataRange1D(value)) elif getattr(cmap, 'range', 'dummy') is None: cmap.range = DataRange1D(value) elif type == "poly": if poly_cmap is None: poly_cmap = Spectral(DataRange1D(value)) elif isinstance(poly_cmap, FunctionType): poly_cmap = poly_cmap(DataRange1D(value)) elif getattr(poly_cmap, 'range', 'dummy') is None: poly_cmap.range = DataRange1D(value) cls = self.renderer_map["contour_poly_plot"] kwargs = dict(color_mapper=poly_cmap, **styles) else: raise ValueError("Unhandled contour plot type: " + type) return self._create_2d_plot(cls, name, origin, xbounds, ybounds, value, hide_grids, **kwargs)
def img_plot(self, data, name=None, colormap=None, xbounds=None, ybounds=None, origin=None, hide_grids=True, **styles): """ Adds image plots to this Plot object. If *data* has shape (N, M, 3) or (N, M, 4), then it is treated as RGB or RGBA (respectively) and *colormap* is ignored. If *data* is an array of floating-point data, then a colormap can be provided via the *colormap* argument, or the default of 'Spectral' will be used. *Data* should be in row-major order, so that xbounds corresponds to *data*'s second axis, and ybounds corresponds to the first axis. Parameters ---------- data : string The name of the data array in self.plot_data name : string The name of the plot; if omitted, then a name is generated. xbounds, ybounds : string, tuple, or ndarray Bounds where this image resides. Bound may be: a) names of data in the plot data; b) tuples of (low, high) in data space, c) 1D arrays of values representing the pixel boundaries (must be 1 element larger than underlying data), or d) 2D arrays as obtained from a meshgrid operation origin : string Which corner the origin of this plot should occupy: "bottom left", "top left", "bottom right", "top right" hide_grids : bool, default True Whether or not to automatically hide the grid lines on the plot 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'. """ if name is None: name = self._make_new_plot_name() if origin is None: origin = self.default_origin value = self._get_or_create_datasource(data) array_data = value.get_data() if len(array_data.shape) == 3: if array_data.shape[2] not in (3,4): raise ValueError("Image plots require color depth of 3 or 4.") cls = self.renderer_map["img_plot"] kwargs = dict(**styles) else: if colormap is None: if self.color_mapper is None: colormap = Spectral(DataRange1D(value)) else: colormap = self.color_mapper elif isinstance(colormap, AbstractColormap): if colormap.range is None: colormap.range = DataRange1D(value) else: colormap = colormap(DataRange1D(value)) self.color_mapper = colormap cls = self.renderer_map["cmap_img_plot"] kwargs = dict(value_mapper=colormap, **styles) return self._create_2d_plot(cls, name, origin, xbounds, ybounds, value, hide_grids, **kwargs)
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]