Search code examples
pythonarraysmatplotlibmontecarlo

Plotting a graph using a function applied to elements in an array


I'm trying to plot a graph where the x-values are denoted by the array below:

player_number = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]

And the y values correspond to the value of the function below, when each of the elements in player_number is passed through it.

def success_rate(player_number):

which returns a single value My issue is that I am unable to to plot the graph in the following way:

plt.scatter(player_number, success_rate(player_number))

I receive the error:

TypeError: unsupported operand type(s) for -: 'list' and 'int'

I'm trying to get each of the values in player_number to produce a

The full details of my code can be seen below, I'm coding a Squid Game bridge Simullation.

import random
import matplotlib.pyplot as plt


#tiles indexed 1-19, with an index of 0 meaning the player was unlucky enough to make it on to 0 tiles
#function to output the furthest tile safely reached
def furthest_safe_tile(total_tiles):
    if total_tiles == 0:
        return total_tiles
    for k in range(1, (total_tiles + 1)):
        current_probability = random.uniform(0, 1)
        if k == total_tiles:
            return k
            break
        elif current_probability < 0.5:
            return k
            break


success_or_failure = []
number_contestants = 16


def tiles():
    number_eliminated_tiles = 0
    for i in range(number_contestants):
        tile_advance = furthest_safe_tile(19 - number_eliminated_tiles)
        number_eliminated_tiles = tile_advance + number_eliminated_tiles
        if number_eliminated_tiles == 19:
            success_or_failure.append(0) #0 meaning success
        else:
            success_or_failure.append(1)
    return success_or_failure


giant_list = []
for y in range(1000):
    giant_list = giant_list + tiles()


def success_rate(player_number):
    running_total = 0
    number_of_values_for_each_player_number = len(giant_list) // 16
    for p in range(0, number_of_values_for_each_player_number):
        running_total = running_total + giant_list[(player_number-1) + (16 * p)]
    success_value = (number_of_values_for_each_player_number - running_total) / number_of_values_for_each_player_number
    return success_value


player_number = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]



plt.style.use('grayscale')
plt.figure(figsize=(10, 10))
plt.scatter(player_number, success_rate(player_number), alpha = 0.4, c = 'black', s = 50, marker = '.')
plt.xlim(1, 16)
plt.ylim(0, 1)
plt.title("A graph Showing the Probability of Each contestant not Dying (Monte Carlo Method)")
plt.ylabel("Probability of Life")
plt.xlabel("Contestant Number")
plt.show()


Solution

  • You need to prepare data correctly to use with .scatter() function.

    Here is the modified code and the output plot:

    import random
    import matplotlib.pyplot as plt
    
    #tiles indexed 1-19, with an index of 0 meaning the player was unlucky enough to make it on to 0 tiles
    #function to output the furthest tile safely reached
    def furthest_safe_tile(total_tiles):
        if total_tiles == 0:
            return total_tiles
        for k in range(1, (total_tiles + 1)):
            current_probability = random.uniform(0, 1)
            if k == total_tiles:
                return k
                break
            elif current_probability < 0.5:
                return k
                break
    
    
    success_or_failure = []
    number_contestants = 16
    
    
    def tiles():
        number_eliminated_tiles = 0
        for i in range(number_contestants):
            tile_advance = furthest_safe_tile(19 - number_eliminated_tiles)
            number_eliminated_tiles = tile_advance + number_eliminated_tiles
            if number_eliminated_tiles == 19:
                success_or_failure.append(0) #0 meaning success
            else:
                success_or_failure.append(1)
        return success_or_failure
    
    
    giant_list = []
    for y in range(1000):
        giant_list = giant_list + tiles()
    
    
    def success_rate(player_number):
        running_total = 0
        number_of_values_for_each_player_number = len(giant_list) // 16
        for p in range(0, number_of_values_for_each_player_number):
            running_total = running_total + giant_list[(player_number-1) + (16 * p)]
        success_value = (number_of_values_for_each_player_number - running_total) / number_of_values_for_each_player_number
        return success_value
    
    player_number = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]
    
    plt.style.use('grayscale')
    plt.figure(figsize=(7, 4))
    
    # Fails here
    #plt.scatter(player_number, success_rate(player_number), alpha = 0.4, c = 'black', s = 50, marker = '.')
    
    # Begin my code
    rates = []
    for ea in player_number:
        rates.append(success_rate(ea))
    plt.scatter(player_number, rates, alpha = 0.4, c = 'black', s = 50, marker = '.')
    # End mycode
    
    plt.xlim(1, 16)
    plt.ylim(0, 1)
    plt.title("A graph Showing the Probability of Each contestant not Dying (Monte Carlo Method)")
    plt.ylabel("Probability of Life")
    plt.xlabel("Contestant Number")
    plt.show()
    

    outputplot

    Alternately, you can change the line of errorneous code

    plt.scatter(player_number, success_rate(player_number), ...
    

    to

    plt.scatter(player_number, [success_rate(x) for x in player_number], alpha=0.4, c='black', s=50, marker='.')
    

    and get the same result.