0

I want to use the onclick method to select a range of data on my matplotlib graph. But the thing is, I can't do that more than once and update the plot. I have some ideas to do this, one of them would be to make a list of plots where I jump to new indices after I appended the new picture ... but mostly I would like to be able to store the information from the click (event.xdata) two times to color the area under the graph in that section - but for starters it would already be an achievement to draw points wherever I click. But I kind of think there is a better solution than putting a plt.draw() in the onclick function?

import numpy as np
import matplotlib.pyplot as plt
from itertools import islice

class ReadFile():
    def __init__(self, filename):
        self._filename = filename

    def read_switching(self):
        return np.genfromtxt(self._filename, unpack=True, usecols={0}, delimiter=',')

def onclick(event):
    global ix, iy
    ix, iy = event.xdata, event.ydata
    global coords
    coords.append((ix, iy))
    print(coords)
    fig.canvas.mpl_disconnect(cid)
    return coords

coords = []    
filename = 'test.csv'
fig = plt.figure()
ax = fig.add_subplot(111)
values = (ReadFile(filename).read_switching())
steps = np.arange(1, len(values)+1)*2
graph_1, = ax.plot(steps, values, label='original curve')
cid = fig.canvas.mpl_connect('button_press_event', onclick)
print(coords)
graph_2, = ax.plot(coords, marker='o')
plt.show()

For example I have the following function (picture) and I want to click on two coordinates and color the area under the graph, probably with a plt.draw(). Example function

1 Answer 1

1

The issue is that you're disconnecting the on_click event inside of your callback. Instead, you'll want to update the xdata and ydata of your graph_2 object. Then force the figure to be redrawn

import numpy as np
import matplotlib.pyplot as plt


fig = plt.figure()
ax = fig.add_subplot(111)

# Plot some random data
values = np.random.rand(4,1);
graph_1, = ax.plot(values, label='original curve')
graph_2, = ax.plot([], marker='o')

# Keep track of x/y coordinates
xcoords = []
ycoords = []

def onclick(event):
    xcoords.append(event.xdata)
    ycoords.append(event.ydata)

    # Update plotted coordinates
    graph_2.set_xdata(xcoords)
    graph_2.set_ydata(ycoords)

    # Refresh the plot
    fig.canvas.draw()

cid = fig.canvas.mpl_connect('button_press_event', onclick)
plt.show()
Sign up to request clarification or add additional context in comments.

3 Comments

This was a great help, but I still don't understand how to get back the x and y coordinates from the function call? I want to store the clicks coordinates and use them in other functions. I know, I could use them in the same function.
@xtlc xcoords and ycoords are global variables so they should be accessible to all other functions already
Sorry, I explained myself poorly: When I click, I can use the coordinates in the function, but everything that happens outside the function stops. For example what if I would want to print the coordinates outside from def onclick(event)? This is why I wanted something "like a loop".

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.