Bugbeeb
Bugbeeb

Reputation: 2161

How to use Line Collection with pyplot

When you run the code the error should be pretty obvious, just click your mouse in the black space and move it around. I'm not sure how the line segments are being created, I pulled it from the library and its kind of confusing. How can I get the line segments to plot along my scatter plot? When I looks at the segments array being generated I believe it’s creating pairs of x,x and y,y instead of x,y and x,y

import tkinter as tk
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.collections import LineCollection
from matplotlib.colors import ListedColormap
import numpy as np
import random

class Mouse_Game:
    '''Creates a matplotlib canvas object that plot mouse coordinates when animated.'''
    def __init__(self, root, width=400, height=400):
        self.frame = tk.Frame(master=root)
        self.status = False
        self.fig = plt.Figure(dpi=100, facecolor='black')
        self.ax = self.fig.add_axes([0,0,1,1], fc='black')
        self.width = width
        self.height = height
        self.ax.axis('off')

        #set up the canvas object and bind commands
        self.canvas = FigureCanvasTkAgg(self.fig, master=self.frame, resize_callback=self.configure)  # A tk.DrawingArea.
        self.canvas.draw()
        self.canvas.get_tk_widget().pack(side='top', fill='both', expand=True)
        self.fig.canvas.mpl_connect('button_press_event', self.animate)
        self.fig.canvas.mpl_connect('motion_notify_event', self.motion) 

    def animate(self, event):
        #Check if currently running
        if not self.status:
            self.status = True
            self.capture = np.array([(event.xdata, event.ydata)]*40)
        else:
            self.status = False

        #plot a line that follows the mouse around
        while self.status:
            self.ax.clear()
            self.ax.set_xlim(0, self.width)
            self.ax.set_ylim(0, self.height)
            x = self.capture[:,0]
            y = self.capture[:,1]
            ############################################################
            points = self.capture.T.reshape(-1, 1, 2)
            segments = np.concatenate([points[:-1], points[1:]], axis=1)
            ###########################################################
            lc = LineCollection(segments, cmap='magma')
            lc.set_array(x)
            lc.set_linewidth(2)
            self.ax.add_collection(lc)
            self.ax.scatter(x, y, marker='o')
            self.fig.canvas.draw()
            self.fig.canvas.flush_events()

    def motion(self, event):
        if self.status:
            #Append mouse coordinates to array when the mouse moves
            self.capture = self.capture[1:40]
            self.capture = np.append(self.capture, [(event.xdata, event.ydata)], axis=0)

    def configure(self, event):
        #Used to adjust coordinate setting when the screen size changes
        self.width, self.height = self.canvas.get_width_height()

def _quit():
    #destroy window
    root.quit()
    root.destroy()

root = tk.Tk()  
root.wm_title("Mouse Plot")
MG = Mouse_Game(root=root)
MG.frame.pack(expand=True, fill='both')
button = tk.Button(root, text="Quit", command=_quit)
button.pack(side='bottom', pady=10)

tk.mainloop()

Upvotes: 0

Views: 1111

Answers (1)

ImportanceOfBeingErnest
ImportanceOfBeingErnest

Reputation: 339775

I'm not sure why you transpose the array. If you leave the transposition out, it'll work just fine

points = self.capture.reshape(-1, 1, 2)

Upvotes: 1

Related Questions