Python: Plot frequency of negative (x,y) coordinates

Question:

I’m trying to plot the frequencies of a 2D-integer random walk starting from (0,0). First, I get a list of (x,y)-coordinates, some of which are negative and I’m having problems plotting them the right way. I know my current attempt is wrong, as (0,0) sometimes look like its not in the random walk at all.

Here’s my attempt:

The idea is to transpose all (x,y)-coordinates, so they’re in the first quadrant and then manipulate the axes on extent to transpose them back to their original form. I do so in order to avoid unwanted list-operations in the construction of grid, which would make the plot ‘jump’

# generate random walk
import random

def random_walk():

    a = 0
    b = 0
    while True:
        yield (a, b)

        i = random.choice([0, 1])
        if i == 0:
            a = random.choice([a-1, a+1])
        else:
            b = random.choice([b-1, b+1])

And the attempt at plotting itself:

import matplotlib.pyplot as plt
import itertools 
import numpy as np

# generate random walk of length 1000
walk = list(itertools.islice(random_walk(), 0, 1000))

xy = list(zip(*walk))

x = list(xy[0])
y = list(xy[1])

ext = (min(x), max(x), min(y), max(y))

min_x = min(x)
min_y = min(y)

# transpose all x.- and y.-coordinates:

for i in range(len(x)):
    x[i] -= min_x

for i in range(len(y)):
    y[i] -= min_y

walk_new = list(zip(x,y))

grid = np.zeros((max(x) + 1, max(y) + 1))

# Put frequencies in grid:
for a,b in walk_new:
    grid[a][b] += 1


plt.imshow(grid)
plt.colorbar()
Asked By: ProbM

||

Answers:

I did notice that the origin (0,0) didn’t show up on your heatmap as expected when I ran your code. I left your random_walk function as is, but I think using matplotlib’s hist2d would be easier here, as the (x,y) coordinates display exactly as you like with no need for transposing the coordinates you generated.

import matplotlib.pyplot as plt
import itertools 
import numpy as np

# generate random walk of length 1000
walk = list(itertools.islice(random_walk(), 0, 1000))

xy = list(zip(*walk))

x = list(xy[0])
y = list(xy[1])

heatmap, xedges, yedges = np.histogram2d(x, y, bins=[np.arange(min(x),max(x),1),np.arange(min(y),max(y),1)])
extent = [xedges[0], xedges[-1], yedges[0], yedges[-1]]
plt.imshow(heatmap, origin='lower', extent=extent)

# set bins to be 1 unit apart since your (x,y) coordinates are integers
# plt.hist2d(x,y, bins=[np.arange(min(x),max(x),1),np.arange(min(y),max(y),1)])
plt.colorbar()
plt.show()

enter image description here

Answered By: Derek O