使用 Python 库绘制共享相同 y 轴的两个水平条形图 [英] Using Python libraries to plot two horizontal bar charts sharing same y axis

查看:50
本文介绍了使用 Python 库绘制共享相同 y 轴的两个水平条形图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想绘制共享相同 y 轴的两个水平条形图.例如,以下问题显示了如何在R中实现此目标:

I would like to plot two horizontal bar charts sharing same y axis. For example, the following question shows how to achieve this in R:

两个水平条ggplot2 中共享轴的图表(类似于人口金字塔)

如何使用Python创建类似的图?

How can I create a similar plot with Python?

上述问题的情节如下所示:

The plot from the question above looks like this:

以下是上图中使用的状态列表(y 轴):

Here is the list of states used in the graph above (the y axis):

["AK", "TX", "CA", "MT", "NM", "AZ", "NV", "CO", "OR", "WY", 
 "MI", "MN", "UT", "ID", "KS", "NE", "SD", "WA", "ND", "OK"]

以下是每个州的销售人员数量列表:

Here is the list of the numbers of sales staff for each state:

[20,30,40,10,15,35,18,25,22,7,12,22,3,4,5,8,14,28,24,32]

销售数字可以是随机的.

The sales figures can be random.

推荐答案

一般来说,如果您显示的两个变量单位不同或范围不同,您需要使用两个共享 y 轴的子图为了这.这与@regdoug 的回答类似,但最好明确共享 y 轴以确保您的数据保持对齐(例如,尝试使用此示例进行缩放/平移).

Generally speaking, if the two variables you're displaying are in different units or have different ranges, you'll want to use two subplots with shared y-axes for this. This is similar to what the answer by @regdoug does, but it's best to explicitly share the y-axis to ensure that your data stays aligned (e.g. try zooming/panning with this example).

例如:

import matplotlib.pyplot as plt

y = range(20)
x1 = range(20)
x2 = range(0, 200, 10)

fig, axes = plt.subplots(ncols=2, sharey=True)
axes[0].barh(y, x1, align='center', color='gray')
axes[1].barh(y, x2, align='center', color='gray')
axes[0].invert_xaxis()
plt.show()

如果您想更精确地重现您链接到的问题中显示的示例(我不使用灰色背景和白色网格,但如果您愿意,这些很容易添加):

If you want to more precisely reproduce the example shown in the question you linked to (I'm leaving off the gray background and white grids, but those are easy to add, if you prefer them):

import numpy as np
import matplotlib.pyplot as plt

# Data
states = ["AK", "TX", "CA", "MT", "NM", "AZ", "NV", "CO", "OR", "WY", "MI",
          "MN", "UT", "ID", "KS", "NE", "SD", "WA", "ND", "OK"]
staff = np.array([20, 30, 40, 10, 15, 35, 18, 25, 22, 7, 12, 22, 3, 4, 5, 8,
                  14, 28, 24, 32])
sales = staff * (20 + 10 * np.random.random(staff.size))

# Sort by number of sales staff
idx = staff.argsort()
states, staff, sales = [np.take(x, idx) for x in [states, staff, sales]]

y = np.arange(sales.size)

fig, axes = plt.subplots(ncols=2, sharey=True)
axes[0].barh(y, staff, align='center', color='gray', zorder=10)
axes[0].set(title='Number of sales staff')
axes[1].barh(y, sales, align='center', color='gray', zorder=10)
axes[1].set(title='Sales (x $1000)')

axes[0].invert_xaxis()
axes[0].set(yticks=y, yticklabels=states)
axes[0].yaxis.tick_right()

for ax in axes.flat:
    ax.margins(0.03)
    ax.grid(True)

fig.tight_layout()
fig.subplots_adjust(wspace=0.09)
plt.show()

一个警告.我实际上尚未正确对齐y-tick-labels.可以这样做,但这比您预期的要痛苦得多.因此,如果您真的希望 y-tick-labels 始终完美地居中在图形中间,则最容易以不同的方式绘制它们.代替 axes[0].set(yticks=y, yticklabels=states),您可以执行以下操作:

One caveat. I haven't actually aligned the y-tick-labels correctly. It is possible to do this, but it's more of a pain than you might expect. Therefore, if you really want y-tick-labels that are always perfectly centered in the middle of the figure, it's easiest to draw them a different way. Instead of axes[0].set(yticks=y, yticklabels=states), you'd do something like:

axes[0].set(yticks=y, yticklabels=[])
for yloc, state in zip(y, states):
    axes[0].annotate(state, (0.5, yloc), xycoords=('figure fraction', 'data'),
                     ha='center', va='center')

这篇关于使用 Python 库绘制共享相同 y 轴的两个水平条形图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