728x90
반응형
y축 중간 생략 그래프는 그래프를 그릴 때 각 항목들 간 데이터 크기 차이가 많이 날 때 쓰는 방식으로
이 방법을 사용하면, 완성된 그래프의 퀄리티도 좋아지고 확실히 눈에 잘 들어오게 됩니다.
아래 그래프는 같은 데이터를 사용하여 두 가지 버전의 그래프를 그린 결과입니다.
y축의 scale이 log 임에도 불구하고, A의 항목이 다른 항목에 비해 데이터 크기가 매우 크다는 걸 알 수 있습니다.
만약에 scale이 log가 아니라면, B와 C 항목은 보이지도 않습니다. ㅎㅎ
파이썬에서 y축 중간 생략 그래프를 그리기 위해선, subplot을 활용합니다.
즉, 두가지 그래프에 각각 그래프를 그려두고, 각 subplot의 ylim을 조정하면서 마치 중간그래프가 생략된 거처럼 만드는 거죠!
아래 코드에서는 subpot 1에 y축의 범위를 [95, 10000]로 두고, subplot 2에서는 y축의 범위를 [0, 0.1]로 둬서 중간 범위들이 결과 그래프 상에선 보이지 않게 되는 겁니다.
import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
# dataset
data = pd.DataFrame({
"Number of items encrypted" : ['2^10','2^10','2^10', '2^11','2^11','2^11','2^12', '2^12','2^12', '2^13', '2^13', '2^13'],
"Algorithms" : ["A", "B", "C", "A", "B", "C", "A","B", "C", "A","B", "C"],
"Encryption time (Sec)" : [150.15, 0.004, 0.005, 230.38, 0.014, 0.016, 900, 0.038, 0.044, 2812, 0.082, 0.088]
})
# setting figure
sns.set(rc={"figure.figsize":(8,6)})
plt.rcParams['lines.linewidth'] = 4.0
plt.rcParams['boxplot.flierprops.markersize'] = 10
sns.set_style("white")
# subplot
f, (ax1, ax2) = plt.subplots(ncols=1, nrows=2, sharex=True)
# making yaxis grid
ax1.yaxis.grid()
ax2.yaxis.grid()
#making barplot for each subplot ax1 and ax2
ax1 = sns.barplot(x = 'Number of items encrypted', y= "Encryption time (Sec)", hue = "Algorithms", data = data, palette = ["dimgrey", "lightgray", "darkgrey"], ax=ax1)
ax2 = sns.barplot(x = 'Number of items encrypted', y= "Encryption time (Sec)", hue = "Algorithms", data = data, palette = ["dimgrey", "lightgray", "darkgrey"], ax=ax2)
plt.xticks(size = 16)
plt.yticks(size = 16)
ax1.set_yscale("log")
ax2.set_yscale("log")
ax1.set_ylim(95, 10000)
ax2.set_ylim(0, 0.1)
ax1.set_yticks([100, 1000, 10000])
ax2.set_yticks([0.001, 0.01, 0.1])
ax1.set_ylabel("")
ax2.set_ylabel("")
ax1.spines['bottom'].set_visible(False)
ax2.spines['top'].set_visible(False)
f.text(0.02, 0.50, "Encryption time (sec)", va='center', rotation = 'vertical', fontsize = 16)
ax1.get_xaxis().set_visible(False)
ax1.get_legend().remove()
ax2.get_legend().remove()
labels = ax1.set_yticklabels(['$10^2$', '$10^3$', '$10^4$'], fontsize = 16)
labels = ax2.set_yticklabels(['$10^{-3}$','$10^{-2}$', '$10^{-1}$'], fontsize = 16)
# how big to make the diagonal lines in axes coordinates
d = .7
kwargs = dict(marker=[(-1, -d), (1, d)], markersize=15, linestyle="none", color='k', clip_on=False)
ax1.plot([0, 1], [0, 0], transform=ax1.transAxes, **kwargs)
ax2.plot([0, 1], [1, 1], transform=ax2.transAxes, **kwargs)
labels = ax2.set_xticklabels(['$2^{10}$', '$2^{11}$', '$2^{12}$', '$2^{13}$'], fontsize = "16")
ax1.set_xlabel("")
ax1.legend(title = "Encryption time", handles=[Rectangle((0,0), 0, 0, color = "dimgrey",alpha = 1, label="A algorithm"), Rectangle((0,0), 0, 0, color = "lightgray", alpha = 1, label="B algorithm"), Rectangle((0,0), 0, 0, color = "darkgrey", alpha = 1, label="C algorithm")], loc = "lower left", bbox_to_anchor=(0, 0.40, 1, 0), ncol = 1, fontsize = "medium", title_fontsize = "medium")
ax2.set_xlabel("Number of items encrypted", fontsize = "16")
plt.savefig("result.pdf")
과정을 더 자세히 살펴보면, 아래 코드를 실행시키면 빗금이 포함된 subplot 1, 2가 생성됩니다.
import pandas as pd
import matplotlib.pyplot as plt
f, (ax1, ax2) = plt.subplots(ncols=1, nrows=2, sharex=True)
d = .7 # how big to make the diagonal lines in axes coordinates
kwargs = dict(marker=[(-1, -d), (1, d)], markersize=15, linestyle="none", color='k', clip_on=False)
ax1.plot([0, 1], [0, 0], transform=ax1.transAxes, **kwargs)
ax2.plot([0, 1], [1, 1], transform=ax2.transAxes, **kwargs)
plt.show()
ax1 그래프의 x축 아래 선과 ax2 그래프의 x축 위 선을 안 보이도록 코드를 추가해줍니다.
ax1.spines['bottom'].set_visible(False)
ax2.spines['top'].set_visible(False)
너무 밋밋하니 y축에 grid를 넣어볼게요.
ax1.yaxis.grid()
ax2.yaxis.grid()
위에서 봤던 예제처럼, ylim을 조정하고 yticks을 설정해줍니다. 그럼 중간 생략 그래프 완성!
ax1.set_ylim(79, 100)
ax2.set_ylim(0, 20)
ax1.set_yticks([80, 85, 90, 95, 100])
ax2.set_yticks([0, 5, 10, 15, 20])
마지막은 저 빗금도 크기와 색, 스타일을 바꿀 수 있다는 걸 보여드리고 이번 피드는 마무리하겠습니다.
import pandas as pd
import matplotlib.pyplot as plt
f, (ax1, ax2) = plt.subplots(ncols=1, nrows=2, sharex=True)
d = .8 # how big to make the diagonal lines in axes coordinates
kwargs = dict(marker=[(-1, -d), (1, d)], markersize=30, linestyle="none", color='r', clip_on=False)
ax1.plot([0, 1], [0, 0], transform=ax1.transAxes, **kwargs)
ax2.plot([0, 1], [1, 1], transform=ax2.transAxes, **kwargs)
ax1.spines['bottom'].set_visible(False)
ax2.spines['top'].set_visible(False)
ax1.yaxis.grid()
ax2.yaxis.grid()
ax1.set_ylim(79, 100)
ax2.set_ylim(0, 20)
ax1.set_yticks([80, 85, 90, 95, 100])
ax2.set_yticks([0, 5, 10, 15, 20])
plt.show()
반응형
'Python > Data Visualization with Python' 카테고리의 다른 글
파이썬 Named colors in matplotlib - 공부하는 도비 (0) | 2023.05.30 |
---|---|
파이썬 y축 중간 생략(broken yaxis) + 더블 y축(twinx) 그래프 그리기 - 공부하는 도비 (1) | 2022.10.27 |
파이썬 더블 y축 그래프 그리기 (plt.twinx()) - 공부하는 도비 (0) | 2022.10.22 |