Let's say there's a plot that has two marginal plots. How can fill_between be used for the vertical plot?

from keras.datasets import mnist
import matplotlib.pylab as plt
from matplotlib.ticker import NullFormatter, NullLocator, MultipleLocator
from scipy import stats
%matplotlib inline
plt.rcParams["figure.figsize"] = [10, 10]

(x_train, y_train), (x_test, y_test) = mnist.load_data()

image = x_train[21]

xi = 0.2; yi = 0.2; wi = 0.7;  hi = 0.7 # image
xc = 0.9; yc = 0.2; wc = 0.05; hc = 0.7 # colorbar
xh = 0.2; yh = 0.0; wh = 0.7;  hh = 0.2 # horizontal plot
xv = 0.0; yv = 0.2; wv = 0.2;  hv = 0.7 # vertical plot

ax_i = plt.axes((xi, yi, wi, hi))
ax_h = plt.axes((xh, yh, wh, hh))
ax_v = plt.axes((xv, yv, wv, hv))
ax_c = plt.axes((xc, yc, wc, hc))

ax_i.xaxis.set_major_formatter(NullFormatter())
ax_i.yaxis.set_major_formatter(NullFormatter())
ax_h.yaxis.set_major_formatter(NullFormatter())
ax_v.xaxis.set_major_formatter(NullFormatter())

plt.axes(ax_i)
plt.imshow(image, aspect='auto', cmap="binary")

ax_h.plot(list(range(0, 28)), image.sum(axis=0),                                     '-k', drawstyle='steps')
#ax_h.plot(list(range(0, 28)), image.sum(axis=0) + 10 * stats.sem(image, axis=0) / 2, '-k', drawstyle='steps', color='red')
#ax_h.plot(list(range(0, 28)), image.sum(axis=0) - 10 * stats.sem(image, axis=0) / 2, '-k', drawstyle='steps', color='red')
ax_h.fill_between(
    list(range(0, 28)),
    image.sum(axis=0) + 10 * stats.sem(image, axis=0) / 2,
    image.sum(axis=0) - 10 * stats.sem(image, axis=0) / 2,
    step      = 'pre',
    facecolor = 'red',
    alpha     = 0.5
)
ax_h.set_xlim(-1, 27)

ax_v.plot(image.sum(axis=1), list(range(0, 28)), '-k', drawstyle='steps')
#ax_v.plot(image.sum(axis=1) + 10 * stats.sem(image, axis=1) / 2, list(range(0, 28)), '-k', drawstyle='steps', color='red')
#ax_v.plot(image.sum(axis=1) - 10 * stats.sem(image, axis=1) / 2, list(range(0, 28)), '-k', drawstyle='steps', color='red')
ax_v.fill_between(
    image.sum(axis=1) + 10 * stats.sem(image, axis=1) / 2,
    image.sum(axis=1) - 10 * stats.sem(image, axis=1) / 2,
    list(range(0, 28)),
    step      = 'pre',
    facecolor = 'red',
    alpha     = 0.5
)
ax_v.set_ylim(0, 28)

cb = plt.colorbar(cax=ax_c)

cb.set_label('intensity')
#ax_i.set_title('input')
#ax_h.set_xlabel('${x}$')
ax_h.set_ylabel('intensity')
ax_h.yaxis.set_label_position('right')
#ax_v.set_ylabel('${y}$')
ax_v.set_xlabel('intensity')
ax_v.xaxis.set_label_position('top')

plt.show()

EDIT: A solution was arrived at by suggestions from Loic and Jody Klymak:

ax_v.fill_betweenx(
    list(range(1, 29)),
    image.sum(axis=1) + 10 * stats.sem(image, axis=1) / 2,
    image.sum(axis=1) - 10 * stats.sem(image, axis=1) / 2,
    step      = 'pre',
    facecolor = 'red',
    alpha     = 0.5
)

1 Answers

1
Community On Best Solutions

I am not sure I understood well your question. Are you looking for the same functionality of fill_between but for reversed axes ?

If so, you can have a look at fill_betweenx : matplotlib.pyplot.fill_betweenx(y, x1, x2=0, where=None, step=None, interpolate=False, *, data=None, **kwargs)