0

I'm trying to create a 'fill' graph in matplotlib from a pair of numpy arrays containing multiple 'curves' to be plotted. The numpy arrays have the form:

xarray([[   0],    #curve 1
        [ 100],    #curve 1
        [ 200],    #curve 1
        [   0],    #curve 2
        [ 100],    #curve 2
        [ 200]])   #curve 2

yarray([[ 11],     #curve 1
        [ 22],     #curve 1
        [ 22],     #curve 1
        [ 19],     #curve 2
        [ 12],     #curve 2
        [  0]])    #curve 2

where for this example code there are two curves (i.e x = 0-200 twice). The actual arrays have ~300 curves all starting at x = 0, although I can number them (using another array containing curve numbers) if necessary. The number of points in each xy pair is also varies.

I want to plot them with an alpha value ~0.01 (i.e nearly transparent) so that the area under the most of the curves shows up the most coloured.

However, if I put the x and y arrays into the fill function (plt.fill(xarray, yarray, alpha=0.01)) it views all the data as a single curve, so the alpha values do not stack when the curve lies on top of itself.

I am unsure how to change the x and y arrays into a list of comma separated arrays that the plt.fill function will accept. Something so that the end result will be the equivalent of me manually writing:

plt.fill(x1, y1, x2, y2, ... yn, xn, alpha=0.01)

Any ideas?

Please let me know if I haven't explained any of that well enough. Thanks!

1
  • What would your array of curve numbers look like? indices = np.array([0, 0, 0, 1, 1, 1])? Commented Jan 16, 2015 at 15:58

2 Answers 2

1

You need to split your series into multiple array and call plot function. The plots will be drawn in the same figure. You either need the length of each series to split the series or split using a marker (as you said "0" being the (always?) the first element of your concatenated series.

import numpy as np
import matplotlib.pyplot as plt

xarray = np.array([[   0],    #curve 1
                   [ 100],    #curve 1
                   [ 200],    #curve 1
                   [   0],    #curve 2
                   [ 100],    #curve 2
                   [ 200]])   #curve 2

yarray = np.array([[ 11],     #curve 1
                   [ 22],     #curve 1
                   [ 22],     #curve 1
                   [ 19],     #curve 2
                   [ 12],     #curve 2
                   [  0]])    #curve 2

# can the value "0" can be used separate xy pairs?
indices = np.argwhere(xarray[:,0] == 0)
for i in range(len(indices)):
    try:
        i0 = indices[i]
        i1 = indices[i+1]
    except:
        i0 = indices[i]
        i1 = len(xarray[:,0])
    plt.fill(xarray[i0:i1,0], yarray[i0:i1,0])
plt.show()
Sign up to request clarification or add additional context in comments.

Comments

0

With some fiddling using various numpy routines, you could attempt something like the following:

import numpy as np
from matplotlib import pyplot as plt

x = np.array([[   0], [ 100], [ 200],
              [   0], [ 100], [ 200], 
              [0], [100], [200], [300]])
y = np.array([[ 11], [ 22], [ 22],
              [ 19], [ 12], [  0],
              [11], [33], [11], [22]])
indices = np.array([0, 0, 0, 1, 1, 1, 2, 2, 2, 2])

split = np.where(np.diff(indices))[0] + 1
x = np.squeeze(x)
y = np.squeeze(y)
x = np.split(x, split)
y = np.split(y, split)

xy = np.vstack((x, y))
xy = xy.T.flatten()

plt.figure()
plt.fill(*xy, alpha=0.01)
plt.show()

All the juggling with x and y are to get the two arrays nicely lined up for a single array, that you can then use with with the *arg method as input to pyplot.fill.

Comments

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.