0

Is there a simple way to plot 2D data with means of pixel intensity along the x- and y-axes on the sides of the image? similar to seaborn's jointplot (doc) but using a 2D numpy array as an input? Or maybe the numpy array can easily be transformed into a form that can be scatter plotted?

An ugly workaround would be the following where I transform the image into x and y coordinates. Then, I can use jointplot but the image output is pretty ugly.

img=#some 2d image data
xx=np.zeros(img.sum())
yy=np.zeros(img.sum())
i=0
for x in range(img.shape[0]):
    for y in range(img.shape[1]):
        for c in range(img[x,y]):
            xx[i]=x
            yy[i]=y
            i+=1

import seaborn as sns            
sns.jointplot(yy,xx)

enter image description here

jlarsch
  • 2,217
  • 4
  • 22
  • 44
  • It's not clear what you expect from an histogram of pixel intensity along the x or y axis. Can you elaborate on that? – MB-F Feb 17 '17 at 13:27
  • I found a pretty good solution here: http://stackoverflow.com/questions/20525983/matplotlib-imshow-a-2d-array-with-plots-of-its-marginal-densities – jlarsch Feb 17 '17 at 13:54
  • not quite a slick as seaborn but a good start – jlarsch Feb 17 '17 at 13:54
  • The solution you found plots the image's means over each axis. This is not the same as a histogram. So what is it you are really after? A discrete (bar plots) version of that solution? – MB-F Feb 17 '17 at 14:23
  • you are right, I should have said 'image's mean'. I adapted the question – jlarsch Feb 17 '17 at 14:31

1 Answers1

0

inspired by the suggestion in the link in my comment, I came up with the following prettified version:

from matplotlib import gridspec
img=tmp
fig=plt.figure(figsize=(6, 6))
t = np.arange(img.shape[0])
f = np.arange(img.shape[1])
flim = (f.min(), f.max())
tlim = (t.min(), t.max())


gs = gridspec.GridSpec(2, 2, width_ratios=[5,1], height_ratios=[1,5])
gs.update(hspace=0, wspace=0)
ax = fig.add_subplot(gs[1,0])
axl = fig.add_subplot(gs[1,1], sharey=ax)
axb = fig.add_subplot(gs[0,0], sharex=ax)
plt.setp(axl.get_yticklabels(), visible=False)
plt.setp(axb.get_xticklabels(), visible=False)
plt.setp(axl.get_xticklabels(), visible=False)
plt.setp(axb.get_yticklabels(), visible=False)

ax.imshow(img, origin='lower',aspect='equal')

axl.fill_between(img.mean(1), f)
axb.fill_between(t, img.mean(0))
ax.set_xlim(tlim)
ax.set_ylim(tlim)

enter image description here

Community
  • 1
  • 1
jlarsch
  • 2,217
  • 4
  • 22
  • 44