0

I have the below code, where I want user input to build a bar chart. However, the plot never actually reveals itself until the user exits the function?

def get_plot():
    while True:
        again = input("Do you want to visualise a player's pb scores?")
        if again == 'yes':          
            while True:
                player_name = input("What player do you want to visualise PB scores for the 19/20 season?").title() 
                if player_name in historics.values:
                    print("Player is present within the underlying data")
                    break
                else:
                    print("Player does not exist within the underlying data")

            is_player = historics['Player Name'] == player_name
            new_table = historics[is_player]

            #now we will use this data to produce a bar chart for this player, showing their pb scores over the 19/20 season
            def get_graph():
                plt.bar(new_table.Date,new_table['Matchday Score'],color="g")
                plt.title("%s's PB scores for 19/20 season" % player_name)
                plt.xlabel("Date")
                plt.ylabel("Matchday Score")
                if 'Forward' in new_table['FI Player Current Position'].values:
                    plt.axhline(y=255.56, color='gold', linestyle='-')
                    plt.axhline(y=239.94, color='slategrey', linestyle='-')
                    plt.axhline(y=173.52, color='saddlebrown', linestyle='-')
                elif 'Midfielder' in new_table['FI Player Current Position'].values:
                    plt.axhline(y=262.44, color='gold', linestyle='-')
                    plt.axhline(y=263.35, color='slategrey', linestyle='-')
                    plt.axhline(y=205.66, color='saddlebrown', linestyle='-')
                else:
                    plt.axhline(y=232.62, color='gold', linestyle='-')
                    plt.axhline(y=227.43, color='slategrey', linestyle='-')
                    plt.axhline(y=182.36, color='saddlebrown', linestyle='-')
                plt.rcParams["figure.figsize"]=10,5
                plt.show()
            get_graph()
        if again == 'no':
            break
        else:
            print("Please provide a valid value")
    
get_plot()

So after the input of "no" is provided, the plot of the last provided player_name value is displayed. However, I want the plot to be created (and displayed) upon the entry of the player_name value, and for the plot to be refreshed upon each subsequent value provided?

Where am I going wrong?

Thanks.

EDIT: An example of the data (historics.head()):

        Date       Player Name       Team Name           Opposition  \
0 2020-08-23    Kingsley Coman  Bayern München  Paris Saint Germain   
1 2020-08-23    Joshua Kimmich  Bayern München  Paris Saint Germain   
2 2020-08-23  Thiago Alcántara  Bayern München  Paris Saint Germain   
3 2020-08-23      Manuel Neuer  Bayern München  Paris Saint Germain   
4 2020-08-23       David Alaba  Bayern München  Paris Saint Germain   

  Home or Away?       Competition Starting Lineup? Formation  \
0          Away  Champions League           Lineup   4-2-3-1   
1          Away  Champions League           Lineup   4-2-3-1   
2          Away  Champions League           Lineup   4-2-3-1   
3          Away  Champions League           Lineup   4-2-3-1   
4          Away  Champions League           Lineup   4-2-3-1   

   Matchday Dividends FI Game Position  ... Interceptions Blocks  Clearances  \
0                0.18          Forward  ...           0.0    0.0         0.0   
1                0.10       Midfielder  ...           1.0    1.0         1.0   
2                0.00       Midfielder  ...           2.0    0.0         0.0   
3                0.00       Goalkeeper  ...           0.0    0.0         0.0   
4                0.00         Defender  ...           1.0    0.0         2.0   

   Offsides  Fouls Committed  Yellow Cards  Red Card (Two Yellows)  \
0       0.0              0.0           0.0                     0.0   
1       0.0              1.0           0.0                     0.0   
2       NaN              4.0           0.0                     0.0   
3       0.0              0.0           0.0                     0.0   
4       0.0              0.0           0.0                     0.0   

   Straight Red Cards  Goals Conceded (GKs)  \
