我认为同时具有相等的条形宽度(垂直方向上的宽度)和不同的子图大小的唯一方法实际上是手动在图中定位轴。
为此,您可以指定条形图的尺寸(以英寸为单位)以及子图之间要以此条形图宽度为单位的间距。根据这些数字以及要绘制的数据量,可以计算出总的图形高度(以英寸为单位)。然后fig.add_axes
根据数据量和先前子图中的间距(通过)定位每个子图。因此,您很好地填写了情节。添加一组新数据将使图变大。
data = [
{"name": "Category 1", "entries": [
{"name": "Entry 1", "value": 5},
{"name": "Entry 2", "value": 2},
]},
{"name": "Category 2", "entries": [
{"name": "Entry 1", "value": 1},
]},
{"name": "Category 3", "entries": [
{"name": "Entry 1", "value": 1},
{"name": "Entry 2", "value": 10},
{"name": "Entry 3", "value": 4},
]},
{"name": "Category 4", "entries": [
{"name": "Entry 1", "value": 6},
]},
]
import matplotlib.pyplot as plt
import numpy as np
def plot_data(data,
barwidth = 0.2, # inch per bar
spacing = 3, # spacing between subplots in units of barwidth
figx = 5, # figure width in inch
left = 4, # left margin in units of bar width
right=2): # right margin in units of bar width
tc = len(data) # "total_categories", holds how many charts to create
max_values = [] # holds the maximum number of bars to create
for category in data:
max_values.append( len(category["entries"]))
max_values = np.array(max_values)
# total figure height:
figy = ((np.sum(max_values)+tc) + (tc+1)*spacing)*barwidth #inch
fig = plt.figure(figsize=(figx,figy))
ax = None
for index, category in enumerate(data):
entries = []
values = []
for entry in category["entries"]:
entries.append(entry["name"])
values.append(entry["value"])
if not entries:
continue # do not create empty charts
y_ticks = range(1, len(entries) + 1)
# coordinates of new axes [left, bottom, width, height]
coord = [left*barwidth/figx,
1-barwidth*((index+1)*spacing+np.sum(max_values[:index+1])+index+1)/figy,
1-(left+right)*barwidth/figx,
(max_values[index]+1)*barwidth/figy ]
ax = fig.add_axes(coord, sharex=ax)
ax.barh(y_ticks, values)
ax.set_ylim(0, max_values[index] + 1) # limit the y axis for fixed height
ax.set_yticks(y_ticks)
ax.set_yticklabels(entries)
ax.invert_yaxis()
ax.set_title(category["name"], loc="left")
plot_data(data)
plt.savefig(__file__+".png")
plt.show()