Search code examples
pythonmatplotlibpowerbiplotly-pythonpowerbi-custom-visuals

How can I make the following charts by using the given dataset in Python or PowerBI


I have some basic knowledge of Python and just started to study plotting with Python.

Here is a sample dataset I have:

Item StartPoint EndPoint Type Value
A 800 1000 1 10
A 700 815 2 20
A 850 900 2 40
A 900 990 2 30

The chart should looks like:

enter image description here

So, it reads the min[start point] and max[end point] to set the ymin and ymax.

Taking the first row as an example, it draws a line at y= 800 with a value 10 and draws another line at y = 1000, then fills the gap between those two lines based on the type (different types will be filled with different colors).

Another example, the second row draws a line at y = 700 with a value 20 and another line at y = 815, then it fills the gap between the two lines with a different color (because the type is different).

Is this something possible to do? Any help will be much appreciated! Thanks for all the kindness in advance.


Solution

  • Since you assured me that the overlap is desired, you may want to reduce the alpha value, so overlaps can be better seen. If this is not desired, remove the alpha option - in this case the standard value 1 will be used for the plotting. If the order is of importance, you can specify this in the order list and sort your df accordingly, so that the first entry in this list is plotted last:

    import matplotlib.pyplot as plt
    import pandas as pd
    
    df = pd.DataFrame({"StartPoint": [800, 700, 850, 900], 
                       "EndPoint": [1000, 815, 900, 990], 
                       "Type": [1, 2, 3, 2],
                       "Value": [10, 20, 40, 30]})
    
    color_dic = {1: "tab:red", 2: "tab:blue", 3: "tab:orange"}
    
    order = [1, 3, 2]
    df["order"] = pd.Categorical(df["Type"], order)
    df = df.sort_values("order", ascending=False)
    
    plt.bar(x=df.Value/2, height=df.EndPoint-df.StartPoint, width=df.Value, bottom=df.StartPoint, color=[color_dic[i] for i in df.Type], alpha=0.7)
    plt.gca().invert_yaxis()
    plt.show()
    

    Sample output:

    enter image description here