0                 0.0                   0.0   
1                 0.0                   0.0   
2                 0.0                   0.0   
3                 0.0                   0.0   
4                 0.0                   0.0   

   Different Game Position to Current FI Position?  
0                                                1  
1                                                1  
2                                                0  
3                                                0  
4                                                0  
2
  • Can you please post your data? Commented Sep 7, 2020 at 10:44
  • Added some example data to my initial post Commented Sep 7, 2020 at 12:21

1 Answer 1

1

There are two factors to this question:

On one hand, you will not be able to keep executing code after showing a plot, unless you are using the interactive mode of matplotlib, which can be activated by using plt.ion(). Please check this question.

On another hand, if you want to update a plot based on user input, you should start by creating a plot, and saving that reference to update the figure every time the user provides a new player_name. Please check this question, and its accepted answer.

I've made a quick example that I tested with the data you provided:

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd


def plot_player_stats(player_name, historics, fig, ax):
    # validate player name
    if player_name not in historics.values:
        print("Sorry! Unknown player!")
        return

    # search player stats
    is_player = historics['Player Name'] == player_name
    player_stats = historics[is_player]

    # draw bar plot
    ax.clear()
    ax.bar(player_stats.Date, player_stats['Matchday Score'], color="g")
    ax.set_title("%s's PB scores for 19/20 season" % player_name)
    ax.set_xlabel("Date")
    ax.set_ylabel("Matchday Score")

    # ... add lines ...
    plt.draw()


def start_main_plot_loop():

    # load data
    historics = pd.read_csv('sample.csv')

    # initialize plot
    fig, ax = plt.subplots()

    # start loop
    while True:
        player_name = input("Please select a player's name (empty to stop): ")
        if not player_name:
            print("Thanks! See ya soon ma mate!")
            break

        plot_player_stats(player_name, historics, fig, ax)


if __name__ == '__main__':
    plt.ion()
    start_main_plot_loop()

Save the ax when creating a subplot and clear it every time you need to draw a new bar plot.

EDIT:

If you are trying to run this on a Jupyter Notebook, the only thing I could do to make it work is the following:

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from IPython.display import clear_output # <---- import this function


def plot_player_stats(player_name, historics):
    # validate player name
    if player_name not in historics.values:
        print("Sorry! Unknown player!")
        return

    # search player stats
    is_player = historics['Player Name'] == player_name
    player_stats = historics[is_player]

    # draw bar plot
    plt.bar(player_stats.Date, player_stats['Matchday Score'], color="g")
    plt.title("%s's PB scores for 19/20 season" % player_name)
    plt.xlabel("Date")
    plt.ylabel("Matchday Score")

    # ... add lines ...

    clear_output() # <---- this will clear all cell output!
    plt.show()


def start_main_plot_loop():

    # load data
    historics = pd.read_csv('sample.csv')

    # start loop
    while True:
        player_name = input("Please select a player's name (empty to stop): ")
        if not player_name:
            print("Thanks! See ya soon ma mate!")
            break

        plot_player_stats(player_name, historics)

if __name__ == '__main__':
    start_main_plot_loop()

As a side effect, the clear_output function will clear all the printed output within the cell. Let me know if this is helpful!

Sign up to request clarification or add additional context in comments.

5 Comments

Thanks for the suggestion! Unfortunately it's only producing a plot (in my Jupyter Notebooks) when you exit the function. So still not getting the ability to build the plot, see it, then clear it and rebuild it.
@JacobStafford oh I didn't know that you were using a jupyter notebook, did you consider clearing the cell output every the plot is updated? Do you need to keep the previously selected player names in the cell output?
@JacobStafford I updated my response with a workaround using clear_outputfor Jupyter Notebooks
Amazing!! Works a charm. Thanks a bunch.
Great @JacobStafford, I'm glad it worked! Please remember to mark the answer as accepted so it can help other users in the future!

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.