Python/Data Visualization with Python

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

DOVISH WISDOM 2022. 10. 22. 16:36  
728x90
반응형

오늘은 파이썬으로 y축 두 개를 가진 그래프를 그려볼게요.

그냥 하나의 y축을 가진 그래프는 쉽게 그릴 수 있어요.

왼쪽 y축을 ax_1으로 두고, 오른쪽 y축을 ax_2로 설정했습니다. 

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

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


ax_1 = sns.barplot()
plt.show()

더블 y축을 하는 방법은, plt.twinx()을 사용하면 됩니다. 

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

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

ax_1 = sns.barplot()

plt.twinx()
ax_2 = sns.lineplot()

plt.show()

이제 데이터를 가지고 그래프를 이쁘게 그려볼게요. 

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

# 그래프 설정 
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)" : [8.15, 4.04, 4.85, 35.38, 22.14, 23.16, 80, 30.38, 36.44, 135, 48.82, 62.88]
})

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)" : [200, 230, 140, 210, 240, 160, 240, 300, 220, 320, 400, 240]
})

# ax_1
ax_1 = sns.barplot(x = "Number of items encrypted", y = "Encryption time (Sec)", hue = "Algorithms", data = data_1,  palette = ["dimgrey", "lightgray", "darkgrey"])
ax_1.set_yticks([0, 10, 100])

# ax_2
ax_2 = plt.twinx()
ax_2 = sns.lineplot(x = "Number of items encrypted", y = "Queries time (Sec)", hue = "Algorithms", data = data_2,  ax = ax_2, style = "Algorithms", markers=True , markersize = 10,  palette = ["black", "silver", "grey"])
ax_2.set_yticks([100, 150, 200, 250, 300, 350, 400])


ax_1.set_xticklabels(['$2^{10}$', '$2^{11}$', '$2^{12}$', '$2^{13}$'], fontsize = 16)
ax_1.set_yticklabels(['$0$', '$10^{1}$','$10^{2}$'], fontsize = 16)
ax_1.set_yscale("log")
ax_2.set_yticklabels(['100', '150', '200', '250', '300', '350', '400'], fontsize = 16)

ax_1.set_xlabel("Number of items encrypted", fontsize = 16)
ax_1.set_ylabel("Encryption time (Sec)", fontsize = 16)
ax_2.set_ylabel("Queries time (Sec)", fontsize = 16)

plt.show()

 

일단 이렇게 완성해봤는데, ax_1을 그린 뒤 ax_2를 그려서 legend가 ax_2에 해당하는 내용밖에 없습니다. 

따라서 따로 legend를 그려줄게요. 

우선 위의 예제는 bar그래프line그래프로 그렸기 때문에, 아래 코드를 추가하여 legend를 따로 그릴 수 있도록 할게요. 

from matplotlib.lines import Line2D
from matplotlib.patches import Rectangle
ax_1.get_legend().remove()
ax_2.get_legend().remove()


ax_1.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.75, 1, 0), ncol = 1, fontsize = "small", title_fontsize = "medium")

ax_2.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, 0.75, 1, 0), ncol= 1,fontsize = "small", title_fontsize = "medium")

 

이렇게 barplot, lineplot에 대한 legend를 따로 만들어 넣어주었습니다. 

legend의 위치는 bbox_to_anchor을 조정하면 되는데 이는 따로 피드를 작성하도록 하겠습니다. 

 

아래는 사용한 전체 코드입니다.

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)" : [8.15, 4.04, 4.85, 35.38, 22.14, 23.16, 80, 30.38, 36.44, 135, 48.82, 62.88]
})

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)" : [200, 230, 140, 210, 240, 160, 240, 300, 220, 320, 400, 240]
})

# ax_1
ax_1 = sns.barplot(x = "Number of items encrypted", y = "Encryption time (Sec)", hue = "Algorithms", data = data_1,  palette = ["dimgrey", "lightgray", "darkgrey"])
ax_1.set_yticks([0, 10, 100])

# ax_2
ax_2 = plt.twinx()
ax_2 = sns.lineplot(x = "Number of items encrypted", y = "Queries time (Sec)", hue = "Algorithms", data = data_2,  ax = ax_2, style = "Algorithms", markers=True , markersize = 10,  palette = ["black", "silver", "grey"])
ax_2.set_yticks([100, 150, 200, 250, 300, 350, 400])


ax_1.set_xticklabels(['$2^{10}$', '$2^{11}$', '$2^{12}$', '$2^{13}$'], fontsize = 16)
ax_1.set_yticklabels(['$0$', '$10^{1}$','$10^{2}$'], fontsize = 16)
ax_1.set_yscale("log")
ax_2.set_yticklabels(['100', '150', '200', '250', '300', '350', '400'], fontsize = 16)

ax_1.set_xlabel("Number of items encrypted", fontsize = 16)
ax_1.set_ylabel("Encryption time (Sec)", fontsize = 16)
ax_2.set_ylabel("Queries time (Sec)", fontsize = 16)

ax_1.get_legend().remove()
ax_2.get_legend().remove()


ax_1.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.75, 1, 0), ncol = 1, fontsize = "small", title_fontsize = "medium")

ax_2.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, 0.75, 1, 0), ncol= 1,fontsize = "small", title_fontsize = "medium")

plt.show()
반응형