Как установить разные интервалы между подзаголовками в pyplot?

#python #matplotlib

#python #matplotlib

Вопрос:

Я хочу уменьшить интервал между первым и вторым подзаголовками и увеличить интервал между вторым и третьим подзаголовками. Что мне делать?

Три подзаголовка

 import numpy as np
import matplotlib.pyplot as plt


plt.figure(figsize=(10, 5))
a = np.random.random((100, 100, 3))
b = np.random.random((100, 100, 3))
grid = plt.GridSpec(2, 3, wspace=0.3, hspace=0.2, height_ratios=[1,1],width_ratios=[1,1,1.8])


plt.subplot(grid[0, 0])
plt.axis('off')
plt.imshow(a)

plt.subplot(grid[0, 1])
plt.axis('off')
plt.imshow(a)

plt.subplot(grid[0, 2])
b = b.reshape((100 * 100 * 3))
plt.hist(b, bins=30, range=(0, 1))


# plt.tight_layout()

plt.show()
  

Комментарии:

1. вы можете добавить оси вручную ( Figure.add_axes )

Ответ №1:

Хотя это и не сложный подход, почему бы не минимизировать интервал и не сдвинуть ось y вправо?

 import numpy as np
import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec

plt.figure(figsize=(10, 5))
a = np.random.random((100, 100, 3))
b = np.random.random((100, 100, 3))
grid = plt.GridSpec(2, 3, wspace=0.2, hspace=0.2, height_ratios=[1,1],width_ratios=[1,1,1.8])


plt.subplot(grid[0, 0])
plt.axis('off')
plt.imshow(a)

plt.subplot(grid[0, 1])
plt.axis('off')
plt.imshow(a)

ax = plt.subplot(grid[0, 2])
b = b.reshape((100 * 100 * 3))
plt.hist(b, bins=30, range=(0, 1))
ax.yaxis.tick_right()

# plt.tight_layout()

plt.show()
  

введите описание изображения здесь

Ответ №2:

Прежде всего, я бы посоветовал вам начать сохранять как созданную фигуру, так и оси как надлежащие объекты, чтобы вы могли ссылаться на них позже. Я лично предпочитаю помещать подзаголовки в специальный ax={} словарь для последующего использования (подумайте о том, как легко вы могли бы, например, добавлять метки ко всем подзаголовкам в простом for a in ax.items(): цикле).

В любом случае, главное здесь — получить Bbox (см. Документацию для Bbox здесь ) рассматриваемого подзаголовка (используя .get_position() ), а затем присвоить ему новый Bbox (используя .set_position() ) с обновленным массивом :

 import matplotlib.pyplot as plt
import numpy as np
from matplotlib.transforms import Bbox

fig = plt.figure(figsize=(10, 5))
grid = plt.GridSpec(2, 3, wspace=0.3, hspace=0.2, height_ratios=[1,1],width_ratios=[1,1,1.8])
ax = {}
ax[0] = fig.add_subplot(grid[0,0])
ax[1] = fig.add_subplot(grid[0,1])
ax[2] = fig.add_subplot(grid[0,2])

a = np.random.random((100, 100, 3))
b = np.random.random((100, 100, 3))

ax[0].axis('off')
ax[0].imshow(a)

old_bb=Bbox(grid[0,1].get_position(fig))
x0,y0,x1,y1 = old_bb.extents

# to debug and see what the Bbox is before changing it
print(x0,y0,x1,y1) 
# we move the x0 anchor by 0.1 to the left:
new_bb=Bbox(np.array([[x0-0.1,y0],[x1,y1]]))
ax[1].set_position(new_bb)
# to debug and see what's going on afterwards
print(ax[1].get_position()) 

ax[1].axis('off')
ax[1].imshow(a)

b = b.reshape((100 * 100 * 3))
ax[2].hist(b, bins=30, range=(0, 1))

plt.show()
  

Ответ №3:

Еще одна мысль, преимущество которой, возможно, заключается в том, что она вносит лишь незначительную корректировку в ваш исходный код.

Установив ncols=4 и поместив гистограмму в четвертый столбец, вы можете использовать незанятый третий столбец в качестве пустого пространства и задать его относительную ширину с помощью переменной spacerWidth . Просто помните, что при изменении вам, spacerWidth вероятно figsize , придется также отрегулировать, чтобы сохранить соотношение сторон.

 import numpy as np
import matplotlib.pyplot as plt

#For each new value of spacerWidth variable below, adjust figsize to desired aspect ratio
plt.figure(figsize=(15, 3))

a = np.random.random((100, 100, 3))
b = np.random.random((100, 100, 3))

#Set spacerWidth to your desired gap size, and adjust figsize (above) to maintain aspect ratio
spacerWidth = 0.6
grid = plt.GridSpec(1, 4, width_ratios=[1,1,spacerWidth,1.8])

plt.subplot(grid[0, 0])
plt.axis('off')
plt.imshow(a)

plt.subplot(grid[0, 1])
plt.axis('off')
plt.imshow(a)

#The histogram is now in the column with index 3, because our spacer occupies index 2
plt.subplot(grid[0, 3])
b = b.reshape((100 * 100 * 3))
plt.hist(b, bins=30, range=(0, 1))

#Omitting tight_layout() seems to result in better results for this method 
#plt.tight_layout()

plt.show()