Python matplotlib堆叠条形图(系列、数据和类别)

huangapple go评论69阅读模式
英文:

Python matplotlib dodged bar (series, data and category)

问题

以下是您要翻译的代码部分:

我有一系列数据和类别我将它们输入到一个函数中以使用matplotlib创建一个分组的柱状图

我已经成功创建了一个堆叠图但我想创建一个分组的柱状图

这是我已经成功创建的堆叠柱状图):
[![点击此处输入图像描述][1]][1]

这是我想要创建的分组的柱状图):
[![点击此处输入图像描述][2]][2]

#
# 文件:bar_dodged.py
# 版本 1
# 许可证:https://opensource.org/licenses/GPL-3.0 GNU通用许可证
#

import matplotlib.pyplot as plt
import numpy as np


def bar_dodged(series_labels: list = ['Minor', 'Low'],
        data: list = [
                [1, 2, 3, 4],
                [5, 6, 7, 8]
            ],
        category_labels: list = ['01/2023', '02/2023', '03/2023', '04/2023'],
        bar_background_colors: list = ['tab:orange', 'tab:green'],
        bar_text_colors: list = ['white', 'grey'],
        direction: str = "vertical",
        x_labels_rotation: int = 0,
        y_label: str = "Quantity (units)",
        figsize: tuple = (18, 5),
        reverse: bool = False,
        file_path: str = ".",
        file_name: str = "bar_dodged.png"):
    """
    :param series_labels:
    :param data:
    :param category_labels:
    :param bar_background_colors:
    :param bar_text_colors:
    :param direction:
    :param x_labels_rotation:
    :param y_label:
    :param figsize:
    :param reverse:
    :param file_path:
    :param file_name:
    :return:
    """
    # 调试
    print("\n")
    print(f"bar_dodged() :: series_labels={series_labels}")
    print(f"bar_dodged() :: data={data}")
    print(f"bar_dodged() :: category_labels={category_labels}")
    print(f"bar_dodged() :: bar_background_colors={bar_background_colors}")

    # 设置图形大小
    plt.figure(figsize=figsize)

    # 绘图
    show_values = True
    value_format = "{:.0f}"
    grid = False
    ny = len(data[0])
    ind = list(range(ny))

    axes = []
    cum_size = np.zeros(ny)

    data = np.array(data)

    if reverse:
        data = np.flip(data, axis=1)
        category_labels = reversed(category_labels)

    for i, row_data in enumerate(data):
        color = bar_background_colors[i] if bar_background_colors is not None else None
        axes.append(plt.bar(ind, row_data, bottom=cum_size,
                            label=series_labels[i], color=color))
        cum_size += row_data

    if category_labels:
        plt.xticks(ind, category_labels)

    if y_label:
        plt.ylabel(y_label)

    plt.legend()

    if grid:
        plt.grid()

    if show_values:
        for axis in axes:
            for bar in axis:
                w, h = bar.get_width(), bar.get_height()
                plt.text(bar.get_x() + w/2, bar.get_y() + h/2,
                         value_format.format(h), ha="center",
                         va="center")

    # 旋转X轴标签
    plt.xticks(rotation=x_labels_rotation)

    # 保存图像
    plt.savefig(f"{file_path}/{file_name}", bbox_inches='tight', dpi=200)


