1

I am trying to create a 2d Histogram from a scatter plot. But I get the error: ValueError: too many values to unpack (expected 2) using the code below

If I alter the input data to contain one list for the xy coordinates it works fine. It also works if I only select the first list in the 2dhistogram line. e.g zi, xi, yi = np.histogram2d(x[0], y[0], bins=bins).

import matplotlib.pyplot as plt
import numpy as np
import random
from functools import partial

##create list of lists (x,y coordinates)
x_list = partial(random.sample, range(80), 10)
y_list = partial(random.sample, range(80), 10)
x = [x_list() for _ in range(10)]
y = [y_list() for _ in range(10)]

fig, ax = plt.subplots()
ax.set_xlim(0,80)
ax.set_ylim(0,80)

bins = [np.linspace(*ax.get_xlim(), 80),
        np.linspace(*ax.get_ylim(), 80)]

##error occurs in this line
zi, xi, yi = np.histogram2d(x, y, bins=bins)
zi = np.ma.masked_equal(zi, 0)

ax.pcolormesh(xi, yi, zi.T)    
ax.set_xticks(bins[0], minor=True)
ax.set_yticks(bins[1], minor=True)
ax.grid(True, which='minor')

scat = ax.scatter(x, y, s = 1)

The only post I could find about this suggested to try and change the x,y to a numpy array. I tried this but still get the same error code.

zi, xi, yi = np.histogram2d(np.asarry(x), np.asarray(y), bins=bins)

Any other suggestions?

  • from the histogram2d documentation : x : array_like, shape (N,) An array containing the x coordinates of the points to be histogrammed. y : array_like, shape (N,) , but it seems your x and y shapes are (10,10) – Siva-Sg Apr 19 '18 at 05:45
  • So I could just combine all the xy coordinates into one list each. Thanks @user1319128 –  Apr 19 '18 at 05:53
  • Easiest way to combine/flatten a list-of-lists in Python is to use a list comprehension. You just have to tweak the lines that populate `x` and `y` a little bit. Alternatively, you could just use `np.random.randint` to get random int arrays of the desired shape without needing any other manipulation – tel Apr 19 '18 at 06:31

1 Answers1

0

np.histogram2d expects flat lists of x and y coordinates, not list-of-lists. You can fix this pretty easily. Just change the lines that populate x and y to flattening list comprehensions:

x = [num for _ in range(10) for num in x_list()]
y = [num for _ in range(10) for num in y_list()]

Alternatively, you could skip the whole complexity of using random.sample and partial and just use np.random.randint instead, which can create random integer arrays of any given shape:

x = np.random.randint(0, 80, size=100)
y = np.random.randint(0, 80, size=100)
tel
  • 13,005
  • 2
  • 44
  • 62
  • Thanks @tel. I was just replicating my input data with the list of lists. –  Apr 22 '18 at 07:28