sh0nk / matplotlib4j

Matplotlib for java: A simple graph plot library for java, scala and kotlin with powerful python matplotlib
MIT License
227 stars 37 forks source link

Threading model? modeless possible? #30

Open tobidelbruck opened 3 years ago

tobidelbruck commented 3 years ago

This package is really handy. I have a question, what is the threading model? My main Swing GUI seems to halt as long as the plot is displayed; is it possible to display a plot and update it while my code is running? I tried to put the call to plt.show() in a separate thread but it didn't seem to help. My code is below.

       if (stats != null) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    stats.plot();
                }
            });

Inside stats.plot() is the code to plot

        public void plot() {
            Plot plt = Plot.create(); // see https://github.com/sh0nk/matplotlib4j
            plt.subplot(2, 1, 1);
            plt.title("f0,f45,f90,f135");
            plt.xlabel("time (s)");
            plt.ylabel("intensity (DN)");
            plt.plot().add(times, f0s, "r").label("f0");
            plt.plot().add(times, f45s, "g").label("f45");
            plt.plot().add(times, f90s, "b").label("f90");
            plt.plot().add(times, f135s, "cyan").label("f135");
            plt.legend();

            plt.subplot(2, 1, 2);
            plt.plot().add(times, aops, "r").label("AoP");
            plt.plot().add(times, dops, "go-").label("DoLP");
            ArrayList[] aopErrs = errors(aops, aopstds);
            ArrayList[] dopErrs = errors(dops, dopstds);
            plt.plot().add(times, aopErrs[0], "r").linewidth(.4).linestyle("dotted");
            plt.plot().add(times, aopErrs[1], "r").linewidth(.4).linestyle("dotted");
            plt.plot().add(times, dopErrs[0], "g").linewidth(.4).linestyle("dotted");
            plt.plot().add(times, dopErrs[1], "g").linewidth(.4).linestyle("dotted");
            plt.xlabel("time (s)");
            plt.ylabel("AoP and DoLP");
            plt.title("AoP and DoLP vs time");
            plt.legend();
            try {
                plt.show();
            } catch (Exception ex) {
                log.warning("cannot show the plot with pyplot - did you install python and matplotlib on path? " + ex.toString());
                showWarningDialogInSwingThread("<html>Cannot show the plot with pyplot - did you install python and matplotlib on path? <p>" + ex.toString(), "Cannot plot");
            }
        }
sh0nk commented 3 years ago

@tobidelbruck Thanks for the question. You know there's an interface called pause() on matplotlib https://matplotlib.org/stable/api/_as_gen/matplotlib.pyplot.pause.html. I've tried to think of if it can be integrated into matplotlib4j, but it's not quite easy since matplotlib4j generates a python script and run each time, so it's hard to pass the latest values to a live script asynchronously.

So far only the option I come up with is to use savefig() interface, and watch the updated image by image viewer. Does the solution work for you?