Reputation: 135
I need to draw something using the turtle module on the same canvas on which a graph would be plotted.
I've thought about using matplotlib to make a graph, but I need to later draw something with turtle on that graph. I could draw both the graph and the other things with turtle, but that is much more complicated.
Can anyone think of a better way?
Upvotes: 1
Views: 988
Reputation: 41872
Since you asked it, this question as been in the back of my mind. I've looked into various approaches involving stacked invisible canvases but no luck.
I finally decided to try plotting behind the scenes, save an image of that plot to a memory file, and load that image into a turtle background. It gets complicated a bit by introducing tkinter for FigureCanvasTkAgg
which then demands a tkinter-embeded turtle. But it works.
The code below plots a sine wave with matplotlib and then uses turtle to scribble a graffiti Hilbert curve over it. Just because I can:
import tkinter as tk
from io import BytesIO
from turtle import TurtleScreen, RawTurtle
from PIL import Image, ImageTk
import numpy as np
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
root = tk.Tk()
# Plot graph
figure = Figure(figsize=(5, 5))
subplot = figure.add_subplot(111)
x = np.arange(0, 3 * np.pi, 0.1)
y = np.sin(x)
subplot.plot(x, y)
# Make memory image of graph
invisible_figure_canvas = FigureCanvasTkAgg(figure, root)
buffer = BytesIO()
figure.savefig(buffer, format="png")
buffer.seek(0)
# Open memory as tkinter image
image = Image.open(buffer)
photoImage = ImageTk.PhotoImage(image)
buffer.close()
# Now do our turtle drawing embedded in tkinter
canvas = tk.Canvas(root, width=500, height=500)
canvas.pack()
screen = TurtleScreen(canvas)
screen._setbgpic(screen._bgpic, photoImage) # bypass restrictions (protected access)
turtle = RawTurtle(screen, shape='turtle')
turtle.shapesize(0.5)
def hilbertCurve(n, angle):
if n <= 0:
return
turtle.left(angle)
hilbertCurve(n - 1, -angle)
turtle.forward(10)
turtle.right(angle)
hilbertCurve(n - 1, angle)
turtle.forward(10)
hilbertCurve(n - 1, angle)
turtle.right(angle)
turtle.forward(10)
hilbertCurve(n - 1, -angle)
turtle.left(angle)
hilbertCurve(4, 90)
screen.mainloop()
Upvotes: 1