pythonmatplotlib

Issue with ticks in histogram plot using Matplotlib


I am generating a plot as shown below. However, the x-ticks are bit misplaced. I want them to start at 0.75 and end at 1.00 with each histogram of width 0.05.

ranges = [(0.75,0.8), (0.8, 0.85), (0.85, 0.9), (0.9, 0.95), (0.95, 1.00)]
    
    #ranges = [0.75, 0.8, 0.85,0.9,0.95,1.00]

    # Count the number of values in each range
    count_values_in_ranges = [sum(1 for value in result if start <= value <= end) for start, end in ranges]

    # Print the counts for each range
    for i, (start, end) in enumerate(ranges):
        # Find corresponding folder numbers within the valid range
        corresponding_folders = [
            folder_numbers[j] for j, value in enumerate(result) if j < len(folder_numbers) and start <= value <= end]

        print(f"Number of values in the range ({start}-{end}) for var={var}: {count_values_in_ranges[i]}")
        print(f"Corresponding folder numbers: {corresponding_folders}")

    # Increase the figure size and DPI for better resolution
    plt.figure(figsize=(10, 8), dpi=300)

    # Calculate the total count for normalization
    total_count = sum(count_values_in_ranges)

    # Adjust the width of the bars for better spacing
    bar_width = 0.05  # Adjust this value to control the width of the bars

    # Define different colors for each histogram
    colors = ['red', 'green', 'blue', 'orange', 'purple']

    # Plot each range as a separate bar with different colors
    for i, (start, end) in enumerate(ranges):
        plt.bar(0.75 + idx * (len(ranges) + 1) * bar_width + i * bar_width, count_values_in_ranges[i] / total_count * 100,
                alpha=0.7, width=bar_width, label=f'Range ({start}-{end})', color=colors[i])


    # Set x-axis ticks at the ends of each histogram
    # Manually set x-tick positions
    # Manually set x-tick positions
    tick_positions = np.linspace(0.7 + idx * (len(ranges) + 1) * bar_width, 1.00 + idx * (len(ranges) + 1) * bar_width, len(ranges) + 1)

# Set x-axis ticks at the center of each histogram
    plt.xticks(tick_positions[:-1] + bar_width / 2, [f"{value:.2f}" for value in np.arange(0.75, 1.00, 0.05)], rotation=0)

The current output is

enter image description here


Solution

  • I think the simplest way is to set the x-values passed to bar as the bottom of each of your ranges, and then set align='edge' so that each bar starts at the respective x-value.

    import matplotlib.pyplot as plt
    
    ranges = [(0.75,0.8), (0.8, 0.85), (0.85, 0.9), (0.9, 0.95), (0.95, 1.00)]
    colors = ['red', 'green', 'blue', 'orange', 'purple']
    
    x = [r[0] for r in ranges]
    y = [1, 8, 33, 52, 3]
    
    fig, ax = plt.subplots()
    
    ax.bar(x, y, width=0.05, align='edge', color=colors)
    
    plt.show()
    

    enter image description here