如何使用python在matplotlib中使用水平条上的边而不扩展条形

xqk2d5yq  于 2023-03-19  发布在  Python
关注(0)|答案(1)|浏览(143)

背景:我正在开发一个基于matplotlib的python商业图表包(参见:受IBCS的启发,我想为水平条形图添加一个函数。
问题:在下面的例子中,条高0.65是相对于两个类别之间的间距而言的。线宽在我看来是一个绝对值,它被添加到条的周围(并使条高一点。当你制作一个大图时,你仍然可以看到不同条之间白色。当你制作一个小图时,条高和线宽完全相同。你会看到两条线之间白色消失了,你也看不到“第一条线”,它部分地在第二条线的后面。

import matplotlib.pyplot as plt

from random import *

linewidth = 2
barheight = 0.65

# create 10 y-coordinates, with budget slightly above actual
y_budget = [y+0.1*barheight for y in range(10)]
y_actual = [y-0.1*barheight for y in range(10)]

# create 10 random width-values for the length of the horizontal bars
width_budget = [randint(1,100) for w in range(10)]
width_actual = [randint(1,100) for w in range(10)]

# Make the "big" figure and the ax to plot on
fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(10, 6))
# first bar (white inside, dark grey border) will be mostly behind the second bar
ax.barh(y=y_budget, width=width_budget, color='#FFFFFF', height=barheight, linewidth=linewidth, edgecolor='#404040')
# second bar (dark grey inside, dark grey border) will be mostly behind the second bar
ax.barh(y=y_actual, width=width_actual, color='#404040', height=barheight, linewidth=linewidth, edgecolor='#404040')
# make category labels
ax.set_yticks(y_actual, ["category "+str(i+1) for i in range(10)]);

# Make the "small" figure and the ax to plot on
fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(10, 2))
# first bar (white inside, dark grey border) will be mostly behind the second bar
ax.barh(y=y_budget, width=width_budget, color='#FFFFFF', height=barheight, linewidth=linewidth, edgecolor='#404040')
# second bar (dark grey inside, dark grey border) will be mostly behind the second bar
ax.barh(y=y_actual, width=width_actual, color='#404040', height=barheight, linewidth=linewidth, edgecolor='#404040')

ax.set_yticks(y_actual, ["category "+str(i+1) for i in range(10)]);

我该怎么做才能使线宽在水平条的“内部”可见?或者我该如何根据图形的大小使线宽相对于水平条?你有什么建议?
Big figure with small figure below
我已经搜索了如何使线宽相对于图形大小的信息,但没有找到。我已经搜索了是否可以找到一个参数,使线宽位于条形图的“内部”,但没有找到。

f1tvaqid

f1tvaqid1#

我建议根据图形的高度来计算线宽。
假设您可以访问要在其上绘图的Figure对象,则可以调用fig.get_size_inches()来计算它的大小。
一旦你有了这些数据,你就可以除以类别的数量,得到每个条形图的垂直尺寸(这并不精确,因为它不包括图例所占的空间)。
由于线宽是以磅为单位表示的,因此需要将英寸乘以72才能得到磅。
接下来,这是一个条形的高度,它太大了,不能用作线宽。我将其乘以0.04629。我选择这个数字是因为我找到了一个数字,这个数字给了我第一个例子的最终线宽大约为2。
最终代码:

width, height = fig.get_size_inches()
linewidth = height / max(len(y_budget), 1) * 72 * 0.04629

注意:max(..., 1)用于避免在绘制零个类别时被零除。
由此生成的图:

相关问题