Якчанд график дар як расм
Чаро якчанд графикро дар як расм мегузорем?
Дар ҳисобот аксар вақт чанд ҷанбаи маълумотро нишон додан лозим аст: тағйироти бузургӣ, тақсимоти он ва робитааш бо нишондиҳандаи дигар. Агар ҳама чизро дар як минтақа омезем, шкалаҳо ва номҳо ба ҳам халал мерасонанд. Якчанд минтақа дар як расм барои хондани паҳлу ба паҳлу ва нигоҳ доштани натиҷа дар як файл ёрӣ медиҳанд.
То ин дам функсияҳои plt.plot ва plt.title минтақаи ҷориро худашон интихоб мекарданд. Акнун ба минтақаи лозимӣ ошкоро муроҷиат мекунем. Ин кодро, махсусан дар даврҳо, пешгӯишаванда мекунад. Ҳар мисоли поён мустақил буда, баробари тасвир хосиятҳои расмро чоп мекунад.
1. Figure — варақ, Axes — минтақа
Figure тамоми расм аст: андоза, сарлавҳаи умумӣ ва маҷмӯи минтақаҳо. Axes як минтақаи график бо шкалаҳо, хатҳо ва номҳои худ аст. Сарфи назар аз ҳарфи охирини s, як объекти Axes як минтақаро ифода мекунад, на массивро. Як меҳвари алоҳидаи шкала Axis ном дорад.
plt.subplots() расм ва минтақаро сохта, онҳоро ҳамчун ҷуфт бармегардонад. Методҳои кашидани минтақа plot, bar, hist, scatter ном доранд; методҳои танзим одатан аз set_ оғоз мешаванд.
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.plot([0, 1], [3, 2])
ax.set_title("A")
ax.set_xlabel("x")
print(len(fig.axes))
print(ax.get_title(), ax.get_xlabel())
Натиҷа:
1
A x
fig.axes як минтақаро дар бар мегирад. ax методҳои set_title, set_xlabel, set_ylabel, set_xlim, set_ylim дорад. Масалан, ax.set_xlabel("x") танҳо минтақаи интихобшударо тағйир медиҳад, новобаста аз он ки pyplot кадом минтақаро ҷорӣ мешуморад.
2. Сатрҳо ва сутунҳои минтақаҳо
subplots(rows, columns) минтақаҳоро дар тӯри росткунҷа мегузорад. Барои тӯри дорои чанд сатр ва сутун axes массиви дученакаи numpy аст. Индексгузорӣ аз сифр сар мешавад: аввал сатр аз боло ба поён, баъд сутун аз чап ба рост.
import matplotlib.pyplot as plt
fig, axes = plt.subplots(2, 2)
axes[0, 0].plot([2, 4])
axes[0, 1].bar(["A", "B"], [3, 5])
axes[1, 0].hist([1, 2, 2], bins=2)
axes[1, 1].scatter([0, 1], [4, 2])
print(axes.shape)
print(len(fig.axes))
print(len(axes[0, 0].lines), len(axes[1, 1].collections))
Натиҷа:
(2, 2)
4
1 1
Дар сатри боло хат ва сутунҳо, дар поён гистограмма ва нуқтаҳо ҳастанд. Индекси [1, 0] минтақаи поёни чапро ифода мекунад. Ҳар даъват танҳо бо объекти интихобшуда кор мекунад, бинобар ин намудҳои графикро озодона якҷо кардан мумкин аст.
3. Чаро шакли axes тағйир меёбад?
Бо танзимоти пешфарз subplots андозаҳои массивро, ки дарозиашон як аст, мебардорад. Ин рафтор squeeze ном дорад. Агар як сатр бошад, массиви якченака ҳосил мешавад; агар танҳо як минтақа бошад, худи объекти Axes бармегардад.
import matplotlib.pyplot as plt
from matplotlib.axes import Axes
fig, axes = plt.subplots(1, 3)
print(axes.shape)
fig, ax = plt.subplots(1, 1)
print(isinstance(ax, Axes))
Натиҷа:
(3,)
True
Шакли (3,) се элементро дар як андоза ифода мекунад. Чунин тӯрро кушодан қулай аст: fig, (left, middle, right) = plt.subplots(1, 3). Барои чанд сатр ва як сутун низ массиви якченака ҳосил мешавад: axes[0], axes[1] ва ғайра.
Агар код бояд бо андозаҳои гуногуни тӯр яксон кор кунад, бо squeeze=False нигоҳ доштани ҳар ду андозаро дархост кунед. Хосияти flat имкон медиҳад, ки ҳамаи минтақаҳои массивро пайдарпай гузарем.
import matplotlib.pyplot as plt
fig, axes = plt.subplots(1, 2, squeeze=False)
for i, ax in enumerate(axes.flat):
ax.set_title(str(i))
print(axes.shape)
print([ax.get_title() for ax in axes.flat])
Натиҷа:
(1, 2)
['0', '1']
Шакл ҳамеша дученака аст: ҳатто барои як минтақа (1, 1) мешавад. Дар массиви дученака ба минтақа бо axes[row, column] ё axes[row][column] муроҷиат мекунанд. axes.flat тӯрро сатр ба сатр аз чап ба рост мегузарад.
4. Шкалаи умумӣ барои муқоиса
sharex=True меҳварҳои уфуқии минтақаҳоро мепайвандад, sharey=True амудиро. Ин вақте муфид аст, ки мавқеъ ё баландии якхела дар ҳамаи графикҳо бояд як бузургиро ифода кунад. Меҳварҳои пайвастшуда худи хатҳоро якҷо намекунанд.
import matplotlib.pyplot as plt
fig, axes = plt.subplots(2, 1, sharex=True)
axes[0].plot([2, 8], [1, 3])
axes[1].plot([2, 8], [5, 4])
axes[0].set_xlim(2, 8)
print(axes[0].get_xlim())
print(axes[1].get_xlim())
Натиҷа:
(2.0, 8.0)
(2.0, 8.0)
Тағйири ҳудудҳои минтақаи боло ба минтақаи поён низ таъсир кард. Ҳар яке қиматҳои y-и худро нигоҳ дошт. Барои меҳварҳои умумӣ matplotlib метавонад номҳои такрории аломатҳои шкаларо пинҳон кунад, то тӯр сербор нашавад.
5. Андоза, сарлавҳаи умумӣ ва нигоҳдорӣ
figsize=(width, height) андозаи тамоми варақро бо дюйм муайян мекунад. fig.suptitle сарлавҳаи умумӣ ва ax.set_title сарлавҳаи минтақаи алоҳидаро мегузорад. fig.tight_layout() фосилаҳои байни минтақаҳо ва номҳои онҳоро танзим мекунад.
Дар мисоли навбатӣ тасвир дар хотира, дар BytesIO, нигоҳ дошта мешавад, то андозаро бе сохтани файл санҷем. dpi шумораи пикселҳо дар як дюйм аст; ҳангоми нигоҳдорӣ бо сарҳадҳои одӣ паҳноӣ ва баландӣ бо пиксел ба андозаи дюймӣ зарб ба dpi баробар аст.
from io import BytesIO
import matplotlib.image as mpimg
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(5, 2))
ax.plot([0, 1], [3, 2])
fig.suptitle("Шарҳ")
fig.tight_layout()
buffer = BytesIO()
fig.savefig(buffer, format="png", dpi=100)
buffer.seek(0)
image = mpimg.imread(buffer)
print(fig.get_size_inches().tolist())
print(image.shape[:2])
Натиҷа:
[5.0, 2.0]
(200, 500)
Массиви тасвир аввал баландӣ ва баъд паҳноиро нигоҳ медорад: (200, 500) маънои 200 сатр ва 500 сутуни пикселҳоро дорад. Барои файли одӣ ба ҷойи buffer роҳ диҳед: fig.savefig("report.png", dpi=100). Параметри bbox_inches="tight" метавонад ҳошияҳоро бурад ва андозаи ниҳоиро бо пиксел тағйир диҳад.
Агар сарлавҳаи умумӣ ё номҳои дароз боз ҳам рӯйи ҳам оянд, андозаи расмро зиёд кунед ё бо fig.tight_layout(rect=(0, 0, 1, 0.9)) ҷойи иловагӣ монед. Роҳи дигар интихоби layout="constrained" ҳангоми сохтани расм аст; ин механизми алоҳидаи ҷойгиркунӣ мебошад ва онро бо tight_layout якҷо кардан лозим нест.
Дар дохил чӣ рӯй медиҳад?
Figure рӯйхати минтақаҳоро нигоҳ медорад ва ҳар Axes хатҳо, маҷмӯаҳои нуқтаҳо, росткунҷаҳо ва матнҳои худро дорад. subplots мавқеи минтақаҳоро дар тӯр ҳисоб карда, истинодҳои онҳоро бармегардонад. Массиви axes роҳи қулайи гирифтани истиноди зарурӣ аст, на худи тасвир.
Функсияҳои pyplot ба расм ва минтақаи ҷорӣ муроҷиат мекунанд: онҳоро бо plt.gcf() ва plt.gca() гирифтан мумкин аст. Методҳои ax объектро ошкоро интихоб мекунанд, бинобар ин аз ивази тасодуфии минтақаи ҷорӣ вобаста нестанд. Ҳангоми нигоҳдорӣ fig.savefig ҳамаи минтақаҳои ҳамин Figure-ро якҷо мекашад. Дар барномаҳои дароз расмҳои нолозимро бо plt.close(fig) пӯшида, захираҳоро озод мекунанд.
Хатоҳои маъмул ва ислоҳи онҳо
- Индексгузории минтақаи ягона. Пас аз
fig, axes = plt.subplots(1, 1)ифодаиaxes[0]хатоиTypeErrorмедиҳад. Ислоҳ: объектро мустақим истифода баред ё аз аввалsqueeze=Falseинтихоб карда, бо[0, 0]муроҷиат кунед. - Шумораи нодурусти индексҳо. Пас аз
plt.subplots(2, 2)ифодаиaxes[0].plot(...)ба массиви сатр муроҷиат карда,AttributeErrorмедиҳад. Ислоҳ: минтақаро бо ду индекс, масаланaxes[0, 1], интихоб кунед. - Сарлавҳа дар минтақаи тасодуфӣ.
plt.title("A")графики ҷориро тағйир медиҳад, ки метавонад дигар бошад. Ислоҳ: барои минтақаи интихобшудаax.set_title("A")ё барои тамоми расмfig.suptitle("A")истифода баред. - Пиксел ба ҷойи дюйм.
figsize=(500, 200)варақи азим месозад, на тасвири 500 × 200 пиксел. Ислоҳ: ҳангомиdpi=100азfigsize=(5, 2)истифода бурда, бо ҳамонdpiнигоҳ доред.
Ёддошт
| Амал | Навишт |
|---|---|
| Як минтақа | fig, ax = plt.subplots() |
| Тӯр | fig, axes = plt.subplots(rows, columns) |
| Ҳамеша массиви дученака | squeeze=False |
| Интихоб ва гузариш | axes[row, column], axes.flat |
| Танзими минтақа | ax.set_title(...), ax.set_xlabel(...) |
| Шкалаҳои умумӣ | sharex=True, sharey=True |
| Андоза ва сарлавҳаи умумӣ | figsize=(w, h), fig.suptitle(...) |
| Фосилаҳо ва файл | fig.tight_layout(), fig.savefig(...) |