Example O1: Scale bar — OVITO Python Reference 3.15.3-dev-HEAD-b1e9512d documentation

# Example O1: Scale bar

Custom overlay that renders a scale bar with a configurable length into a viewport.

The implementation makes use of the `Canvas.project_length()` method to compute the screen-space length corresponding to a simulation-space distance, which is given by a configurable user parameter of the overlay class.

    from ovito.vis import ViewportOverlayInterface
    from ovito.data import DataCollection
    from traits.api import Range
    from ovito.traits import Color
    from ovito.qt_compat import QtGui

    class ScaleBarOverlay(ViewportOverlayInterface):

        # Adjustable user parameters:

        # World-space length of the scale bar:
        length = Range(value=4.0, low=0.0, label='Length (nm)')

        # Screen-space height of the scale bar:
        height = Range(value=0.05, low=0.0, high=0.2, label='Height')

        # Bar color:
        bar_color = Color(default=(0.0, 0.0, 0.0), label='Bar color')

        # Text color:
        text_color = Color(default=(1.0, 1.0, 1.0), label='Text color')

        def render(self, canvas: ViewportOverlayInterface.Canvas, data: DataCollection, **kwargs):

            # Compute the center coordinates of the simulation cell.
            center = data.cell @ (0.5, 0.5, 0.5, 1.0)

            # Compute length of bar in screen space - as a fraction of the canvas height.
            screen_length = canvas.project_length(center, self.length)

            # Convert from nanometers to simulation units of length (Angstroms) and
            # convert from vertical to horizontal canvas coordinates by multiplying with the h/w aspect ratio.
            screen_length *= 10 * canvas.logical_size[1] / canvas.logical_size[0]

            # Create a 1-by-1 pixel image for drawing the bar rectangle.
            image = QtGui.QImage(1, 1, canvas.preferred_qimage_format)
            image.fill(QtGui.QColor.fromRgbF(*self.bar_color))

            # Draw the bar rectangle.
            canvas.draw_image(image, pos=(0.01, 0.01), size=(screen_length, self.height), anchor="south west")

            # Draw the text label.
            canvas.draw_text(f"{self.length:.3} nm",
                             pos=(0.01 + 0.5*screen_length, 0.01 + 0.5*self.height),
                             font_size=self.height,
                             anchor="center",
                             color=self.text_color)