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

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-11 03:35:48

问题


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,marker=marker,orientation=orientation,name=name)]
    ........

In a similar way how can I make a reusable code for multiple traces ?

for this below code,

fig = go.Figure()

# Add Traces

fig.add_trace(
    go.Scatter(x=list(df.index),
               y=list(df.High),
               name="High",
               line=dict(color="#33CFA5")))

fig.add_trace(
    go.Scatter(x=list(df.index),
               y=[df.High.mean()] * len(df.index),
               name="High Average",
               visible=False,
               line=dict(color="#33CFA5", dash="dash")))

fig.add_trace(
    go.Scatter(x=list(df.index),
               y=list(df.Low),
               name="Low",
               line=dict(color="#F06A6A")))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": low_annotations}]),

            ]),
        )
    ])

# Set title
fig.update_layout(title_text="Yahoo")

fig.show()

here, the traces would be of any,i.e., based on combination of values passed for each trace, so how can I make it as a reusable code?

.....


回答1:


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'})


来源:https://stackoverflow.com/questions/57975944/how-to-make-a-multiple-trace-plot-as-a-reusable-code

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!