Python/Data Visualization with Python

파이썬 y축 중간 생략(broken yaxis) + 더블 y축(twinx) 그래프 그리기 - 공부하는 도비

DOVISH WISDOM 2022. 10. 27. 19:53  
728x90
반응형

지난 피드에서 파이썬 y축 중간 생략 그래프와 파이썬 더블 y축 그래프를 그려보았습니다.  각각 내용에 대해서는 아래 링크를 참고해주세요. 

오늘은 이 두 가지를 합친 그래프를 그려볼게요!.

 

 

2022.10.20 - [파이썬/파이썬 시각화 (colab)] - [파이썬 시각화] 파이썬 y축 중간 생략 그래프 그리기 - 공부하는 도비

 

[파이썬 시각화] 파이썬 y축 중간 생략 그래프 그리기 - 공부하는 도비

y축 중간 생략 그래프는 그래프를 그릴 때 각 항목들 간 데이터 크기 차이가 많이 날 때 쓰는 방식으로 이 방법을 사용하면, 완성된 그래프의 퀄리티도 좋아지고 확실히 눈에 잘 들어오게 됩니다

yang-wistory1009.tistory.com

2022.10.22 - [파이썬/파이썬 시각화 (colab)] - [파이썬 시각화] 파이썬 더블 y축 그래프 그리기 (plt.twinx()) - 공부하는 도비

 

[파이썬 시각화] 파이썬 더블 y축 그래프 그리기 (plt.twinx()) - 공부하는 도비

오늘은 파이썬으로 y축 두 개를 가진 그래프를 그려볼게요. 그냥 하나의 y축을 가진 그래프는 쉽게 그릴 수 있어요. 왼쪽 y축을 ax_1으로 두고, 오른쪽 y축을 ax_2로 설정했습니다. import pandas as pd imp

yang-wistory1009.tistory.com

 

y축 중간 생략 그래프를 그리기 위해선, subplot을 사용해야 하고

더블 y축을 그리기 위해선 plt.twinx()을 사용해야 합니다. 

 

다음 코드를 실행시켜 각 subplot에 더블 y축이 적용되도록 합니다. 

import pandas as pd
import matplotlib.pyplot as plt

figure, (ax1, ax2) = plt.subplots(ncols=1, nrows=2, sharex=True)

ax1.plot()
ax2.plot()

ax3 = ax1.twinx()
ax4 = ax2.twinx()

plt.show()

ax1과 ax2에 빗금을 추가시켜줍니다. 

import pandas as pd
import matplotlib.pyplot as plt

figure, (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)

ax3 = ax1.twinx()
ax4 = ax2.twinx()

plt.show()

중간 생략 그래프처럼 보이기 위해서, ax1, ax3 그래프의 아래쪽 줄을 제거하고, ax2, ax4 그래프의 위쪽 줄을 제거해줍니다. 

ax1.spines['bottom'].set_visible(False)
ax2.spines['top'].set_visible(False)

ax3.spines['bottom'].set_visible(False)
ax4.spines['top'].set_visible(False)

ax1 그래프의 x축 값을 제거해주지 않아서 중앙에 저런 표시가 생기는 걸 확인할 수 있습니다. 따라서, 저 값도 지워줄게요. 

ax1.get_xaxis().set_visible(False)

이제 조금 볼만해졌네요. 

 

 

그럼 예제를 통해서 그래프를 완성시켜볼게요.

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from matplotlib.lines import Line2D
from matplotlib.patches import Rectangle

# 그래프 설정 
sns.set(rc={"figure.figsize":(8,6)})
plt.rcParams['lines.linewidth'] = 4.0
plt.rcParams['boxplot.flierprops.markersize'] = 10
sns.set_style("white")

# 사용한 데이터 

data_1 = 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]
})


data_2 = 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"],
    "Queries time (Sec)" : [4.55, 1.55, 1.5, 47.7, 2.3, 2.4, 256.25, 4.3, 4.6, 961.77, 7.6, 8.8]
})

