I’m trying to plot the data (see below). With company_name on the x-axis, status_mission_2_y on the y axis and percentage on the other y_axis. I have tried using the twinx() fucntion but I can’t get it to work.
Please can you help? Thanks in advance!
JavaScript
x
18
18
1
def twinplot(data):
2
x_ = data.columns[0]
3
y_ = data.columns[1]
4
y_2 = data.columns[2]
5
6
data1 = data[[x_, y_]]
7
data2 = data[[x_, y_2]]
8
plt.figure(figsize=(15, 8))
9
ax = sns.barplot(x=x_, y=y_, data=data1)
10
11
ax2 = ax.twinx()
12
g2 = sns.barplot(x=x_, y=y_2, data=data2, ax=ax2)
13
plt.show()
14
15
16
data = ten_company_missions_failed
17
twinplot(data)
18
company_name | percentage | status_mission_2_y |
---|---|---|
EER | 1 | 1 |
Ghot | 1 | 1 |
Trv | 1 | 1 |
Sandia | 1 | 1 |
Test | 1 | 1 |
US Navy | 0.823529412 | 17 |
Zed | 0.8 | 5 |
Gov | 0.75 | 4 |
Knight | 0.666666667 | 3 |
Had | 0.666666667 | 3 |
Advertisement
Answer
Seaborn plots the two bar plots with the same color and on the same x-positions.
The following example code resizes the bar widths, with the bars belonging ax
moved to the left. And the bars of ax2
moved to the right. To differentiate the right bars, a semi-transparency (alpha=0.7
) and hatching is used.
JavaScript
1
42
42
1
import matplotlib.pyplot as plt
2
from matplotlib.ticker import PercentFormatter
3
import pandas as pd
4
import seaborn as sns
5
from io import StringIO
6
7
data_str = '''company_name percentage status_mission_2_y
8
EER 1 1
9
Ghot 1 1
10
Trv 1 1
11
Sandia 1 1
12
Test 1 1
13
"US Navy" 0.823529412 17
14
Zed 0.8 5
15
Gov 0.75 4
16
Knight 0.666666667 3
17
Had 0.666666667 3'''
18
data = pd.read_csv(StringIO(data_str), delim_whitespace=True)
19
20
x_ = data.columns[0]
21
y_ = data.columns[1]
22
y_2 = data.columns[2]
23
24
data1 = data[[x_, y_]]
25
data2 = data[[x_, y_2]]
26
plt.figure(figsize=(15, 8))
27
ax = sns.barplot(x=x_, y=y_, data=data1)
28
width_scale = 0.45
29
for bar in ax.containers[0]:
30
bar.set_width(bar.get_width() * width_scale)
31
ax.yaxis.set_major_formatter(PercentFormatter(1))
32
33
ax2 = ax.twinx()
34
sns.barplot(x=x_, y=y_2, data=data2, alpha=0.7, hatch='xx', ax=ax2)
35
for bar in ax2.containers[0]:
36
x = bar.get_x()
37
w = bar.get_width()
38
bar.set_x(x + w * (1- width_scale))
39
bar.set_width(w * width_scale)
40
41
plt.show()
42
A simpler alternative could be to combine a barplot
on ax
and a lineplot
on ax2
.
JavaScript
1
9
1
plt.figure(figsize=(15, 8))
2
ax = sns.barplot(x=x_, y=y_, data=data1)
3
ax.yaxis.set_major_formatter(PercentFormatter(1))
4
5
ax2 = ax.twinx()
6
sns.lineplot(x=x_, y=y_2, data=data2, marker='o', color='crimson', lw=3, ax=ax2)
7
8
plt.show()
9