Visualization

Classes for plotting, drawing, and displaying images and video.

Figures

class mytk.figures.Figure(figure=None, figsize=None)[source]

Bases: Base

Wrapper around matplotlib Figure for embedding plots in tkinter.

is_environment_valid()[source]

Check that matplotlib is installed and importable.

create_widget(master)[source]

Create the matplotlib canvas and navigation toolbar.

property figure

The underlying matplotlib Figure.

property first_axis

The first axes of the figure, or None if unavailable.

property axes

All axes of the figure, or None if the figure is not set.

styles_pointmarker(linestyle='')[source]

Return a list of point-marker style dictionaries for plotting.

styles_points_linemarkers(linestyle='-')[source]

Return a list of point-and-line marker style dictionaries for plotting.

class mytk.figures.XYPlot(figsize)[source]

Bases: Figure

Simple XY line plot backed by matplotlib.

create_widget(master, **kwargs)[source]

Create the plot widget and draw the initial plot.

clear_plot()[source]

Clear all data and redraw the plot.

update_plot()[source]

Redraw the plot with the current data.

append(x, y)[source]

Append a data point to the plot.

class mytk.figures.Histogram(figsize)[source]

Bases: Figure

Histogram plot backed by matplotlib and numpy.

is_environment_valid()[source]

Check that matplotlib and numpy are installed and importable.

create_widget(master, **kwargs)[source]

Create the histogram widget and draw the initial plot.

clear_plot()[source]

Clear all histogram data and the axes.

update_plot()[source]

Redraw the histogram with the current data.

CanvasView

class mytk.canvasview.CanvasView(width=200, height=200, **kwargs)[source]

Bases: Base

Tkinter Canvas wrapper with coordinate system support.

property relative_basis

A dynamic basis that tracks the current canvas size.

create_widget(master, **kwargs)[source]

Create the underlying tkinter Canvas widget.

property is_disabled

Whether the canvas and its children are disabled.

on_resize(event)[source]

Handle canvas resize events and post a notification.

place(element, position=None)[source]

Place a CanvasElement on the canvas at the given position.

element(id)[source]

Return the CanvasElement with the given id, or None.

save_to_pdf(filepath, bbox=None, **kwargs)[source]

Export the canvas content to a PDF file via PostScript conversion.

class mytk.canvasview.CanvasElement(basis=None, **kwargs)[source]

Bases: object

Base class for drawable elements on a CanvasView.

itemconfigure(**kwargs)[source]

Configure options on the underlying canvas item.

property coords

The current coordinates of this element on the canvas.

property tags

The tags associated with this element on the canvas.

add_tag(tag)[source]

Add a tag to this element.

add_group_tag(tag)[source]

Add a group tag to this element.

move_by(dx, dy)[source]

Move this element by the given pixel offsets.

create(canvas, position)[source]

Create the element on the canvas. Override in subclasses.

class mytk.canvasview.Rectangle(size: (<class 'int'>, <class 'int'>), basis=None, position_is_center=True, **kwargs)[source]

Bases: CanvasElement

A rectangle element for drawing on a CanvasView.

create(canvas, position=None)[source]

Create the rectangle on the canvas and return its id.

class mytk.canvasview.Oval(size: (<class 'int'>, <class 'int'>), basis=None, position_is_center=True, **kwargs)[source]

Bases: CanvasElement

An oval element for drawing on a CanvasView.

create(canvas, position=None)[source]

Create the oval on the canvas and return its id.

class mytk.canvasview.Line(points=None, basis=None, **kwargs)[source]

Bases: CanvasElement

A line element connecting a series of points on a CanvasView.

create(canvas, position=None)[source]

Create the line on the canvas and return its id.

class mytk.canvasview.Arrow(start=None, end=None, **kwargs)[source]

Bases: Line

A line with an arrowhead at the end.

class mytk.canvasview.CanvasLabel(font_size=20, basis=None, **kwargs)[source]

Bases: CanvasElement

A text label element for drawing on a CanvasView.

create(canvas, position=None)[source]

Create the text label on the canvas and return its id.

class mytk.canvasview.Arc(radius, basis=None, **kwargs)[source]

Bases: CanvasElement

An arc element for drawing on a CanvasView.

create(canvas, position=None)[source]

Create the arc on the canvas and return its id.

Data Views

class mytk.dataviews.DataPoint(size: float, **kwargs)[source]