f, (ax1, ax2) = plt.subplots(ncols=1, nrows=2, sharex=True)

ax1.yaxis.grid()
ax2.yaxis.grid()

ax1 = sns.barplot(x = 'Number of items encrypted', y= "Encryption time (Sec)", hue = "Algorithms", data = data_1,  palette = ["dimgrey", "lightgray", "darkgrey"], ax=ax1)
ax2 = sns.barplot(x = 'Number of items encrypted', y= "Encryption time (Sec)", hue = "Algorithms", data = data_1,  palette = ["dimgrey", "lightgray", "darkgrey"], ax=ax2)


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("")


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)


ax1.spines['bottom'].set_visible(False)
ax2.spines['top'].set_visible(False)

ax1.get_xaxis().set_visible(False)

ax1.set_ylabel("")
ax2.set_ylabel("")

f.text(0.02, 0.50, "Total encryption time (sec)", va='center', rotation = 'vertical', fontsize = 16)

ax1.get_legend().remove()
ax2.get_legend().remove()

labels = ax1.set_yticklabels(['$10^2$', '$10^3$', '$10^4$'], fontsize = 14)
labels = ax2.set_yticklabels(['$10^{-3}$', '$10^{-2}$','$10^{-1}$'], fontsize = 14)
labels = ax2.set_xticklabels(['$2^{10}$', '$2^{11}$', '$2^{12}$', '$2^{13}$'], fontsize = 14)

# ax3, ax4
ax3 = ax1.twinx()
ax4 = ax2.twinx()

ax3 = sns.lineplot(x = "Number of items encrypted", y = "Queries time (Sec)", hue = "Algorithms", data = data_2, ax = ax3, style = "Algorithms", markers = True, markersize = 8, palette = ["black", "silver", "grey"])
ax4 = sns.lineplot(x = "Number of items encrypted", y = "Queries time (Sec)", hue = "Algorithms", data = data_2, ax = ax4, style = "Algorithms", markers = True, markersize = 8, palette = ["black", "silver", "grey"])

ax3.set_ylim(30, 1100)
ax4.set_ylim(0, 12)


ax3.spines['bottom'].set_visible(False)
ax4.spines['top'].set_visible(False)

ax3.get_legend().remove()
ax4.get_legend().remove()

ax3.lines[0].set_linestyle("solid")
ax4.lines[0].set_linestyle("solid")
ax4.lines[1].set_linestyle("dotted")
ax4.lines[2].set_linestyle("dashed")

ax3.set_ylabel("")
ax4.set_ylabel("")

ax3.set_yticks([50, 400, 750, 1100])
ax4.set_yticks([0, 5, 10, 15])

labels = ax2.set_xticklabels(['$2^{10}$', '$2^{11}$', '$2^{12}$', '$2^{13}$'], fontsize = "16")

labels = ax3.set_yticklabels(['$50$','$450$','$750$', '$1100$'], fontsize = 14)
labels = ax4.set_yticklabels(['$0$','$5$','$10$','$15$'], fontsize = 14)

f.text(0.97, 0.50, "Queries time (Sec)", va='center', rotation = 90, fontsize = 16)
ax2.set_xlabel("Number of items encrypted", fontsize = "16")

plt.show()

없앴던 legend를 추가로 그려줄게요. 

from matplotlib.lines import Line2D
from matplotlib.patches import Rectangle

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.5, 1, 0), ncol = 1, fontsize = "small", title_fontsize = "medium")
ax2.legend(title = "Queries time", handles = [ Line2D([], [], marker='o', color = "black" ,alpha = 1, label="A Algorithm"), Line2D([], [], marker='X', color = "silver", alpha = 1, label="B Algorithm"), Line2D([], [], marker='s', color = "grey", alpha = 1, label="C Algorithm")], loc = "lower left", bbox_to_anchor=(0.25, 1.7, 1, 0), ncol= 1,fontsize = "small", title_fontsize = "medium")

 

이렇게 2중 y 축이면서, y축 중앙 생략 그래프를 그려보았습니다.! 

반응형