1. Anuncie Aqui ! Entre em contato fdantas@4each.com.br

[Python] Values over bars in barplot not centered

Discussão em 'Python' iniciado por Stack, Outubro 8, 2024.

  1. Stack

    Stack Membro Participativo

    I have the following code, which produces a plot, that plots two dictionaries next to each other, where the y-axis are the days and the y-axis the relative costs. Since the plot is pretty bloated, i want to add the values over each bar, ideally centered. Thus, I added the option ha='center' to my code, but somehow it produces a plot, where the rotated values are not truly centered above the bar. I want the middle of the rotated number centered over the bar. How can i achieve that?

    This is my code:

    import matplotlib.pyplot as plt
    import numpy as np
    import random

    def plot_relative_undercover_dual(ls1, ls2, demand_dict, days, shifts):
    list1, list2 = [], []

    for day in range(1, days + 1):
    daily_sum1 = sum(ls1.get((day, shift), 0) for shift in range(1, shifts + 1))
    daily_sum2 = sum(ls2.get((day, shift), 0) for shift in range(1, shifts + 1))
    daily_demand_sum = sum(demand_dict.get((day, shift), 0) for shift in range(1, shifts + 1))

    if daily_demand_sum > 0:
    relative1 = daily_sum1 / daily_demand_sum
    relative2 = daily_sum2 / daily_demand_sum
    else:
    relative1 = relative2 = 0

    list1.append(relative1)
    list2.append(relative2)

    plt.figure(figsize=(12, 6))

    x = np.arange(1, days + 1)
    width = 0.35

    colors = plt.cm.magma([0.8, 0.2])

    bars1 = plt.bar(x - width / 2, list1, width, color=colors[0], alpha=0.7, label='Option 1')
    bars2 = plt.bar(x + width / 2, list2, width, color=colors[1], alpha=0.7, label='Option 2')

    plt.xlabel('Days', fontsize=14.5, labelpad=15)
    plt.ylabel('Relative Costs', fontsize=14.5, labelpad=15)

    plt.grid(axis='y', linestyle='--', alpha=0.7)
    plt.xticks(x)

    def add_value_labels(bars):
    for bar in bars:
    height = bar.get_height()
    plt.text(bar.get_x() + bar.get_width() / 2., height + 0.01,
    f'{height:.2%}',
    ha='center', va='bottom', rotation=90, fontsize=10, color='black')

    add_value_labels(bars1)
    add_value_labels(bars2)

    # Find the maximum height of all bars
    max_height = max(max(bar.get_height() for bar in bars1), max(bar.get_height() for bar in bars2))

    # Add a margin above the highest bar for the labels and legend
    legend_margin = 0.15 * max_height
    plt.ylim(top=max_height + legend_margin)

    # Erstelle die Legende mit dünnerem Rahmen
    legend = plt.legend(loc='upper left', bbox_to_anchor=(0.02, 0.98), ncol=1, frameon=True, edgecolor='black', facecolor='white', framealpha=1, fontsize=14.5) # Set font size to match axis labels
    legend.get_frame().set_linewidth(0.5)

    plt.tight_layout()
    plt.show()


    def generate_random_data(days, shifts, min_value, max_value):
    return {(day, shift): round(random.uniform(min_value, max_value), 2) for day in range(1, days + 1) for shift in range(1, shifts + 1)}

    demand_dict, u1, u2 = generate_random_data(28, 3, 0, 105), generate_random_data(28, 3, 0, 100), generate_random_data(28, 3, 0, 100)

    plot_relative_undercover_dual(u1, u2, demand_dict, 28, 3)


    Here you can see the output and the problem more clearly: [​IMG]

    Continue reading...

Compartilhe esta Página