Bases: Oval

A circular data point drawn as an oval on a canvas.

class mytk.dataviews.Function(fct, xs, basis=None, **kwarg)[source]

Bases: CanvasElement

A canvas element that draws a mathematical function as a polyline.

create(canvas, position=None)[source]

Create the function polyline on the given canvas.

class mytk.dataviews.XYCoordinateSystemElement(size=None, normalized_size=None, axes_limits=((0, 1), (0, 1)), **kwargs)[source]

Bases: CanvasElement

An XY coordinate system with axes, ticks, and labels drawn on a canvas.

property basis

Compute the coordinate basis from axes limits and canvas size.

create(canvas, position=None)[source]

Create the full coordinate system on the given canvas.

create_x_axis(origin=None)[source]

Draw the positive and negative x-axis arrows on the canvas.

create_y_axis(origin=None)[source]

Draw the positive and negative y-axis on the canvas.

x_major_ticks()[source]

Return a list of nicely spaced major tick values for the x-axis.

y_major_ticks()[source]

Return a list of nicely spaced major tick values for the y-axis.

create_x_major_ticks(origin=None)[source]

Draw major tick marks along the x-axis.

create_x_major_ticks_labels(origin=None)[source]

Draw numeric labels below each x-axis major tick.

create_y_major_ticks(origin=None)[source]

Draw major tick marks along the y-axis.

create_y_major_ticks_labels(origin=None)[source]

Draw numeric labels beside each y-axis major tick.

place(element, position)[source]

Place an element at a data-coordinate position within this coordinate system.

mytk.dataviews.nice_number(x, round_to_nearest=True)[source]

Rounds or ceilings the number x to a ‘nice’ value, which is one of 1, 2, or 5 times a power of 10.

mytk.dataviews.get_nice_ticks(x_min, x_max, num_ticks=5)[source]

Generate ‘nice’ tick marks for the axis spanning from x_min to x_max.

Images

class mytk.images.Image(filepath=None, url=None, pil_image=None)[source]

Bases: Base

Widget for displaying a PIL image in a tkinter label.

property width

The width of the source PIL image in pixels.

property height

The height of the source PIL image in pixels.

property displayed_width

The width of the currently displayed image in pixels.

property displayed_height

The height of the currently displayed image in pixels.

is_environment_valid()[source]

Check that Pillow and its submodules are installed and importable.

read_pil_image(filepath=None, url=None)[source]

Load a PIL image from a local file path or a URL.

observed_property_changed(observed_object, observed_property_name, new_value, context)[source]

Handle changes to observed properties such as is_rescalable.

create_widget(master)[source]

Create a tkinter Label widget to display the image.

event_resized(event)[source]

Resize the image if is_rescalable, throttling to avoid infinite loops.

resize_image_to_fit_widget()[source]

Resize the PIL image to fit the parent grid cell while preserving aspect ratio.

update_display(image_to_display=None)[source]

Update the widget to show the given image, or the source image if None.

class mytk.images.ImageWithGrid(filepath=None, url=None, pil_image=None)[source]

Bases: Image

Image widget with an optional grid overlay drawn on top.

observed_property_changed(observed_object, observed_property_name, new_value, context)[source]

Handle changes to grid visibility or grid count.

update_display(image_to_display=None)[source]

Update the widget, adding a grid overlay if enabled.

image_with_grid_overlay(pil_image)[source]

Return a copy of the image with grid lines drawn on it.

class mytk.images.DynamicImage(width=200, height=200)[source]

Bases: CanvasView

Canvas-based image that can be redrawn dynamically.

draw_canvas()[source]

Draw the canvas contents. Override in subclasses.

VideoView

class mytk.videoview.VideoView(device=0, zoom_level=3, auto_start=True)[source]

Bases: Base

Live video capture and display widget backed by OpenCV.

is_environment_valid()[source]

Check that OpenCV and Pillow are available, installing them if needed.

signal_handler(sig, frame)[source]

Handle SIGINT to stop capture gracefully before propagating.

classmethod available_devices()[source]

Return a list of indices for available video capture devices.

create_widget(master)[source]

Create the label widget used to display video frames.

property is_running

Return True if video capture is currently active.

property startstop_button_label

Return the appropriate label for the start/stop button.

start_capturing()[source]

Open the video device and begin reading frames.

stop_capturing()[source]

Release the video device and cancel scheduled display updates.

