Monday 12 July 2021

Data value of a variable in each marker within subplots

I'm developing the following function: extract_name_value() that generates a step chart taking the values of a pandas DataFrame in Python, for now it works fine, but I want to add the values of the variable points_axisyvalue or values_list to it in each marker:

    import xml.etree.ElementTree as ET
    import pandas as pd
    import numpy as np
    from matplotlib import pyplot as plt
    
    file_xml = ET.parse('example.xml')
    rootXML = file_xml.getroot()
    
    def transfor_data_atri(rootXML):
        file_xml = ET.parse(rootXML)
        data_XML = [
            {"Name": signal.attrib["Name"],
             "Value": int(signal.attrib["Value"].split(' ')[0])
             } for signal in file_xml.findall(".//Signal")
        ]
        
        signals_df = pd.DataFrame(data_XML)
        extract_name_value(signals_df)

    # Function to extract the Name and Value attributes
    def extract_name_value(signals_df, rootXML):
        # print(signals_df)
        names_list = [name for name in signals_df['Name'].unique()]
        num_names_list = len(names_list)
        num_axisx = len(signals_df["Name"])
        ### Variable that contains the values that I want to paint in each point or coordinate of the graph
        points_axisyvalue = signals_df["Value"]
        print(points_axisyvalue)

        colors = ['b', 'g', 'r', 'c', 'm', 'y']

        # Creation Graphic
        fig, ax = plt.subplots(nrows=num_names_list, figsize=(20, 30), sharex=True)
        plt.suptitle(f'File XML: {rootXML}', fontsize=16, fontweight='bold', color='SteelBlue', position=(0.75, 0.95))
        plt.xticks(np.arange(0, num_axisx), color='SteelBlue', fontweight='bold')
        i = 1
        for pos, name in enumerate(names_list):
            # get data
            data = signals_df[signals_df["Name"] == name]["Value"]
            # get color
            j = random.randint(0, len(colors) - 1)
            # get plots by index = pos
            ax[pos].plot(data.index, data, drawstyle='steps-post', marker='o', color=colors[j], linewidth=3)
            ax[pos].set_ylabel(name, fontsize=8, fontweight='bold', color='SteelBlue', rotation=30, labelpad=35)
            ax[pos].yaxis.set_major_formatter(ticker.FormatStrFormatter('%0.1f'))
            ax[pos].yaxis.set_tick_params(labelsize=6)
            ax[pos].grid(alpha=0.4)
            i += 1
    plt.show()

I tried to use the following examples:Data value at each marker, Matplotlib scatter plot with different text at each data point or How to put individual tags for a matplotlib scatter plot?, which would be something like what I want; also I even tried using plt.annotate(), but the data of the values does not come out the way I want it, plus I think it would cover up the graph a lot and not appreciate well. Below I put the code in which I'm using plt.annotate():

    # Function to extract the Name and Value attributes
    def extract_name_value(signals_df, rootXML):
        # print(signals_df)
        names_list = [name for name in signals_df['Name'].unique()]
        num_names_list = len(names_list)
        num_axisx = len(signals_df["Name"])
        values_list = [value for pos, value in enumerate(signals_df["Value"])]
        print(values_list)
        points_axisy = signals_df["Value"]
        print(len(points_axisy))

        colors = ['b', 'g', 'r', 'c', 'm', 'y']
    
        # Creation Graphic
        fig, ax = plt.subplots(nrows=num_names_list, figsize=(20, 30), sharex=True)
        plt.suptitle(f'File XML: {rootXML}', fontsize=16,         fontweight='bold', color='SteelBlue', position=(0.75, 0.95))
        plt.xticks(np.arange(-1, num_axisx), color='SteelBlue', fontweight='bold')
        labels = ['value: {0}'.format(j) for j in values_list]
        print(labels)
        i = 1
        for pos, name in enumerate(names_list):
            # get data
            data = signals_df[signals_df["Name"] == name]["Value"]
            print(data)
            # get color
            j = random.randint(0, len(colors) - 1)
            # get plots by index = pos
            x = np.hstack([-1, data.index.values, len(signals_df) - 1])
            y = np.hstack([0, data.values, data.iloc[-1]])
            ax[pos].plot(x, y, drawstyle='steps-post', marker='o', color=colors[j], linewidth=3)
            ax[pos].set_ylabel(name, fontsize=8, fontweight='bold', color='SteelBlue', rotation=30, labelpad=35)
            ax[pos].yaxis.set_major_formatter(ticker.FormatStrFormatter('%0.1f'))
             ax[pos].yaxis.set_tick_params(labelsize=6)
             ax[pos].grid(alpha=0.4)
             i += 1

             for label, x, y in zip(labels, x, y):
             plt.annotate(label, xy=(x, y), xytext=(-20, 20), textcoords='offset points', ha='right', va='bottom', bbox=dict(boxstyle='round,pad=0.5', fc='yellow', alpha=0.5),
                    arrowprops=dict(arrowstyle='->', connectionstyle='arc3,rad=0'))

        plt.show()

What I get I show it right away, which are the annotations spliced and in different position:

console image

But, What does my code need to show each value at each point?

I've also been trying to use the code from the Matplotlib reference and couldn't get it done: Marker Reference. The xml file can be taken from here: xml file Thank you very much in advance, any comment helps.



from Data value of a variable in each marker within subplots

No comments:

Post a Comment