Beispiel #1
0
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
Beispiel #2
0
    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]
Beispiel #3
0
    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]
Beispiel #4
0
    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
Beispiel #5
0
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."
Beispiel #6
0
    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]
Beispiel #7
0
 def _get__ydata(self):
     return ArrayDataSource(self._data[:, 1])
Beispiel #8
0
 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)
Beispiel #10
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)