Place multiple numpy arrays into a larger array

Question:

I wish to create a large array and replace some of the values with two other arrays. Each assignment works independently but the second statement overrides the first. I wish to see both images in the background plot.

import numpy as np
import matplotlib.pyplot as plt

#initialize the arrays
img1 = np.random.rand(400,400)
img2 = np.arange(0,10000).reshape((100,100))
background = np.zeros(shape = (1600, 1600))

#embed the background with the 1st image
background[0:img1.shape[0], 0:img1.shape[1]] = img1

#place the other image somewhere else in the array
background[500:(100+500), 500:(100+500)] = img2

#plot the results
fig, ax = plt.subplots(3, 1, figsize = (5,5))
ax[0].imshow(img1, cmap = 'rainbow') 
ax[1].imshow(img2, cmap = 'rainbow') 
ax[2].imshow(background, cmap = 'rainbow') 

plt.show()
Asked By: john

||

Answers:

The problem is not that "the second statement overrides the first". The problem (i.e. the reason that you’re only seeing one of the images within the composite image) is that the entries in image 2 are much larger than those of image 1. When you show img1 alone, the colormap fits the colors over a scale from 0 to (approximately) 1. When the two images are shown together, the colors are scaled from 0 to 10000, so the values from img1 are all too close to zero for the image to show up.

Here’s a change to your code that scales the values of the second array down to a maximum value of 1; note that both images show up this time.

import numpy as np
import matplotlib.pyplot as plt

#initialize the arrays
img1 = np.random.rand(400,400)
img2 = np.arange(0,10_000).reshape((100,100))/10_000
background = np.zeros(shape = (800, 800))

#embed the background with the 1st image
background[0:img1.shape[0], 0:img1.shape[1]] = img1

#place the other image somewhere else in the array
background[500:(100+500), 500:(100+500)] = img2

#plot the results
fig, ax = plt.subplots(3, 1, figsize = (5,5))
ax[0].imshow(img1, cmap = 'rainbow') 
ax[1].imshow(img2, cmap = 'rainbow') 
ax[2].imshow(background, cmap = 'rainbow') 

plt.show()

The result:

enter image description here


Incidentally, if you want to combine arrays on a zero "background" in this manner, you might want to consider using the scipy.linalg.block_diag method. For instance,

import numpy as np
import matplotlib.pyplot as plt
from scipy.linalg import block_diag

#initialize the arrays
img1 = np.random.rand(400,400)
img2 = np.arange(0,10_000).reshape((100,100))/10_000

space1 = np.zeros([100,100])
space2 = np.zeros([100,100])

composite = block_diag(img1, space1, img2, space2)

#plot the results
fig, ax = plt.subplots(3, 1, figsize = (5,5))
ax[0].imshow(img1, cmap = 'rainbow') 
ax[1].imshow(img2, cmap = 'rainbow') 
ax[2].imshow(composite, cmap = 'rainbow') 

plt.show()
Answered By: Ben Grossmann