简体   繁体   中英

Combining a grouped bar plot with a truncated line chart

I know how to create a grouped bar plot and I know how to create a line plot in matplotlib but unfortunately, I don't know how to combine both in a way that groups the line plots as well according to the bar groups, while preserving two axes. The following sketch (hopefully) illustrates what I try to achieve:

绘图草图

And this is what I have done so far:

import matplotlib
import matplotlib.pyplot as plt
import numpy as np

labels = ['G1', 'G2', 'G3', 'G4', 'G5']
men_means = [20, 34, 30, 35, 27]
women_means = [25, 32, 34, 20, 25]

YearGroup1 = ['G11','G12']
Unemployment_RateGroup1 = [31,32]

x = np.arange(len(labels))  # the label locations
width = 0.35  # the width of the bars

fig, ax = plt.subplots()
rects1 = ax.bar(x - width/2, men_means, width, label='Men')
rects2 = ax.bar(x + width/2, women_means, width, label='Women')

# Add some text for labels, title and custom x-axis tick labels, etc.
ax.set_ylabel('Scores')
ax.set_title('Scores by group and gender')
ax.set_xticks(x)
ax.set_xticklabels(labels)
ax.legend()

def autolabel(rects):
    """Attach a text label above each bar in *rects*, displaying its height."""
    for rect in rects:
        height = rect.get_height()
        ax.annotate('{}'.format(height),
                    xy=(rect.get_x() + rect.get_width() / 2, height),
                    xytext=(0, 3),  # 3 points vertical offset
                    textcoords="offset points",
                    ha='center', va='bottom')

autolabel(rects1)
autolabel(rects2)

fig.tight_layout()

plt.plot(YearGroup1, Unemployment_RateGroup1)
plt.show()

However, I don't know how to reposition the x-positions of the line chart manually. The lines are supposed to be within groups and should be on the second y-axis.

The whole plot aims to show results for different algorithms (X_1,X_2,X_3,...) on different data types (red bar, green bar, blue bar). The grouped line charts on the second y-axis should represent the time needed for each algorithm.

Any help is highly appreciated.

Assuming the line plot is supposed to display within group data, you can plot it like this:

import matplotlib
import matplotlib.pyplot as plt
import numpy as np

labels = ['G1', 'G2', 'G3', 'G4', 'G5']
men_means = [20, 34, 30, 35, 27]
women_means = [25, 32, 34, 20, 25]

YearGroup1 = ['G11','G12']
Unemployment_RateGroup1 = [31,32]

x = np.arange(len(labels))  # the label locations
width = 0.35  # the width of the bars

fig, ax = plt.subplots()
ax2 = ax.twinx()  # <--- make a second y-axis
rects1 = ax.bar(x - width/2, men_means, width, label='Men')
rects2 = ax.bar(x + width/2, women_means, width, label='Women')

# Add some text for labels, title and custom x-axis tick labels, etc.
ax.set_ylabel('Scores')
ax.set_title('Scores by group and gender')
ax.set_xticks(x)
ax.set_xticklabels(labels)
ax.legend()

def autolabel(rects):
    """Attach a text label above each bar in *rects*, displaying its height."""
    for rect in rects:
        height = rect.get_height()
        ax.annotate('{}'.format(height),
                    xy=(rect.get_x() + rect.get_width() / 2, height),
                    xytext=(0, 3),  # 3 points vertical offset
                    textcoords="offset points",
                    ha='center', va='bottom')

autolabel(rects1)
autolabel(rects2)

# plot lines    
for i in range(len(labels)):
    ax2.plot(
        [x[i] - width / 2, x[i] + width / 2], 
        Unemployment_RateGroup1, 
        color='C3', marker='+', mec='k'
    )

fig.tight_layout()

Please mind that I dropped plt.show() . If you require this line, don't forget to add it.

If you have separate data of Unemployment_Rate for each group, fi

Unemployment_Rate = [[31, 32], [7, 12], [23, 9], [0, 1], [32, 0]]

you can replace the line plotting with:

ax2.plot(
    [x[i] - width / 2, x[i] + width / 2], 
    Unemployment_Rate[i], 
    color='C3', marker='+', mec='k'
)

which will yield: 条形图和组内线

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM