Python imshow will only display last line - python

I have the following code that when run separately, displays two maps:
Map1:
f = h5py.File(filename[0], 'r')
group_id='Soil_Moisture_Retrieval_Data_AM'
var_id = 'soil_moisture'
a = f[group_id][var_id][:,:]
plt.figure(figsize=(10, 10))
a[a==f[group_id][var_id].attrs['_FillValue'].astype(int)]==np.nan;
plt.imshow(a,vmin=0.,vmax=0.55, cmap = 'terrain_r');
cbar = plt.colorbar(orientation='horizontal')
cbar.set_label('$cm^3 cm^{-3}$')
Map2:
f1 = h5py.File(filename[1], 'r')
b = f1[group_id][var_id][:,:]
b[b==f1[group_id][var_id].attrs['_FillValue'].astype(int)]==np.nan;
plt.figure(figsize=(10, 10))
plt.imshow(b,vmin=0.,vmax=0.55, cmap = 'terrain_r');
cbar = plt.colorbar(orientation='horizontal')
cbar.set_label('$cm^3 cm^{-3}$')
Trying to overlay the two maps will only display the last line (in this case, b):
plt.figure(figsize=(10, 10))
plt.imshow(a,vmin=0.,vmax=0.55, cmap = 'terrain_r')
plt.imshow(b,vmin=0.,vmax=0.55, cmap = 'terrain_r')
What am I possibly missing? Happy to provide more info if needed...

Related

Plot multiple lines in a loop

I try to plot lines in a loop,but its connecting it,i tried many variants,but cand understand and find the answer,maybe the dataframe
im a newbie in Matplotlib
the code of method:
self.testnewnewventnest[Debit] - is a nested dict with the data i need for plotting
def showmainplot(self):
for Debit in self.Debitlist:
self.Presinit = self.VentTable.loc[Debit]
self.Tinit= float(self.Tinit)
self.Presinit=int(float(self.Presinit))
self.Powinit = float(self.Powinit)
x = symbols("x")
for Turatie in self.Tfin:
eqPres = (Turatie/self.Tinit)*(Turatie/self.Tinit)*self.Presinit-x
PresFin = solve(eqPres)
eqDebit = (Turatie/self.Tinit)*int(Debit)
DebitFin = solve(eqDebit)
eqPow = (Turatie/self.Tinit)*(Turatie/self.Tinit)*(Turatie/self.Tinit)*float(self.Powinit)
self.TestnewVentnest['KW'] = float(eqPow)
self.TestnewVentnest['Turatie'] = Turatie
self.TestnewVentnest['Presiune'] = float(PresFin[0])
self.TestnewVent[float(eqDebit)] = dict(self.TestnewVentnest)
self.testnewnewventnest[Debit] = dict(self.TestnewVent)
print(self.testnewnewventnest)
axeslist = []
n=0
fig, ax = plt.subplots(figsize=(5, 5))
ax1 = ax.twinx()
ax1.spines.right.set_position(("axes", 1.06))
ax.set_xlabel("Debit")
for dicts in self.testnewnewventnest:
Ventdataframe = pd.DataFrame(self.testnewnewventnest[dicts])
print(Ventdataframe)
ax2 = plt.subplot()
fig, ax = plt.subplots(figsize=(5, 5))
ax1 = ax.twinx()
ax1.spines.right.set_position(("axes", 1.06))
ax.set_xlabel("Debit")
axeslist.append(plt.subplot())
# print(df.iloc[0])
# ax1.set_ylabel("Turatie")
# ax.set_ylabel("Presiune")
# Ventdataframe.plot(Ventdataframe.loc["Presiune"], color="b",label="Presiune"+str(n),marker = 'o')
Ventdataframe.loc["Presiune"].plot(color="b",label="Presiune"+str(n),marker = 'o')
n+=1
# ax2 = ax.twinx()
# ax2.set_ylabel('KW')
# ax1.plot(Ventdataframe.loc["Turatie"],color='#000000',label="Turatie",marker = 'o')
# ax2.plot(Ventdataframe.loc["KW"], color='r',label="KW",marker = 'o')
# ax1.grid()
# ax2.yaxis.set_major_locator(FixedLocator(Ventdataframe.loc["KW"]))
# ax.yaxis.set_major_locator(FixedLocator(Ventdataframe.loc["Presiune"]))
# ax1.yaxis.set_major_locator(FixedLocator(self.Tfin))
# ax.xaxis.set_major_locator(FixedLocator(Ventdataframe.columns))
# lc = matpl.ticker.NullLocator()
# ax.yaxis.set_major_locator(lc)
plt.show()
and the self.testnewnewventnest look like:
Yes,the problem was in the loop,and in the dictionaries,in every iteration he added all previous dictionaries from iterations
I would put that in a dataframe and do it like this.
uniques = df['ID'].unique()
for i in uniques:
fig, ax = plt.subplots()
fig.set_size_inches(4,3)
df_single = df[df['ID']==i]
sns.lineplot(data=df_single, x='Month', y='Expense')
ax.set(xlabel='Time', ylabel='Total Expense')
plt.xticks(rotation=45)
plt.show()

