Matplotlib:如何指定x标签边界框的宽度

我想在MatPlotLib中创建一个堆叠的条形图,顶部和底部有两个不同的x标签。上面的那个应该有一个与条形本身宽度相同的边界框。Matplotlib:如何指定x标签边界框的宽度

情节这并不完全正确

这是我如何创建标签:

plt.tick_params(axis="both", left=False, bottom=False, labelleft=False) 

plt.xticks(ind, diagram.keys())

ax.set_frame_on(False)

for label, x in zip([q[1] for q in diagram.values()], ind):

ax.text(

x, 1.05, '{:4.0%}'.format(label),

ha="center", va="center",

bbox={"facecolor": "blue", "pad": 3}

)

diagram就像{bottom-label: [[contents], top-label]}

字典所以我想我的问题归结到:如何操纵t的边界框ext对象?

非常感谢!

根据要求,可运行例如:

import matplotlib.pyplot as plt 

import numpy as np

def stacked_bar_chart(

diagram, title="example question", img_name="test_image", width=0.7, clusters=None, show_axes=True,

show_legend=True, show_score=True):

"""

Builds one or multiple scaled stacked bar charts for grade

distributions. saves image as png.

:param show_score: whether the score should be shown on top

:param show_legend: whether the legend should be shown

:param show_axes: whether question name should be shown on bottom

:param clusters: indices of clusters to be displayed.

:param width: the width of the bars as fraction of available space

:param title: diagram title

:param img_name: output path

:param diagram: dictionary: {x-label: [[grade distribution], score]}

:return: nothing.

"""

grades = {

"sehr gut": "#357100",

"gut": "#7fb96a",

"befriedigend": "#fdd902",

"ausreichend": "#f18d04",

"mangelhaft": "#e3540e",

"ungenügend": "#882d23"

}

# select clusters

if clusters is not None:

diagram = {i: diagram[i] for i in clusters}

# normalize score distribution => sum of votes = 1.0

normalized = []

for question in diagram.values():

s = sum(question[0])

normalized.append([x/s for x in question[0]])

# transpose dict values (score distributions) to list of lists

transformed = list(map(list, zip(*normalized)))

# input values for diagram generation

n = len(diagram) # number of columns

ind = np.arange(n) # x values for bar center

base = [0] * n # lower bounds for individual color set

bars = []

fig, ax = plt.subplots()

# loop over grades

for name, grade in zip(grades.keys(), transformed):

assert len(grade) == n, \

"something went wrong in plotting grade stack " + img_name

bar = plt.bar(ind, grade, width=width, color=grades[name], bottom=base)

bars.append(bar)

# loop over bars

for i, (rect, score) in enumerate(zip(bar, grade)):

# update lower bound for next bar section

base[i] += grade[i]

# label with percentage

# TODO text color white

ax.text(

rect.get_x() + width/2, rect.get_height()/2 + rect.get_y(), "{0:.0f}%".format(score * 100),

va="center", ha="center")

# label diagram

plt.suptitle(title)

if show_axes:

plt.tick_params(axis="both", left=False, bottom=False, labelleft=False)

plt.xticks(ind, diagram.keys())

ax.set_frame_on(False)

else:

plt.tick_params(axis="both", left=False, bottom=False, labelleft=False, labelbottom=False)

plt.axis("off")

# show score label above

if show_score:

for label, x in zip([q[1] for q in diagram.values()], ind):

ax.text(

x, 1.05, '{:4.0%}'.format(label),

ha="center", va="center",

bbox={"facecolor": "blue", "pad": 3}

)

# create legend

if show_legend:

plt.legend(

reversed(bars), reversed([*grades]),

bbox_to_anchor=(1, 1), borderaxespad=0)

# save file

plt.show()

diagram = {

"q1": [[1, 2, 3, 4, 5, 6], 0.6],

"q2": [[2, 3, 1, 2, 3, 1], 0.4]

}

stacked_bar_chart(diagram)

回答:

对于参数为什么一个文本框的宽度设置为定义的宽度是难以看到this question这大约是设置标题文本框宽度。原则上,这里的答案也可以用在这里 - 这使得它变得相当复杂。

一个相对简单的解决方案是指定文本在数据坐标中的x位置和其在坐标轴中的y位置。这允许为具有相同坐标的文本创建矩形作为背景,使得它看起来像文本的边界框。

import matplotlib.pyplot as plt 

import numpy as np

ind = [1,2,4,5]

data = [4,5,6,4]

perc = np.array(data)/float(np.array(data).sum())

width=0.7

pad = 3 # points

fig, ax = plt.subplots()

bar = ax.bar(ind, data, width=width)

fig.canvas.draw()

for label, x in zip(perc, ind):

text = ax.text(

x, 1.00, '{:4.0%}'.format(label),

ha="center", va="center" , transform=ax.get_xaxis_transform(), zorder=4)

bb= ax.get_window_extent()

h = bb.height/fig.dpi

height = ((text.get_size()+2*pad)/72.)/h

rect = plt.Rectangle((x-width/2.,1.00-height/2.), width=width, height=height,

transform=ax.get_xaxis_transform(), zorder=3,

fill=True, facecolor="lightblue", clip_on=False)

ax.add_patch(rect)

plt.show()

以上是 Matplotlib:如何指定x标签边界框的宽度 的全部内容, 来源链接: utcz.com/qa/257786.html

回到顶部