Fixed position of any Scatter child widget in Kivy

Just in case you were wondering how one could go about having any child widget of a Kivy Scatter widget that would stick in a single window-relative position whilst the scatter itself was being translated and rotated, I thought I’d post this solution.

With a scatter, one can very easily implement a canvas-like object that can be rotated, translated and zoomed, whilst all of the widgets it contains are transformed along with it. This is usually great, unless you’d like, for some or other reason, to display a widget at a fixed position, for example any kind of overlay, such as a label.

The short answer is that this can be done by using a MatrixInstruction that is executed before that widget is drawn (in the canvas.before context) and that effectively reverses the parent Scatter’s transformation.

The slightly more involved answer is the minimal working example below. First we have the Python part of the ScatterOverlayApp. This only defines the MyScatter class which we’ll flesh out in the KV file, and the main app class which instantiates the top-level widget, in our case MyScatter:

from import App
from kivy.uix.scatter import Scatter

class MyScatter(Scatter):

class ScatterOverlayApp(App):
    def build(self):
        return MyScatter()

if __name__ == '__main__':

In the KV Language part of this example, the <MyScatter> rule defines two buttons, and then the Label which we shall configure to be the fixed position overlay. The Label stores the current matrix, and then applies the inverse transformation matrix of its parent, in other words that of the MyScatter.

This will result in the widget drawing in the space of MyScatter‘s parent, in our case the window. So when we specify the label to be in the middle of the root widget, it will actually be drawn right in the middle of the window. Even when we rotate and scale MyScatter (see screenshot below), the label will remain exactly where we put it.

        text: "Click me"
        pos: 100, 100

        text: "Don't click me"
        pos: 150, 200

        pos: root.width / 2.0, root.height / 2.0
        text: "I am an overlay label!"
        font_size: 32

            # store current matrix
                # reverse MyScatter's transformation matrix
                matrix: self.parent.transform_inv

            # restore matrix so that other widgets draw normally

Here’s a screenshot showing the situation after the containing MyScatter widget has been rotated, translated and zoomed. Both the buttons it contains have also been transformed, but the label is exactly where we placed it initially.


One thought on “Fixed position of any Scatter child widget in Kivy”

  1. Hi
    Sorry for my poor english
    I work on my iMac with your example : Fixed position of any Scatter child widget in Kivy

    I don’t understand how to use the mouse (left click) to generate red dot and to remove this red dot
    Can you help me

Leave a Reply

Your email address will not be published. Required fields are marked *