|
| 1 | +#!/usr/bin/env python |
| 2 | +# -*- noplot -*- |
| 3 | + |
| 4 | +import matplotlib as mpl |
| 5 | +import numpy as np |
| 6 | +import Tkinter as tk |
| 7 | +import matplotlib.backends.tkagg as tkagg |
| 8 | +from matplotlib.backends.backend_agg import FigureCanvasAgg |
| 9 | + |
| 10 | +def draw_figure(canvas, figure, loc=[0,0]): |
| 11 | + """ Draw a matplotlib figure onto a Tk canvas |
| 12 | + |
| 13 | + loc: location of top-left corner of figure on canvas in pixels. |
| 14 | +
|
| 15 | + Inspired by matplotlib source: lib/matplotlib/backends/backend_tkagg.py |
| 16 | + """ |
| 17 | + figure_canvas_agg = FigureCanvasAgg(figure) |
| 18 | + figure_canvas_agg.draw() |
| 19 | + figure_x, figure_y, figure_w, figure_h = figure.bbox.bounds |
| 20 | + figure_w, figure_h = int(figure_w), int(figure_h) |
| 21 | + photo = tk.PhotoImage(master=canvas, width=figure_w, height=figure_h) |
| 22 | + |
| 23 | + # Position: convert from top-left anchor to center anchor |
| 24 | + canvas.create_image(loc[0] + figure_w/2, loc[1] + figure_h/2, image=photo) |
| 25 | + |
| 26 | + # Unfortunatly, there's no accessor for the pointer to the native renderer |
| 27 | + tkagg.blit(photo, figure_canvas_agg.get_renderer()._renderer, colormode=2) |
| 28 | + |
| 29 | + # Return a handle which contains a reference to the photo object |
| 30 | + # which must be kept live or else the picture disappears |
| 31 | + return photo |
| 32 | + |
| 33 | +# Create a canvas |
| 34 | +w, h = 300, 200 |
| 35 | +window = tk.Tk() |
| 36 | +window.title("A figure in a canvas") |
| 37 | +canvas = tk.Canvas(window, width=w, height=h) |
| 38 | +canvas.pack() |
| 39 | + |
| 40 | +# Generate some example data |
| 41 | +X = np.linspace(0, 2.0*3.14, 50) |
| 42 | +Y = np.sin(X) |
| 43 | + |
| 44 | +# Create the figure we desire to add to an existing canvas |
| 45 | +fig = mpl.figure.Figure(figsize=(2, 1)) |
| 46 | +ax = fig.add_axes([0,0,1,1]) |
| 47 | +ax.plot(X, Y) |
| 48 | + |
| 49 | +# Keep this handle alive, or else figure will disappear |
| 50 | +fig_x, fig_y = 100, 100 |
| 51 | +fig_photo = draw_figure(canvas, fig, loc=[fig_x, fig_y]) |
| 52 | +fig_w, fig_h = fig_photo.width(), fig_photo.height() |
| 53 | + |
| 54 | +# Add more elements to the canvas, potentially on top of the figure |
| 55 | +canvas.create_line(200, 50, fig_x + fig_w / 2, fig_y + fig_h / 2) |
| 56 | +canvas.create_text(200, 50, text="Zero-crossing", anchor="s") |
| 57 | + |
| 58 | +# Let Tk take over |
| 59 | +tk.mainloop() |
0 commit comments