How to make a multiple trace plot as a reusable code?

后端 未结 1 603
误落风尘
误落风尘 2021-01-14 09:22

I somehow tried to make the reusable code of plots for eg a bar_graph as:

def bar(x,y,text,marker,orientation,name):
    barchart=[go.Bar(x=x,y=y,text=text,         


        
相关标签:
1条回答
  • 2021-01-14 09:59

    You can easily loop through the columns of your dataframe and create a trace for each of them like in the snippet below.

    # crate traces
    traces={}
    for col in df.columns:
        traces['trace_' + col]=go.Bar(x=df.index, name=col, y=df[col])
    
    # convert data to form required by plotly
    data=list(traces.values())
    
    # build figure
    fig=go.Figure(data)
    fig.show()
    

    Edited suggestion after conversations with OP in comments and chat.

    Without a reproducible data sample, it's a bit hard to suggest a perfect solution. But here's a suggestion that is reusable in the sense that:

    (1): it's flexible with regards to the number of columns in your source dataframe and uses a for loop to add traces as requested,

    (2): it calculates max() and min() for each column,

    (3): it is structured as a function and can easiliy be applied to any dataframe.

    I've put together some sample data that looks like this:

    Plot 1:

    Code 1:

    # Imports
    import pandas as pd
    import plotly.graph_objs as go
    import matplotlib.pyplot as plt
    import numpy as np
    
    # data
    humid = pd.Series(np.random.uniform(low=25, high=40, size=6).tolist())
    windy = pd.Series(np.random.uniform(low=40, high=60, size=6).tolist())
    df = pd.concat([humid,windy], axis = 1)
    df.columns=['Humidity', 'windspeed']
    df.index = ['Shanghai', 'Houston', 'Venice', 'Munich', 'Milan', 'Turin']
    
    
    def plotMaxMin(df):
        for col in df.columns:
            #print(df[col].max())
            df[col+'_max']=df[col].max()
            df[col+'_min']=df[col].min()
    
        # crate traces
        traces={}
        for col in df.columns:
            traces['trace_' + col]=go.Scatter(x=df.index, name=col, y=df[col])
    
        # convert data to form required by plotly
        data=list(traces.values())
    
        # build figure
        fig=go.Figure(data)
        fig.show()
    
    plotMaxMin(df=df)
    

    Test for reusability using an edited dataframe:

    Plot 2:

    Code 2:

    df2=df.copy(deep=True)
    df2['Temperature']=pd.Series(np.random.uniform(low=-5, high=40, size=6).tolist())
    
    plotMaxMin(df2)
    

    We're sill missing the updatemnu(). As it is, the plot still is pretty interactive by only clicking the names of the series.

    Test with go.layout.Updatemenu()

    This will take some more tweaking to make perfect, but the main functioanlities seem to be in place, so I hope you'll be able to add a few things to get it exaclty like you want with your dataset.

    Plot 3:

    Code 3:

    # Imports
    import pandas as pd
    import matplotlib.pyplot as plt
    import numpy as np
    
    # data
    humid = pd.Series(np.random.uniform(low=25, high=40, size=6).tolist())
    windy = pd.Series(np.random.uniform(low=40, high=60, size=6).tolist())
    df = pd.concat([humid,windy], axis = 1)
    df.columns=['Humidity', 'windspeed']
    df.index = ['Shanghai', 'Houston', 'Venice', 'Munich', 'Milan', 'Turin']
    
    
    def plotMaxMin(df):
        for col in df.columns:
            #print(df[col].max())
            df[col+'_max']=df[col].max()
            df[col+'_min']=df[col].min()
    
        # crate traces
        traces={}
        for col in df.columns:
            traces['trace_' + col]=go.Scatter(x=df.index, name=col, y=df[col])
    
        # convert data to form required by plotly
        data=list(traces.values())
    
        # build figure
        fig=go.Figure(data)
    
        # add dropdown functionality
    
        fig.update_layout(
        updatemenus=[
            go.layout.Updatemenu(
                active=0,
                buttons=list([
                    dict(label="None",
                         method="update",
                         args=[{"visible": [True, False, True, False]},
                               {"title": "Yahoo",
                                "annotations": []}]),
                    dict(label="High",
                         method="update",
                         args=[{"visible": [True, True, False, False]},
                               {"title": "Yahoo High",
                                "annotations": high_annotations}]),
                    dict(label="Low",
                         method="update",
                         args=[{"visible": [False, False, True, True]},
                               {"title": "Yahoo Low",
                                "annotations": high_annotations}]),
    
                ]),
            )
        ])
    
    
    
        fig.show()
    
    plotMaxMin(df=df)
    

    Edit 2: Example on how to expand function with more arguments to customize your plotly figure

    Plot 4:

    Code 4:

    # Imports
    import pandas as pd
    import matplotlib.pyplot as plt
    import numpy as np
    
    # data
    humid = pd.Series(np.random.uniform(low=25, high=40, size=6).tolist())
    windy = pd.Series(np.random.uniform(low=40, high=60, size=6).tolist())
    df = pd.concat([humid,windy], axis = 1)
    df.columns=['Humidity', 'Windspeed']
    df.index = ['Shanghai', 'Houston', 'Venice', 'Munich', 'Milan', 'Turin']
    
    
    def plotMaxMin(df, colors):
        """Adds max and min for all df columns and plots the data using plotly
    
        Arguments:
        ==========
        df - pandas dataframe
        colors - dictionary with single word to identify line category and assign color
    
        Example call:
        =============
        plotMaxMin(df=df, colors={'wind':'#33CFA5', 'humidity':'#F06A6A'})
    
        """
    
    
        # add max and min for each input column
        for col in df.columns:
            df[col+'_max']=df[col].max()
            df[col+'_min']=df[col].min()
    
        # sort df columns by name
        df = df.reindex(sorted(df.columns), axis=1)
    
        # crate traces
        traces={}
        for col in df.columns:
    
            # format traces
            if 'Humid' in col:
                linecolor = colors['humidity']
    
            if 'Wind' in col:
                linecolor = colors['wind']
    
            traces['trace_' + col]=go.Scatter(x=df.index, name=col, y=df[col], line=dict(color=linecolor))
    
        # convert data to form required by plotly
        data=list(traces.values())
    
        # build figure
        fig=go.Figure(data)
    
        # uncomment bloew section to add dropdown functionality
    
        #fig.update_layout(
        #updatemenus=[
        #    go.layout.Updatemenu(
        #        active=0,
        #        buttons=list([
        #            dict(label="None",
        #                 method="update",
        #                 args=[{"visible": [True, False, True, False]},
        #                       {"title": "Yahoo",
        #                        "annotations": []}]),
        #            dict(label="High",
        #                 method="update",
        #                 args=[{"visible": [True, True, False, False]},
        #                       {"title": "Yahoo High",
        #                        "annotations": high_annotations}]),
        #            dict(label="Low",
        #                 method="update",
        #                 args=[{"visible": [False, False, True, True]},
        #                       {"title": "Yahoo Low",
        #                        "annotations": high_annotations}]),
        #        ]),
        #    )
        #])
    
    
    
        fig.show()
    
    plotMaxMin(df=df, colors={'wind':'#33CFA5', 'humidity':'#F06A6A'})
    
    0 讨论(0)
提交回复
热议问题