1

I have a MxN (say, 1000x50) array. I want to plot each 50-point line onto the same plot, and have a heatmap of their density.

Simply doing a plt.pcolor(data) is not what I want, since I don't want to plot the matrix.

This is what I want to plot, but as I said it doesn't provide me with the heatmap I need.

import numpy as np
import matplotlib.pyplot as plt

data = np.random.rand(1000, 50)

fig, ax = plt.subplots()
for i in range(0,1000):
    ax.plot(data[i], '.')

plt.show()

I would like a way of getting this together (I assume it will have something to do with histograms and binning?).

EDIT: simply adding an alpha value to the plot ( ax.plot(data[i], '.r', alpha=0.01)) achieves something similar to what I want. I would like, however, to have a heatmap with different colours.

2
  • i am not sure, as to what exactly you want. Does this look like something you were going for (i've used a normal distribution instead of uniform)? Commented Apr 11, 2019 at 11:49
  • @SamProell that is precisely what I was going for. Cheers Commented Apr 11, 2019 at 12:38

1 Answer 1

1

As you already pointed out in your question, probably one of the simplest approaches involves histograms. A linear approximation of the histogram is probably enough for this application.

You can use np.histogram to calculate bin heights and edges and use scipy.interpolate.interp1d to obtain a function that provides an interpolation of the histogram. We can define a simple helper function to get the approximate density around each value in one column of the data array:

# import scipy.interpolate as interp
def get_density(vals, bins=30, kind="linear"):
    y, bin_edges = np.histogram(vals, bins=bins, density=True)
    x = (bin_edges[1:] + bin_edges[:-1])/2.
    f = interp.interp1d(x, y, kind=kind, fill_value="extrapolate")
    return f(vals)

Then you can use any colormap you want to map the density to a color value. The easiest way to go from here is to use plt.scatter instead of plot, where you can provide a specific color for every data point.

I would do something like this:

fig, ax = plt.subplots()
for i in range(data.shape[1]):
    colors = plt.cm.viridis(get_density(data[:, i]))
    ax.scatter(i*np.ones(data.shape[0]), data[:, i], c=colors, marker='.')
Sign up to request clarification or add additional context in comments.

2 Comments

I have been using this now for a while, thanks a lot for this answer. However, lately I have been trying to use a custom-made LinearSegmentedColormap as opposed to a ListedColormap like viridis, and I am getting a ValueError: data mapping points must start with x=0 and end with x=1 when I try to compute colors. Is there a way to solve this? Or is it another question I need to open?
@Enzo, I am not familiar with custom colormaps.. It might be best to post a new, more specific, question!

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.