Пример #1
0
    def _update_text(self):
        vb = self.plot_item.getViewBox()
        data_coords = vb.mapSceneToView(self.last_hover_event.scenePos())

        # TODO: Draw text directly to graphics scene rather than going through
        # pyqtgraph for performance - don't need any of the fancy interaction
        # or layouting features that come with being a plot item.

        def make_text():
            text = pyqtgraph.TextItem()
            # Don't take text item into account for auto-scaling; otherwise
            # there will be positive feedback if the cursor is towards the
            # bottom right of the screen.
            text.setFlag(text.ItemHasNoContents)
            self.plot_item.addItem(text)
            return text

        if not self.x_text:
            self.x_text = make_text()

        if not self.y_text:
            self.y_text = make_text()

        x_range, y_range = vb.state["viewRange"]
        x_range = np.array(x_range) * self.x_data_to_display_scale
        y_range = np.array(y_range) * self.y_data_to_display_scale

        def num_digits_after_point(r):
            # We want to be able to resolve at least 1000 points in the displayed
            # range.
            smallest_digit = np.floor(np.log10(r[1] - r[0])) - 3
            return int(-smallest_digit) if smallest_digit < 0 else 0

        self.x_text.setText("{0:.{width}f}{1}".format(
            data_coords.x() * self.x_data_to_display_scale,
            self.x_unit_suffix,
            width=num_digits_after_point(x_range)))
        self.x_text.setPos(data_coords)

        self.last_x = data_coords.x()

        y_text_pos = QtCore.QPointF(self.last_hover_event.scenePos())
        y_text_pos.setY(self.last_hover_event.scenePos().y() + 10)
        self.y_text.setText("{0:.{width}f}{1}".format(
            data_coords.y() * self.y_data_to_display_scale,
            self.y_unit_suffix,
            width=num_digits_after_point(y_range)))
        self.y_text.setPos(vb.mapSceneToView(y_text_pos))

        self.last_y = data_coords.y()
Пример #2
0
    def _update(self):
        x_data = self.points["axis_0"]
        y_data = self.points["axis_1"]
        z_data = self.points["channel_" + self.active_channel_name]

        # Figure out how many complete data points we have, and whether there are any
        # not already shown.

        num_to_show = min(len(x_data), len(y_data), len(z_data))

        if num_to_show == self.num_shown:
            return
        num_skip = self.num_shown
        self.num_shown = num_to_show

        # Update z autorange if active.
        if True:  # TODO: Provide manual override.
            data_min = np.min(z_data[num_skip:num_to_show])
            data_max = np.max(z_data[num_skip:num_to_show])
            if self.current_z_limits is None:
                self.current_z_limits = (data_min, data_max)
                num_skip = 0
            else:
                z_limits = (min(self.current_z_limits[0], data_min),
                            max(self.current_z_limits[1], data_max))
                if z_limits != self.current_z_limits:
                    self.current_z_limits = z_limits
                    num_skip = 0

        # Determine range of x/y values to show and prepare image buffer accordingly if
        # it changed.
        x_range = _calc_range_spec(self.x_min, self.x_max, self.x_increment,
                                   x_data)
        y_range = _calc_range_spec(self.y_min, self.y_max, self.y_increment,
                                   y_data)

        if x_range != self.x_range or y_range != self.y_range:
            self.x_range = x_range
            self.y_range = y_range

            # TODO: Splat old data for progressively less blurry look on refining scans?
            self.image_data = np.full((_num_points_in_range(x_range),
                                       _num_points_in_range(y_range), 4),
                                      0,
                                      dtype="ubyte")

            self.image_rect = QtCore.QRectF(
                QtCore.QPointF(x_range[0] - x_range[2] / 2,
                               y_range[0] - y_range[2] / 2),
                QtCore.QPointF(x_range[1] + x_range[2] / 2,
                               y_range[1] + y_range[2] / 2))

            num_skip = 0

        x_inds = _coords_to_indices(x_data[num_skip:num_to_show], self.x_range)
        y_inds = _coords_to_indices(y_data[num_skip:num_to_show], self.y_range)

        z_min, z_max = self.current_z_limits
        z_scaled = (z_data[num_skip:num_to_show] - z_min) / (z_max - z_min)

        cmap = colormaps.plasma
        if self._get_display_hints().get("coordinate_type", "") == "cyclic":
            cmap = colormaps.kovesi_c8
        self.image_data[x_inds, y_inds, :] = cmap.map(z_scaled)

        self.image_item.setImage(self.image_data, autoLevels=False)
        if num_skip == 0:
            # Image size has changed, set plot item size accordingly.
            self.image_item.setRect(self.image_rect)