0

I have gotten this to run on my machine, and it gave me an idea: instead of printing a string, can I show a new graph, based on the point's meta data?

To give an idea about my data, I have a SQL table with experiment names and results, and then I have another table with the entire procession of the experiment. It is easy to use matplotlib to graph either. I would like to create something interactive where I can plot the end results of the experiment (some kind of scatterplot), allowing the user to drill down deeper and view a graph of the entire experiment for the point clicked.

It seems like I should be able to modify the on_pick function to do plotting, as the following code shows.

import matplotlib.pyplot as plt

class custom_objects_to_plot:
    def __init__(self, x, y, name):
        self.x = x
        self.y = y
        self.name = name

a = custom_objects_to_plot(10, 20, "a")
b = custom_objects_to_plot(30, 5, "b")
c = custom_objects_to_plot(40, 30, "c")
d = custom_objects_to_plot(120, 10, "d")

def on_pick(event):
    plt.scatter([1,2,3,4], [5,6,7,8]) # For the real function, run a SQL query to
                                      # get the data needed to do the plot of interest
    plt.title(event)
    plt.show()

fig, ax = plt.subplots()
for obj in [a, b, c, d]:
    artist = ax.plot(obj.x, obj.y, 'ro', picker=5)[0]
    artist.obj = obj

fig.canvas.callbacks.connect('pick_event', on_pick)

plt.show()

When I run this, I get an error: QCoreApplication::exec: The event loop is already running.

Can matplotlib perform what I want to do?

(Eventually, the goal is to put this interactive graph in a panel browser window, but I am content right now just to run matplotlib from the command line.)

Dave
  • 314
  • 2
  • 13

2 Answers2

2

I figured out how to get a new figure to plot. All it requires are unique names in on_pick, not just plt, for the figure and axes.

def on_pick(event):
    my_fig, my_ax = plt.subplots() # New plot with unique name
    my_ax.scatter([1, 2, 3, 4], [5, 6, 7, 8]) # Make the scatterplot
    my_fig.show() # Show the plot
Dave
  • 314
  • 2
  • 13
1

You're doing everything almost fine, except that you don't need to create a new scatter, but rather update the old one. That's what your error is about. plt.show()'s loop is already running, and inside your callback, you're trying to launch it once more. Your callback should be like:

def on_pick(event):
    plt.clf()  # It will clear previous scatter from figure
    plt.scatter([1, 2, 3, 4], [5, 6, 7, 8])
    plt.draw()  # It will tell pyplot to redraw

This would result into: Result

Answer is provided, looking at this question

  • If another SO question / answer, answer the new question, then the new question should be flagged as a duplicate. – Trenton McKinney Oct 14 '21 at 17:07
  • +1 this is cool, but I think I do want to create a new plot, which I'm pretty sure I figured out how to do by calling a new `fix, ax` within the `on_pick` function. I might post a self-answer in the next few hours or days. – Dave Oct 14 '21 at 19:41