start_streaming(filepath)[source]

Begin writing captured frames to a video file at the given path.

stop_streaming()[source]

Stop writing frames and release the video writer.

update_display(readonly_frame=None)[source]

Read the next frame, update the display widget, and schedule the next refresh.

update_histogram()[source]

Recompute and redraw the per-channel histogram from the current image.

create_behaviour_popups()[source]

Create a popup menu listing available camera devices.

create_behaviour_buttons()[source]

Create start/stop, save, and stream buttons with their callbacks.

bind_button_to_startstop_behaviour(button)[source]

Bind a button to toggle video capture on and off.

bind_button_to_save_behaviour(button)[source]

Bind a button to save the current frame as an image file.

bind_button_to_stream_behaviour(button)[source]

Bind a button to start streaming frames to a video file.

bind_popup_to_camera_selection_behaviour(popup)[source]

Bind a popup menu to switch the active camera device.

click_start_stop_button(event, button)[source]

Toggle capture and update the button label accordingly.

click_save_button(event, button)[source]

Prompt the user for a filename and save the current frame.

click_stream_button(event, button)[source]

Prompt for a filename and begin streaming frames to an AVI file.

camera_selection_changed(index)[source]

Switch capture to a different camera device by index.

prop_ids()[source]

Print all major OpenCV capture properties to stdout.

get_prop_id(prop_id)[source]

Return the value of an OpenCV capture property, or None if not capturing.

Common prop_id constants include CAP_PROP_FRAME_WIDTH, CAP_PROP_FRAME_HEIGHT, CAP_PROP_FPS, CAP_PROP_FOURCC, and CAP_PROP_CONVERT_RGB.

Indicators

class mytk.indicators.NumericIndicator(value_variable=None, value=0, format_string='{0}')[source]

Bases: Base

A label that displays a formatted numeric value from a tkinter variable.

create_widget(master)[source]

Create the label widget and display the initial value.

value_updated(var, index, mode)[source]

Callback triggered when the value variable changes.

update_text()[source]

Format the current value and update the label text.

class mytk.indicators.BooleanIndicator(diameter=15)[source]

Bases: CanvasView

A colored circle indicator that is green when True and red when False.

create_widget(master, **kwargs)[source]

Create the canvas widget and draw the initial indicator.

value_updated(var, index, mode)[source]

Callback triggered when the boolean variable changes.

draw_canvas()[source]

Draw the indicator circle with the appropriate color.

class mytk.indicators.Level(maximum=100, width=200, height=20)[source]

Bases: CanvasView

A horizontal bar indicator that fills proportionally to a value.

create_widget(master, **kwargs)[source]

Create the canvas widget and draw the initial level bar.

value_updated(var, index, mode)[source]

Clamp the value to the valid range and redraw the bar.

draw_canvas()[source]

Draw the level bar reflecting the current value.

View3D

Embedded 3D mesh viewers for myTk: one widget, two rendering backends.

View3D is an abstract widget that loads a GLB/GLTF/OBJ/PLY file with trimesh and shows it lit and coloured inside an ordinary myTk layout — drag to orbit, scroll to zoom. Rather than embed a fragile OpenGL widget, it renders off-screen and blits each frame into a tk.Canvas via Pillow, the same strategy VideoView uses for camera frames. It re-renders only on interaction.

Two concrete implementations share that machinery:

  • View3DModernGL — a hand-written moderngl renderer (its own shaders, matrices and buffers). Near-zero install footprint, and it uses its own GL bindings rather than PyOpenGL, so it works where pyrender’s context fails:

    pip install moderngl trimesh numpy Pillow
    
  • View3DPyrender — delegates the GL work (shaders, lighting, materials, framebuffer) to pyrender, so the widget keeps almost no GL of its own. Heavier dependencies:

    pip install pyrender trimesh numpy Pillow
    

Both backends map UV image textures onto the mesh (else per-vertex/material colour) and honour the object’s own alpha.

Everything that is not backend-specific — the Tk widget and mouse handling, the orbit camera, render scheduling, file loading and the blit — lives in the abstract base. A backend only has to know how to build its renderer, upload the geometry, and draw one frame into a Pillow image.

The base shows static geometry only (no baked animations): textured or per-vertex-coloured triangles with a two-sided Lambert-ish shade — enough to inspect exported scenes.

class mytk.view3d.View3D(*args, **kwargs)[source]

