-1

I am making an application where the users inputs data and the results are displayed on a chart. I want the plot to update each time new data is input, but updating the plot is not happening.

The plot is produce using the matlib plot library and the interface is created using the tkinter package. The way it is done is uses a function to create the plot as I want to call this several times. What I think could be the problem is the way the function returns the variable, but I can't put my finger on what or why this is wrong.

I have looked on here for solutions and none of the ones I have read seem to work. I have tried to update my axes, used patlibplot.figure instead of matlibplot.plot , adding canvas.daw() to the end and even tried to get a new way of producing the plot.

This is the function that creates the plot:

import matplotlib.pyplot as plt

def PlotConsumption(fuelEntry, plotConfig):
    '''
    Produce a line plot of the consumption
    :params object fuelEntry: all of the fuel entry information
    :params object plotConfig: the config object for the plot
    '''

    # create a data frame for plotting
    df = pd.DataFrame(fuelEntry)
    df = df.sort_values(["sort"]) # ensure the order is correct
    df["dateTime"] = pd.to_datetime(df["date"], format="%d/%m/%Y") # create a date-time version of the date string

    if plotConfig.xName == "date": # change the indexing for dates
        ax = df.plot(x = "dateTime", y = plotConfig.yName, marker = '.', rot = 90, title = plotConfig.title)
    else:
        ax = df.plot(x = plotConfig.xName, y = plotConfig.yName, marker = '.', title = plotConfig.title)

    # calculate the moving average if applicable
    if plotConfig.moveCalc == True and plotConfig.move > 1 and len(df) > plotConfig.move:
        newName = plotConfig.yName + "_ma"
        df[newName] = df[plotConfig.yName].rolling(window = plotConfig.move).mean()   
        if plotConfig.xName == "date":
            df.plot(x = "dateTime", y = newName, marker = "*", ax = ax)
        else:
            df.plot(x = plotConfig.xName, y = newName, marker = "*", ax = ax)

    # tidy up the plot
    ax.set(xlabel = plotConfig.xLabel, ylabel = plotConfig.yLabel)
    plt.setp(ax.xaxis.get_majorticklabels(), rotation=90)
    L=plt.legend()
    L.get_texts()[0].set_text(plotConfig.yLegend)
    if len(L.get_texts()) == 2: # only process if there is a moving average plot
        L.get_texts()[1].set_text(plotConfig.moveLegend)

    return plt # also tried with returning ax

And this is where it is used:

self.plot = displayCharts.PlotConsumption(self.data.carEntry["fuelEntry"], self.plotConfig)
#fig = plt.figure(1) # also tried creating fig this way 
fig = self.plot.figure(1)
self.plotCanvas = FigureCanvasTkAgg(fig, master = self.master)
self.plotWidget = self.plotCanvas.get_tk_widget()
self.plotWidget.grid(row = 0, column = 1, rowspan = 3, sticky = tk.N)
fig.canvas.draw() 

I expect the plot to update automatically but instead it does nothing. I know the data is read and processed as if you close the application, start it up again and then load the same data file the plot produced is correct.

KitsonRis
  • 23
  • 6

1 Answers1

0

I revisited some of the answers I initially looked at and picked my way through them and this one is the best I found and it actually does what I want!

There were a few sublte differences that I needed to change:

  1. Create the figure and canvas to start with
  2. Use these variables to create the plot

I copied the linked solution to see how it works and managed to get it to work. Now the next thing is to get it to plot with my data! But now that I have got it updating it should be easier to finish off.

KitsonRis
  • 23
  • 6