if __name__ == '__main__':
    # 用法示例:

    series_labels = ['Globally', 'Customer']
    data = [[9, 6, 5, 4, 8], [8, 5, 4, 3, 7]
    category_labels = ['Feb/2023', 'Dec/2022', 'Nov/2022', 'Oct/2022', 'Sep/2022']
    bar_background_colors = ['#800080', '#ffa503']

    bar_dodged(series_labels=series_labels, data=data, category_labels=category_labels,
               bar_background_colors=bar_background_colors)

请注意,这只是您代码的翻译版本,不包括其他任何内容。如果您需要更多帮助,请随时提问。

英文:

I have series, data and categories that I feed into a function to create a dodged bar using matplotlib.

I have managed to created a stacked chart, however I want to create a dodged bar.

This is what I have managed to create (stacked bar):
Python matplotlib堆叠条形图(系列、数据和类别)

This is what I want to create (dodged bar):
Python matplotlib堆叠条形图(系列、数据和类别)

#
# File: bar_dodged.py
# Version 1
# License: https://opensource.org/licenses/GPL-3.0 GNU Public License
#
import matplotlib.pyplot as plt
import numpy as np
def bar_dodged(series_labels: list = ['Minor', 'Low'],
data: list = [
[1, 2, 3, 4],
[5, 6, 7, 8]
],
category_labels: list = ['01/2023', '02/2023', '03/2023', '04/2023'],
bar_background_colors: list = ['tab:orange', 'tab:green'],
bar_text_colors: list = ['white', 'grey'],
direction: str = "vertical",
x_labels_rotation: int = 0,
y_label: str = "Quantity (units)",
figsize: tuple = (18, 5),
reverse: bool = False,
file_path: str = ".",
file_name: str = "bar_dodged.png"):
"""
:param series_labels:
:param data:
:param category_labels:
:param bar_background_colors:
:param bar_text_colors:
:param direction:
:param x_labels_rotation:
:param y_label:
:param figsize:
:param reverse:
:param file_path:
:param file_name:
:return:
"""
# Debugging
print(f"\n")
print(f"bar_dodged() :: series_labels={series_labels}")
print(f"bar_dodged() :: data={data}")
print(f"bar_dodged() :: category_labels={category_labels}")
print(f"bar_dodged() :: bar_background_colors={bar_background_colors}")
# Set size
plt.figure(figsize=figsize)
# Plot!
show_values = True
value_format = "{:.0f}"
grid = False
ny = len(data[0])
ind = list(range(ny))
axes = []
cum_size = np.zeros(ny)
data = np.array(data)
if reverse:
data = np.flip(data, axis=1)
category_labels = reversed(category_labels)
for i, row_data in enumerate(data):
color = bar_background_colors[i] if bar_background_colors is not None else None
axes.append(plt.bar(ind, row_data, bottom=cum_size,
label=series_labels[i], color=color))
cum_size += row_data
if category_labels:
plt.xticks(ind, category_labels)
if y_label:
plt.ylabel(y_label)
plt.legend()
if grid:
plt.grid()
if show_values:
for axis in axes:
for bar in axis:
w, h = bar.get_width(), bar.get_height()
plt.text(bar.get_x() + w/2, bar.get_y() + h/2,
value_format.format(h), ha="center",
va="center")
# Rotate
plt.xticks(rotation=x_labels_rotation)
# Two  lines to make our compiler able to draw:
plt.savefig(f"{file_path}/{file_name}", bbox_inches='tight', dpi=200)
if __name__ == '__main__':
# Usage example:
series_labels = ['Globally', 'Customer']
data = [[9, 6, 5, 4, 8], [8, 5, 4, 3, 7]]
category_labels = ['Feb/2023', 'Dec/2022', 'Nov/2022', 'Oct/2022', 'Sep/2022']
bar_background_colors = ['#800080', '#ffa503']
bar_dodged(series_labels=series_labels, data=data, category_labels=category_labels,
bar_background_colors=bar_background_colors)

What do I have to change in my code in order to make the chart dodged?

答案1

得分: 0

为了做到这一点,您只需更改在绘制条形图的for循环内的一行。将axes.append()更改为以下内容...

axes.append(plt.bar([element + 0.2*i for element in ind], 
                    row_data, width=0.2, #bottom=cum_size,
                    label=series_labels[i], color=color))

这将基本上将条形的x位置更改为0,1,2..(第一次运行时1=0),并在第二次运行时添加0.2。我保持了条形的宽度为0.2,使用width=0.2。如果您想要更宽的条形,可以进行更改。此外,我已删除了bottom,这意味着每个条形/矩形将从0开始。希望这是您正在寻找的内容...

图表

Python matplotlib堆叠条形图(系列、数据和类别)

英文:

To do that, you need to change just one line inside the for loop where you are drawing the bars. Change the axes.append() to below...

axes.append(plt.bar([element + 0.2*i for element in ind], 
row_data, width = 0.2, #bottom=cum_size,
label=series_labels[i], color=color))

This will basically change the x position of the bar to 0,1,2.. (for the first run when 1=0) and add 0.2 for the second run. That that I have kept the bar width as 0.2 using width = 0.2. YOu can change it if you want thicker bars. Also, I have removed the bottom, which means, each bar/rectangle will be starting at 0. Hope this is what you are looking for...

Plot

Python matplotlib堆叠条形图(系列、数据和类别)

huangapple
  • 本文由 发表于 2023年2月19日 18:11:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/75499365.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定