Bases: Base, ABC

Off-screen 3D mesh viewer blitted into a Tk label.

Load a mesh with load_file(), place it like any other myTk widget, then drag to orbit, scroll to zoom, and Shift+drag (or Shift+scroll) to pan. Renders only on interaction, so it is cheap when idle.

Calling View3D(...) does not build a base instance — it is a factory that picks a rendering backend and returns one of its concrete subclasses, preferring View3DModernGL (lighter deps, its own GL bindings, so it works where pyrender’s PyOpenGL context fails) and falling back to View3DPyrender only when moderngl is not importable. Both backends map UV image textures onto the mesh. Ask for a specific backend — e.g. pyrender for its nicer lighting — by instantiating that subclass directly.

The choice is made from which backend module imports. moderngl is preferred because pyrender can import yet still fail to create a GL context at render time (notably PyOpenGL on newer Pythons), which the import-probe cannot detect; construct View3DPyrender explicitly when you want it.

Parameters:
  • width (int) – Initial render width in pixels (the label adopts the size of the first rendered frame, then follows the layout).

  • height (int) – Initial render height in pixels.

  • background (str) – Tk colour shown behind the mesh while empty.

A mesh’s own per-vertex/material alpha is honoured, so translucent geometry is blended over the background.

is_environment_valid()[source]

Check that trimesh, numpy, Pillow and the backend module are present.

create_widget(master)[source]

Create the canvas that displays rendered frames and wire up the mouse.

A tk.Canvas (not a label) is used on purpose: a label sizes itself to its image, so each rendered frame would grow the widget by its chrome and re-trigger <Configure> — a runaway resize loop when the widget is content-sized. A canvas keeps the size the layout gives it regardless of what is drawn into it, so no feedback occurs.

load_file(path)[source]

Load a GLB/GLTF/OBJ/PLY file and display it.

All meshes in the file are handed to the backend, each keeping its own colour (vertex colours, else the material colour, else grey).

Raises whatever trimesh raises for an unreadable/unknown file; use load_file_or_warn() for the interactive (drop) case.

load_file_or_warn(path)[source]

Load a file, popping up a warning dialog if it is not a usable mesh.

Unlike load_file(), this never raises — it is meant for dropped or user-picked files, where an unrecognised format should be reported in the UI rather than crash the app. Returns True if the file loaded.

render()[source]

Drive one frame: size the renderer, upload if dirty, draw, blit.

class mytk.view3d.View3DModernGL(*args, **kwargs)[source]

Bases: View3D

View3D backed by a hand-written moderngl renderer.

Owns its own shader program, perspective/look-at matrices and vertex/index buffers, drawing into a standalone off-screen framebuffer.

set_geometry(interleaved, faces, center, radius)[source]

Display a single untextured mesh from raw buffers.

A convenience for vertex-coloured geometry; textured meshes arrive through _ingest() instead. The buffer is wrapped as one draw item with zero UVs and no texture.

Parameters:
  • interleaved – Nx10 float32 array of [position, normal, rgba] per vertex (the alpha channel carries the object’s transparency).

  • faces – Mx3 int32 array of triangle vertex indices.

  • center – 3-vector at the centre of the geometry’s bounding box.

  • radius – Half the bounding-box diagonal; frames the orbit camera.

class mytk.view3d.View3DPyrender(*args, **kwargs)[source]

Bases: View3D

View3D backed by pyrender.

pyrender owns the GL context, shaders, lighting, materials and framebuffer, so this backend keeps only a scene graph, an off-screen renderer, and the orbit-camera pose. A mesh’s own alpha is honoured via alphaMode='BLEND'.

JSON Canvas

Viewer for JSON Canvas 1.0 documents (https://jsoncanvas.org/spec/1.0/).

class mytk.jsoncanvas.JSONCanvas(width=800, height=600, **kwargs)[source]

Bases: CanvasView

Render a JSON Canvas 1.0 document on a Tk canvas.

Usage:

canvas = JSONCanvas(width=800, height=600) canvas.grid_into(parent, …) canvas.load(document_dict) # or: canvas.load_from_file(“example.canvas”)

load(data)[source]

Render the supplied JSON Canvas document (a dict).

load_from_file(filepath)[source]

Load and render a .canvas / .json file from disk.

create_widget(master, **kwargs)[source]

Create the underlying tkinter Canvas widget.