How to plot 2 maps in 1 plot using Matplotlib? (Python)

I was trying to overlay 1 map on another, but I could not.
input_file = "slicedSmoothedStokesPlanck/Smoothed_Sliced_PSI_MAP.fits"
i_file = "slicedSmoothedStokesPlanck/Smoothed_Sliced_I_MAP.fits"
pl_b = fits.getdata(input_file, ext=0)
i_file_data = fits.getdata(i_file, ext=0)
fig = plt.figure()
ax = fig.add_subplot(111) #, projection=wcs
im = ax.imshow(texture, alpha=0.5) #, cmap='RdYlBu_r'
ax.imshow(i_file_data)
plt.title("TEST")
plt.show()
The above code, only shows last ax.imshow(i_file_data)
The idea is that I have a map1, and map2. I want to overlay map2 with alpha = 0.5 on map1, and plot it.
If I am getting you correctly then this should work. I assume your bottom layer has color and top layer has just boundaries.
fig, ax = plt.subplots(1,1, figsize(8, 8))
pl_b.plot(ax = ax, cmap = "RdYlBu_r", edgecolor = "black", lw = 0.1) #, this is your map 1
i_file_data.plot(ax = ax, facecolor = "none", edgecolor = "black", lw = 0.1, alpha = 0.5) #, this is your map 2
plt.title("TEST")
plt.show()
You can tweak the top layer and change the opacity accordingly.
If you want your map 2 be just the outline on top of map 1 then set facecolor = "none" in the second layer

Fast way of saving many images with matplotlib and for loop

I noticed that there is a big performance gap between the following two solutions to load and save images with matplotlib. Can anyone explain why, and what is the best (and fastest) way to save images in a python for loop?
Implementation 1:
create a figure outside the for loop, update what is displayed and then save.
fig, a = plt.subplots(1, 3, figsize=(30, 20)) # <--------
# list_of_fnames is just a list of file names
for k, fname in enumerate(list_of_fnames):
with Image.open(fname) as img:
x = np.array(img)
y = process_image_fn1(x)
z = process_image_fn2(x)
a[0].imshow(x)
a[1].imshow(y)
a[2].imshow(z)
output_filename = f'results_{k}.png'
plt.savefig(output_filename, dpi=320, format='png', transparent=False, bbox_inches='tight', pad_inches=0)
Implementation 2:
create a figure inside the for loop, save it, finally destroy it.
# list_of_fnames is just a list of file names
for k, fname in enumerate(list_of_fnames):
with Image.open(fname) as img:
x = np.array(img)
y = process_image_fn1(x)
z = process_image_fn2(x)
fig, a = plt.subplots(1, 3, figsize=(30, 20)) # <--------
a[0].imshow(x)
a[1].imshow(y)
a[2].imshow(z)
output_filename = f'results_{k}.png'
plt.savefig(output_filename, dpi=320, format='png', transparent=False, bbox_inches='tight', pad_inches=0)
plt.close() # <--------
The first option could be improved in a couple of ways.
removing the previously plotted AxesImages (from imshow), so that you don't keep increasing the number of plotted images on the axes
fig, a = plt.subplots(1, 3, figsize=(30, 20)) # <--------
# list_of_fnames is just a list of file names
for k, fname in enumerate(list_of_fnames):
for ax in a:
ax.images.pop()
with Image.open(fname) as img:
x = np.array(img)
y = process_image_fn1(x)
z = process_image_fn2(x)
a[0].imshow(x)
a[1].imshow(y)
a[2].imshow(z)
output_filename = f'results_{k}.png'
plt.savefig(output_filename, dpi=320, format='png', transparent=False, bbox_inches='tight', pad_inches=0)
alternatively, create the AxesImages once per axes, then rather than replot them each iteration, use .set_array() to change what is plotted on the AxesImage
fig, a = plt.subplots(1, 3, figsize=(30, 20)) # <--------
# list_of_fnames is just a list of file names
for k, fname in enumerate(list_of_fnames):
with Image.open(fname) as img:
x = np.array(img)
y = process_image_fn1(x)
z = process_image_fn2(x)
if k == 0:
im0 = a[0].imshow(x)
im1 = a[1].imshow(y)
im2 = a[2].imshow(z)
else:
im0.set_array(x)
im1.set_array(y)
im2.set_array(z)
output_filename = f'results_{k}.png'
plt.savefig(output_filename, dpi=320, format='png', transparent=False, bbox_inches='tight', pad_inches=0)

