Boundary histograms / graph lines as in FACS

My question is mostly different from this , but for matplotlib. I'm sure it has something to do with axes or subplots, but I don't think I fully understand these paradigms (a fuller explanation would be great).

When I go through a set of comparisons, I would like the base value of each new graph to be slightly lower than the previous one, in order to get something like this:

enter image description here

Another (potential) wrinkle is that I generate these plots in a loop, so I don't necessarily know how many areas there will be at the very beginning. I think this is one of those things I get on a day to day basis with subplots / axes because it seems like you need to set them up ahead of time.

Any ideas will be very grateful.

EDIT: I've made little progress, I think:

import numpy as np 
import pandas as pd
import matplotlib.pyplot as plt

x = np.random.random(100)
y = np.random.random(100)


fig = plt.figure()
ax = fig.add_axes([1,1,1,1])
ax2 = fig.add_axes([1.02,.9,1,1])

ax.plot(x, color='red')
ax.fill_between([i for i in range(len(x))], 0, x, color='red', alpha=0.5)
ax2.plot(y, color='green')
ax2.fill_between([i for i in range(len(y))], 0, y, color='green', alpha=0.5)

      

Gives me: enter image description here

Which is close to what I want ...

+3


source to share


3 answers


Is this what you want?

stacked charts

What I did was define the y distance between the baselines of each curve. For the i-th curve, I calculated the minimum Y value, then set the minimum to be i times the y-distance, adjusting the height of the entire curve accordingly. I used a decreasing z-order to ensure that the filled portion of the curves was not shaded by the baselines.

Here's the code:



import numpy as np
import matplotlib.pyplot as plt

delta_Y = .5

zorder = 0
for i, Y in enumerate(data):
  baseline = min(Y)
  #change needed for minimum of Y to be delta_Y above previous curve
  y_change = delta_Y * i - baseline
  Y = Y + y_change
  plt.fill_between(np.linspace(0, 1000, 1000), Y, np.ones(1000) * delta_Y * i, zorder = zorder)
  zorder -= 1

      

Code that generates dummy data:

def gauss(X):
  return np.exp(-X**2 / 2.0)

#create data
X = np.linspace(-10, 10, 100)
data = []
for i in xrange(10):
  arr = np.zeros(1000)
  arr[i * 100: i * 100 + 100] = gauss(X)
  data.append(arr)
data.reverse()

      

+4


source


You can also explore JoyPy installation via:

pip install joypy

A fairly dynamic tool created by Leonardo Taccari, if you look at "stacked" distribution plots like this:

Example 1 - Plot of joy using JoyPy:
Joy Plot using JoyPy



Example 2 - Plot of joy in aperture dataset:
Joy Plot on Iris dataset

Leonardo also has a neat description of the package and how to use it here .

Alternatively Seaborn has a package , but I found it less easy to use.

Hope it helps!

+2


source


This way I was able to get a little further by adding an extra Axes instance to each loop.

import numpy as np 
import pandas as pd
import matplotlib.pyplot as plt

#instantiate data sets
x = np.random.random(100)
y = np.random.random(100)
z = np.random.random(100)

plots = [x, y, z]
fig = plt.figure()

#Sets the default vertical position
pos = 1

def making_plot(ax, p):
    ax.plot(p)

    # Prevents the background from covering over the earlier plots
    ax.set_axis_bgcolor('none')

for p in plots:
    ax = fig.add_axes([1,pos,1,1])
    pos -= 0.3
    making_plot(ax, p)
plt.show()

      

enter image description here

Clearly I could have spent more time making this prettier, but it does the job.

0


source







All Articles