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.patchesadd_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 个标签传递给它们。我猜你混淆了dfAnimalRankingsnew_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(图文并茂版!!!)

poj3694 双连通分量+lca

申通快递 双11 云原生应用实践

Shopify:如何显示每个位置变体的库存数量?

一本通1131:基因相关性