I have a 3D plot with 4 points, I want one to be the focal point and the other three to have lines connecting them to the focal point

I used scatter3D to plot the points, but it doesn't seem like I can connect them. The cell is the focal point and the inj are the three it should connect to, any suggestions?
fig = plt.figure()
ax = fig.gca(projection='3d')
cell= [1258096.60,11285000.00, 9415.22]
inj_1 = [1267960.80 ,11278335.00,9430.9]
inj_2 = [1267960.80 ,11278335.00,9441.32]
inj_3 = [1267960.80 ,11278335.00,9453.99]
inj_cells = cell,inj_1,inj_2,inj_3
for i in inj_cells:
I = np.array(i[0])
J = np.array(i[1])
K = np.array(i[2])
plot = ax.scatter3D(I,J,K)
plt.show()
to draw lines use ax.plot:
fig = plt.figure()
ax = fig.gca(projection='3d')
cell= [1258096.60,11285000.00, 9415.22]
inj_1 = [1267960.80 ,11278335.00,9430.9]
inj_2 = [1267960.80 ,11278335.00,9441.32]
inj_3 = [1267960.80 ,11278335.00,9453.99]
inj_cells = cell,inj_1,inj_2,inj_3
c, d, e = cell
for i in inj_cells:
I = np.array(i[0])
J = np.array(i[1])
K = np.array(i[2])
ax.plot((c,I), (d,J), (e,K))
plt.show()

How to add subfigures in a loop

I have a loop in which I would like to create three subfigures. Here is some code with the function definitions removed.
n = 14
dets = []
entropies = []
N = 1000
fig = plt.figure()
# The loop.
for h in xrange(2,8,2):
for i in xrange(N):
A = (np.random.randint(2, size=(h,n)))*2-1
detA_Atranspose = np.linalg.det(np.dot(A, A.transpose()))
logdetA_Atranspose = math.log(detA_Atranspose + 1,2)
H = compute_entropy(A)
entropies.append(H)
dets.append(logdetA_Atranspose)
ax1 = fig.add_subplot(311)
ax1.plot(dets, entropies, 'ro')
plt.show()
However, there is something I don't know how to do.
In the code above, I need ax2 = fig.add_subplot(312)
ax2.plot(dets, entropies, 'ro') in the second iteration and ax3 = fig.add_subplot(313)
ax3.plot(dets, entropies, 'ro') in the third to create the three subfigures. How should I do that?
You can make use of plt.subplots and do something like:
fig, ax = plt.subplots(nrows = 3, ncols = 1)
hs = [2,8,2]
for p in xrange(3):
h = hs[p]
for i in xrange(N):
# skip other code
ax[p].plot(dets, entropies, 'ro')

Categories