'How to draw an image based on data stored on an array in Google Colab

I need to create something like this

enter image description here

in Google Colab. I have all the data on an array. First, I tried using matplotlib to create a horizontal bar chart. I made this based on the examples given on their documentation:

import matplotlib.pyplot as plt
import numpy as np

n = 4
bars1 = (20, 35, 30, 35)
bars2 = (25, 32, 34, 20)
ind = np.arange(n)    # the x locations for the groups

fig, ax = plt.subplots()

p1 = ax.barh(ind, bars1)
p2 = ax.barh(ind, bars2, left=bars1)

ax.set_ylabel('Bars')
ax.set_title('Divisions of each bars')

plt.yticks(ind)

# Label with label_type 'center' instead of the default 'edge'
ax.bar_label(p1, label_type='center')
ax.bar_label(p2, label_type='center')

plt.show()

and this is the result of this code

enter image description here

This looks good, but has a major limitation: I need to have the same number of intervals on every bar, which doesn't always happen on the first picture. Which library could I use to recreate something like this? I tried searching but I don't know exactly how to specify my problem.



Solution 1:[1]

The trick to getting a section to not appear is to add a value of np.nan, not float("nan"). So, using this data:

bars1 = (20, 35, 30, 35)
bars2 = (25, 32, 34, np.nan)

results in this graph:

new graph

Solution 2:[2]

I think you can achieve that with the code you already wrote.

  1. The first thing let's consider is that each bar needs to have an accumulated value = 100 (it can be any number) let's called MAX.

  2. Then for each bar, you calculate the actual value you have, and if it's less of our MAX, add the MAX - current value to your bar.

like that we will have all bars at MAX value.

but you will not have the exact same number of sections in each bar if one of those is already at MAX value. to fix that you will need to calculate the MAX value by finding the maximum value in your bars and add x value to it.

code :

import matplotlib.pyplot as plt
import numpy as np

def get_added_bar(bars):
    max = 0
    new_limit = 0
    added_val = 5
    vertic_sums = []
    added_bar = []
    for x in bars:
        t=0
        for item in x:
            if t > len(vertic_sums)-1:
                vertic_sums.append(item)
            else:   
                vertic_sums[t]  = vertic_sums[t]+item
            if vertic_sums[t] > max:
                max = vertic_sums[t]
            t=t+1
    new_limit = max + added_val
    t=0
    for x in vertic_sums:
        added_bar.append(new_limit-vertic_sums[t])
        t=t+1
    return tuple(added_bar)

def sum_bars(bars) : 
    vertic_sums = []
    for x in bars:
        t=0
        for item in x:
            if t > len(vertic_sums)-1:
                vertic_sums.append(item)
            else:   
                vertic_sums[t]  = vertic_sums[t]+item
            t=t+1
    return tuple(vertic_sums)

n = 4
# 0 for missing value
bars1 = (0, 35, 30, 35)
bars2 = (25, 32, 0, 20)
added_bar = get_added_bar((bars1,bars2)) #

ind = np.arange(n)    # the x locations for the groups

fig, ax = plt.subplots()

print((bars1,bars2,added_bar))

p1 = ax.barh(ind, bars1)
p2 = ax.barh(ind, bars2, left=bars1)
p3 = ax.barh(ind, added_bar, left=sum_bars((bars1,bars2)), color='white')

ax.set_ylabel('Bars')
ax.set_title('Divisions of each bars')

plt.yticks(ind)
print(ind)

# Label with label_type 'center' instead of the default 'edge'
ax.bar_label(p1, label_type='center')
ax.bar_label(p2, label_type='center')
# ax.bar_label(p3, label_type='center')

plt.show()

you can check, I created a working example here: https://replit.com/join/mgpidbnqfb-amirping

you can change any value in your bars with 0 if it's missing and you will still have it working

enter image description here

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 MattDMo
Solution 2