Python scatter - change marker style based on entity
Question: I'm struggling for days trying to resolve this problem: I have cartesian
coordinates on the y-axis (for depth from 0 to 1) and numbers with different
values on the x axis (the numbers are the firing rate of different cells
populations at the given depth on y axis, so they vary randomly). I would like
to show bigger size of markers in the scatterplot corresponding to a bigger
x-axis value (firing rate). Thank you for any suggestion. This is the code
(not working).

    
    
    import matplotlib.pyplot as plt
    import numpy as np
    import matplotlib.cbook as cbook
    
    x = np.genfromtxt('x_dex.csv', delimiter=',')
    
    y = np.genfromtxt('z_dex.csv', delimiter=',')
    
    array = [i for i in x if i > 4]
    array.sort()
    
    s = [30*2**n for n in range(len(array))];
    
    plt.subplot(212)
    
    plt.scatter(x,y,s=s)
    
    plt.show()
    

This is unfortunately not showing the correct relation between size of marker
and depth.


Answer: The line where you compute your 'size' values looks incorrect to me:

    
    
    s = [30*2**n for n in range(len(array))];
    

This will give you a list containing:

    
    
    s = [30*2**0, 30*2**1, 30*2**2, ..., 30*2**(len(array) - 1)]
    

The values bear no relation to `y`, so I assume this is not what you intended.
Maybe you meant something more like this:

    
    
    s = 30 * 2 ** y
    

* * *

There are actually several other issues here:

  * Don't give your variables names like `array` \- this can lead to confusion with `numpy.array`. It's even worse in this case, since `array` is actually not an array but a Python `list`!

  * Since you're dealing with numpy arrays, it's much faster to use vectorization rather than list comprehensions. For example, you could use:
    
        array = x[x > 4]
    

rather than

    
        array = [i for i in x if i > 4]
    

  * After your list comprehension `array = [i for i in x if i > 4]`, `array` will have a different number of elements to `y` if there are elements in `array` that are less than 4.

  * `array.sort()` will sort the list _in place_ , which means that the order of the elements in `array` will no longer match the order of elements in `y`.

  * In fact, sorting seems rather pointless in this situation - since you're making a scatter plot the order of the points should not matter.

  * You're not writing MATLAB code any more, so there's no need to end lines on a semicolon (although it won't do any harm if you do).

* * *

Here's my educated guess at what you're trying to do:

    
    
    import matplotlib.pyplot as plt
    import numpy as np
    
    x = np.genfromtxt('x_dex.csv', delimiter=',')
    y = np.genfromtxt('z_dex.csv', delimiter=',')
    
    # get the set of indices that will sort x in ascending order, apply these
    # to both x & y
    order = np.argsort(x)
    x_sorted = x[order]
    y_sorted = y[order]
    
    # keep only xy pairs where x > 4
    valid = x_sorted > 4
    x_valid = x_sorted[valid]
    y_valid = y_sorted[valid]
    
    # compute the sizes
    s = 30 * 2 ** y_valid
    
    # plot
    plt.subplot(212)
    plt.scatter(x_valid, y_valid, s=s)
    
    plt.show()
    

