FixedLocator 位置的数量 (11),通常来自对 set_ticks 的调用,与刻度标签的数量 (166) 不匹配 | Matplotlib [重复]
Posted
技术标签:
【中文标题】FixedLocator 位置的数量 (11),通常来自对 set_ticks 的调用,与刻度标签的数量 (166) 不匹配 | Matplotlib [重复]【英文标题】:The number of FixedLocator locations (11), usually from a call to set_ticks, does not match the number of ticklabels (166) | Matplotlib [duplicate] 【发布时间】:2021-11-13 11:38:49 【问题描述】:我之前发布了一个问题,但我的措辞将其标记为重复,因此我将对此问题非常具体。
这是 13 行数据,但我的 df 大约有 160 行:
Animal Score
0 Dog 1
1 Pig 2
2 Chicken 3
3 Cat 4
4 Fox 5
5 Whale 6
7 Beetle 7
8 Ox 8
9 Monkey 9
10 Cow 10
11 Duck 11
12 Hen 12
13 Crow 13
我正在尝试用值注释图表,但有一行代码在我身上出现问题,我无法弄清楚原因 - ax.set_xticklabels(x_labels)
我认为这是因为 concat 强制 11 行而不是完整的 160 行,但这里是代码:
#Add custom entries here
custom_df = dfAnimalRankings.loc[dfAnimalRankings['Animals'].isin(['Beetle'])]
# Create new df to show top 5, bottom 5, and Beetle
new_df = pd.concat([dfAnimalRankings[:5], dfAnimalRankings[-5:], custom_df])
new_df.sort_values(by=['Score'], inplace= True)
new_df.reset_index(drop=True, inplace= True)
# Plot the figure.
plt.figure(figsize=(12, 8))
ax = new_df.plot(kind='bar')
ax.set_title('Animal Rankings')
ax.set_xlabel('Animals')
ax.set_ylabel('Score')
ax.set_xticklabels(x_labels)
rects = ax.patches
def add_value_labels(ax, spacing=5):
"""Add labels to the end of each bar in a bar chart.
Arguments:
ax (matplotlib.axes.Axes): The matplotlib object containing the axes
of the plot to annotate.
spacing (int): The distance between the labels and the bars.
"""
# For each bar: Place a label
for rect in ax.patches:
# Get X and Y placement of label from rect.
y_value = rect.get_height()
x_value = rect.get_x() + rect.get_width() / 2
# Number of points between bar and label. Change to your liking.
space = spacing
# Vertical alignment for positive values
va = 'bottom'
# If value of bar is negative: Place label below bar
if y_value < 0:
# Invert space to place label below
space *= -1
# Vertically align label at top
va = 'top'
# Use Y value as label and format number with one decimal place
label = ":.1f".format(y_value)
# Create annotation
ax.annotate(
label, # Use `label` as label
(x_value, y_value), # Place label at end of the bar
xytext=(0, space), # Vertically shift label by `space`
textcoords="offset points", # Interpret `xytext` as offset in points
ha='center', # Horizontally center label
va=va) # Vertically align label differently for
# positive and negative values.
# Call the function above. All the magic happens there.
add_value_labels(ax)
plt.savefig("image.png")
如果我运行上面的代码,我会得到以下错误:
The number of FixedLocator locations (11), usually from a call to set_ticks, does not match the number of ticklabels (166).
但是如果我运行这段代码:
#Add custom entries here
custom_df = dfAnimalRankings.loc[dfAnimalRankings['Animals'].isin(['Beetle'])]
# Create new df to show top 5, bottom 5, and Beetle
new_df = pd.concat([dfAnimalRankings[:5], dfAnimalRankings[-5:], custom_df])
new_df.sort_values(by=['Score'], inplace= True)
new_df.reset_index(drop=True, inplace= True)
# Plot the figure.
plt.figure(figsize=(12, 8))
ax = new_df.plot(kind='bar')
ax.set_title('Animal Rankings')
ax.set_xlabel('Animals')
ax.set_ylabel('Score')
# ax.set_xticklabels(x_labels)
rects = ax.patches
def add_value_labels(ax, spacing=5):
"""Add labels to the end of each bar in a bar chart.
Arguments:
ax (matplotlib.axes.Axes): The matplotlib object containing the axes
of the plot to annotate.
spacing (int): The distance between the labels and the bars.
"""
# For each bar: Place a label
for rect in ax.patches:
# Get X and Y placement of label from rect.
y_value = rect.get_height()
x_value = rect.get_x() + rect.get_width() / 2
# Number of points between bar and label. Change to your liking.
space = spacing
# Vertical alignment for positive values
va = 'bottom'
# If value of bar is negative: Place label below bar
if y_value < 0:
# Invert space to place label below
space *= -1
# Vertically align label at top
va = 'top'
# Use Y value as label and format number with one decimal place
label = ":.1f".format(y_value)
# Create annotation
ax.annotate(
label, # Use `label` as label
(x_value, y_value), # Place label at end of the bar
xytext=(0, space), # Vertically shift label by `space`
textcoords="offset points", # Interpret `xytext` as offset in points
ha='center', # Horizontally center label
va=va) # Vertically align label differently for
# positive and negative values.
# Call the function above. All the magic happens there.
add_value_labels(ax)
plt.savefig("image.png")
我明白了(我知道数字不匹配,但它是我的实际数据集的输出,而不是上面的示例):
为什么那一行代码会破坏注解?以及如何将数据标签(动物名称而非数字)添加到图表中?
干杯
【问题讨论】:
我没有看到x_labels
在任何地方定义
好点,但是在运行时添加x_labels = dfAnimalRankings['Animals'].tolist() # Plot the figure. plt.figure(figsize=(12, 8)) ax = new_df.plot(kind='bar') ax.set_title('Animal Rankings') ax.set_xlabel('Animals') ax.set_ylabel('Score') ax.set_xticklabels(x_labels)
仍然会给我The number of FixedLocator locations (11), usually from a call to set_ticks, does not match the number of ticklabels (166).
,所以我无法确认它是否有效?
你为什么要这样做?确保您已更新为matplotlib v3.4.2
,删除您的整个功能并按照此answer 使用ax.bar_label(ax.containers[0], label_type='edge')
我删除了从 rects =ax.patches
到 add_value_labels(ax)
的所有内容,并将其替换为 ax.bar_label(ax.containers[0], label_type='edge')
并收到此错误消息 'AxesSubplot' object has no attribute 'bar_label'
编辑:我正在运行 3.3.4,这就是原因。
已更新,效果惊人 - 非常感谢您提供的超级简单提示!
【参考方案1】:
您收到错误的原因很清楚,您的情节只有 11 个条形图,但您将 166 个标签传递给它们。我猜你混淆了dfAnimalRankings
和new_df
,结果标签不匹配。
这里的解决方法是将x_labels
设置为
x_labels = new_df['Animals'].tolist()
这样一来,您将获得 11 个条形图的 11 个标签。
【讨论】:
以上是关于FixedLocator 位置的数量 (11),通常来自对 set_ticks 的调用,与刻度标签的数量 (166) 不匹配 | Matplotlib [重复]的主要内容,如果未能解决你的问题,请参考以下文章
解决警告:UserWarning: FixedFormatter should only be used together with FixedLocator(图文并茂版!!!)