如何绘制和注释分组的条

发布于 2025-02-12 15:15:39 字数 1127 浏览 0 评论 0 原文

我有以下代码

import numpy as np
import matplotlib.pyplot as plt

oct_data = [10, 24, 25, 30]
nov_data = [12, 42, 21, 78]

labels = ['Account_1', 'Account_2', 'Account_3', 'Account_4']
bar_width = 0.4

rect_1 = np.arange(0, len(oct_data)*2 ,2) 
rect_2 = [x + bar_width for x in rect_1]

plt.bar(rect_1, oct_data, color='#7f6d5f', width=bar_width, edgecolor='white', label='Month_1')
plt.bar(rect_2, nov_data, color='#557f2d', width=bar_width, edgecolor='white', label='Month_2')

plt.ylabel('Cost ($)', fontsize=10)

plt.legend()
plt.show()

给我以下数字:

如您所见Account_2,... )不集中。 据我了解,此命令应该完成这项工作,但事实并非如此。

plt.xticks([r + bar_width for r in range(0, len(oct_data)*2, 2)], labels)

我也想在酒吧内添加heigh的价值。通常,这就是我使用“单栏”图进行操作的方式:

  for i in range(len(labels)):
    plt.text(i, oct_data[i]//2, oct_data[i], ha = 'center', color = 'black')

但这在这里不起作用。

任何帮助将不胜感激。我是Matplotlib的总体初学者。

I have the following code

import numpy as np
import matplotlib.pyplot as plt

oct_data = [10, 24, 25, 30]
nov_data = [12, 42, 21, 78]

labels = ['Account_1', 'Account_2', 'Account_3', 'Account_4']
bar_width = 0.4

rect_1 = np.arange(0, len(oct_data)*2 ,2) 
rect_2 = [x + bar_width for x in rect_1]

plt.bar(rect_1, oct_data, color='#7f6d5f', width=bar_width, edgecolor='white', label='Month_1')
plt.bar(rect_2, nov_data, color='#557f2d', width=bar_width, edgecolor='white', label='Month_2')

plt.ylabel('Cost ($)', fontsize=10)

plt.legend()
plt.show()

Which gives me the following figure:
enter image description here

As you can see, my xticks (Account_1, Account_2, ...) are not centered.
As I understand, this command should do the job, but it doesn't.

plt.xticks([r + bar_width for r in range(0, len(oct_data)*2, 2)], labels)

I also would like to add the value of the heigh inside the bar. Usually, this is how I do it with a "single bar" graph:

  for i in range(len(labels)):
    plt.text(i, oct_data[i]//2, oct_data[i], ha = 'center', color = 'black')

But that does not work here.

Any help would be greatly appreciated. I am a total beginner with Matplotlib.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

醉生梦死 2025-02-19 15:15:39
import pandas as pd
import matplotlib.pyplot as plt

# create a dict with the data
data = {'October': oct_data, 'November': nov_data}

# create the dataframe with the labels as the index
df = pd.DataFrame(data, index=labels)

# display(df)
           October  November
Account_1       10        12
Account_2       24        42
Account_3       25        21
Account_4       30        78

# plot the dataframe
ax = df.plot(kind='bar', figsize=(10, 6), rot=0, ylabel='Cost ($)', color=['#7f6d5f', '#557f2d'])

# iterate through each group of container (bar) objects
for c in ax.containers:

    # annotate the container group
    ax.bar_label(c, label_type='center')

plt.show()

“在此处输入图像说明”

  • The easiest solution is to use pandas. This puts the data in an object which easily facilitates further analysis, and the plot API properly manages the spacing of grouped bars.
    • This implementation uses only 6 lines of code, compared to 18 lines.
  • Use pandas.DataFrame.plot, which uses matplotlib as the default plotting backend. Columns are plotted as the bar groups and the index is the independent axis.
  • From matplotlib 3.4.2, .bar_label should be used for annotations on bars.
  • See How to add value labels on a bar chart for addition information and examples about using .bar_label, and How to plot and annotate a grouped bar chart for an additional example of grouped bars.
  • Tested in python 3.9.7, pandas 1.3.4, matplotlib 3.4.3
import pandas as pd
import matplotlib.pyplot as plt

# create a dict with the data
data = {'October': oct_data, 'November': nov_data}

# create the dataframe with the labels as the index
df = pd.DataFrame(data, index=labels)

# display(df)
           October  November
Account_1       10        12
Account_2       24        42
Account_3       25        21
Account_4       30        78

# plot the dataframe
ax = df.plot(kind='bar', figsize=(10, 6), rot=0, ylabel='Cost ($)', color=['#7f6d5f', '#557f2d'])

# iterate through each group of container (bar) objects
for c in ax.containers:

    # annotate the container group
    ax.bar_label(c, label_type='center')

plt.show()

enter image description here

小清晰的声音 2025-02-19 15:15:39

Align 您可以使用:

# number of data points
num_data = len(labels)

bars1 = plt.bar(range(num_data), oct_data, color='#7f6d5f', 
                align='edge', width=-bar_width,    # align and negative width for left bars
                edgecolor='white', label='Month_1')
bars1 = plt.bar(range(num_data), nov_data, color='#557f2d', 
                align='edge', width=bar_width,     # align and positive width for right bars
                edgecolor='white', label='Month_2')

# set xticks
plt.xticks(range(num_data), labels)

为了注释,建议具有轴实例:

fig, ax = plt.subplots()
# other plot commands

for patch in ax.patches:
    ax.text(patch.get_x() + patch.get_width()/2,
            patch.get_height()/2,
            f'{patch.get_height()}',
            verticalalignment='center', horizontalalignment='center')

output:

”输入图像在此处描述“


更新:所有代码:

oct_data = [10, 24, 25, 30]
nov_data = [12, 42, 21, 78]

labels = ['Account_1', 'Account_2', 'Account_3', 'Account_4']
bar_width = 0.4

fig, ax = plt.subplots()

# number of data points
num_data = len(labels)

bars1 = plt.bar(range(num_data), oct_data, color='#7f6d5f', 
                align='edge', width=-bar_width,    # align and negative width for left bars
                edgecolor='white', label='Month_1')
bars1 = plt.bar(range(num_data), nov_data, color='#557f2d', 
                align='edge', width=bar_width,     # align and positive width for right bars
                edgecolor='white', label='Month_2')

for patch in ax.patches:
    ax.text(patch.get_x() + patch.get_width()/2,
            patch.get_height()/2,
            f'{patch.get_height()}',
            verticalalignment='center', horizontalalignment='center')

# set xticks
plt.xticks(range(num_data), labels)
plt.ylabel('Cost ($)', fontsize=10)

plt.legend()
plt.show()

There is align option you can use:

# number of data points
num_data = len(labels)

bars1 = plt.bar(range(num_data), oct_data, color='#7f6d5f', 
                align='edge', width=-bar_width,    # align and negative width for left bars
                edgecolor='white', label='Month_1')
bars1 = plt.bar(range(num_data), nov_data, color='#557f2d', 
                align='edge', width=bar_width,     # align and positive width for right bars
                edgecolor='white', label='Month_2')

# set xticks
plt.xticks(range(num_data), labels)

For annotation, it's recommend to have an axis instance:

fig, ax = plt.subplots()
# other plot commands

for patch in ax.patches:
    ax.text(patch.get_x() + patch.get_width()/2,
            patch.get_height()/2,
            f'{patch.get_height()}',
            verticalalignment='center', horizontalalignment='center')

Output:

enter image description here


Update: All code:

oct_data = [10, 24, 25, 30]
nov_data = [12, 42, 21, 78]

labels = ['Account_1', 'Account_2', 'Account_3', 'Account_4']
bar_width = 0.4

fig, ax = plt.subplots()

# number of data points
num_data = len(labels)

bars1 = plt.bar(range(num_data), oct_data, color='#7f6d5f', 
                align='edge', width=-bar_width,    # align and negative width for left bars
                edgecolor='white', label='Month_1')
bars1 = plt.bar(range(num_data), nov_data, color='#557f2d', 
                align='edge', width=bar_width,     # align and positive width for right bars
                edgecolor='white', label='Month_2')

for patch in ax.patches:
    ax.text(patch.get_x() + patch.get_width()/2,
            patch.get_height()/2,
            f'{patch.get_height()}',
            verticalalignment='center', horizontalalignment='center')

# set xticks
plt.xticks(range(num_data), labels)
plt.ylabel('Cost ($)', fontsize=10)

plt.legend()
plt.show()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文