简体   繁体   English

使用matplotlib为水平条形图创建替代的y轴标签

[英]Creating alternative y axis labels for a horizontal bar plot with matplotlib

This is a (clearer) repost of a question I just made, my deidentification was confusing people. 这是我刚才提出的问题的(更清楚的)转贴,我的身份识别令人困惑。

Hi, I'm new to graphing in python using matplotlib.pyplot and spent a good amount of time searching on this site and others, and trying to figure this out but I haven't succeeded in accomplishing what I'd like to do. 嗨,我是使用matplotlib.pyplot在python中进行图形绘制的新手,并花了很多时间在该站点和其他站点上进行搜索,并试图弄清楚这一点,但我没有成功完成我想做的事情。

Using the code below, I have generated the following graph, which is a collection of courses and the percent of those enrolled who went on to complete the course: What my code is creating: 使用下面的代码,我生成了以下图形,它是课程的集合以及完成课程的已注册人数的百分比:我的代码正在创建什么:

However, what I would like to generate with python is something like the following (crudely made in MS paint to convey to you all what I would like my code to generate): 但是,我想用python生成的内容类似于以下内容(用MS Paint精心制作,可以将您想要生成的所有代码传达给您):

What I want to create: 我要创建的内容:

The right hand side axis labels is the number of people who enrolled in each course, which is the additional information I would like featured. 右侧轴标签是每门课程的注册人数,这是我希望提供的其他信息。 An alternative solution is to have the enrollment numbers featured within the graph, written on/at the end of the bars. 另一种解决方案是在图表内的条形图的末尾写上注册号。 But whatever works is fine. 但是任何可行的方法都很好。

import matplotlib.pyplot as plt
y = ['Physics','Chemistry','Economics','Philosophy','Computer Science','Sociology','Biology','History','Overall']
x = [0.0,33.333333333333336,50.0,50.0,50.0,54.54545454545455,58.333333333333336,100.0,51.851851851851855]
alternativeYlabels = ['54', '1', '3', '12', '12', '2', '11', '12', '1']
plt.barh(y,x)
plt.title('Percent Completion Rate of Each Course')

plt.show()

How can I alter my code to fit my needs? 如何更改代码以满足我的需求? Also, how could I add vertical grid lines in my plot corresponding to each 20% in here as well? 另外,如何在图中也添加垂直网格线,分别对应于此处的20%?

Thanks 谢谢

Here are both the solutions: You need to add a twinx axis. 这两种解决方案都是:您需要添加一个twinx轴。 Add the following lines before your plt.show() . 在您的plt.show()之前添加以下行。 If you want to put the values on top the bars instead of the second y-axis on right hand side, you can have a look at this similar answer which I provided few weeks ago (I attached the code below as well along with the output). 如果你想要把值之上的酒吧,而不是在右边的第二y轴,你可以看看这个 ,我几个星期前,提供了类似的答案(我附上下面以及代码与输出一起)。

ax.xaxis.grid(True) # adding vertical grid lines
ax2 = ax.twinx() # Creating the right hand side y axis
ax_lim = ax.get_ylim()
ax2_lim = (ax_lim[0], ax_lim[1]) # Aligning the limits of both y axes
ax2.set_ylim(ax2_lim)
ax2.set_yticks(range(0, len(y)))
ax2.set_yticklabels(alternativeYlabels[::-1]) # Reverses the list
ax2.set_ylabel("# enrolled in each course",rotation = 270, labelpad=15)

Output 产量

在此处输入图片说明

Alternative desired output (see the link in the answer) EDIT: vertical alignment of text based on @ImportanceOfBeingErnest's suggestion 可选的期望输出 (请参见答案中的链接)编辑:基于@ImportanceOfBeingErnest的建议的文本垂直对齐

ax.xaxis.grid(True)
for i in range(len(x)):
    ax.text(x[i]+1, i, alternativeYlabels[::-1][i], color='black', fontweight='bold', va="center")

Output 产量

在此处输入图片说明

I adapted the code from this matplotlib example which has two separate scales on both sides of the plot. 我改编自 matplotlib示例的代码, 示例在绘图的两侧都有两个不同的比例。 The main difference is that here the second bar plot is a dummy one (each bar has a height of 0). 主要区别在于,此处的第二个条形图是一个虚拟的图(每个条形的高度为0)。 I think this is the easiest way to do it (without manually adding ticks etc.) 我认为这是最简单的方法(无需手动添加刻度线等)

# Initialize parameters as in your post
import matplotlib.pyplot as plt
y = ['Physics','Chemistry','Economics','Philosophy','Computer Science','Sociology','Biology','History','Overall']
x = [0.0,33.333333333333336,50.0,50.0,50.0,54.54545454545455,58.333333333333336,100.0,51.851851851851855]
alternativeYlabels = ['54', '1', '3', '12', '12', '2', '11', '12', '1']

# This time draw the bar plot from an 'axes' object
ax1 = plt.subplot(111)
ax1.barh(y,x)

# Draw a second 'dummy' barplot just to define the second ticks
ax2 = ax1.twinx()
ax2.barh(range(len(x)), [0]*len(x), tick_label=alternativeYlabels[::-1])  # don't forget to reverse the labels 

# Add the vertical grid
ax1.xaxis.grid(True)

# Add a title and show figure
plt.title('Percent Completion Rate of Each Course')
plt.show()

Running the code below should produce this figure: 运行下面的代码应该会产生此图:

双秤

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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