Violin Plot using dropdown in Dash

Hi all,
I am trying to implement a violin plot in Dash Framework.
Here the X (color) will be a value from dropdown and y will be another value from dropdown.
But when I am returning the fig to the browser it’s showing error:


import dash
from dash.dependencies import Input, Output
from dash import dash_table
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd
import plotly.graph_objects as go

df=pd.read_csv('data/chronos.csv')
cols=set(df.columns)
meta_df=pd.read_csv('data/metadata.csv')
tot_col=set(meta_df.columns)


app = dash.Dash(__name__)

app.layout = html.Div([
    html.H1("Elucidata Dashboard"),
    html.Hr(),
    html.Div([
    dcc.Dropdown(
        id='x_file-dropdown',
        options=[
            {'label': 'Chronos_data', 'value': 'chronos.csv'},
            {'label': 'CN_data', 'value': 'cn.csv'},
            {'label': 'Expression_data', 'value': 'expression.csv'}
        ],
        value='chronos.csv'
    ),
    ]),
    html.Div([
    dcc.Dropdown(
        id='x_col-dropdown',
        options=[
            {'label':i ,'value':i }
            for i in cols
        ],
        value='HOXD8'
    ),
    ]),
    html.Div([
    dcc.Dropdown(
        id='color_col-dropdown',
        options=[
            {'label':i ,'value':str(i) }
            for i in tot_col
        ],
        value='source'
    ),
    ]),

    
    html.Br(),
    html.Div( id='datatable-interactivity'),
    
])

@app.callback(
    Output('datatable-interactivity', 'children'),
    [Input('x_file-dropdown', 'value'),Input('x_col-dropdown', 'value'),Input('color_col-dropdown', 'value')]
)

def update_table(x_file,x_col,cols):
    xdf = pd.read_csv('data/'+x_file)
    print(x_file)
    xdf1=xdf[['Sample_ID',x_col]]
    zdf1=meta_df[['Sample_ID',cols]]
    final_df = pd.merge(xdf1, zdf1, on="Sample_ID")
    final_df1=final_df.dropna()
    meta_colors = set(final_df1[cols])
    for mc in meta_colors:
        fig.add_trace(go.Violin(x=final_df1[cols][df[cols] == mc],
                                y=df[x_col][df[cols] == mc],
                                name=mc,
                                box_visible=True,
                                meanline_visible=True))
        #fig.show()
    return html.Div([
        dcc.Graph(figure=fig)
    ])




if __name__ == '__main__':
    app.run_server(debug=True)

In server the error is coming.
Error:

Traceback (most recent call last):
  File "C:\Users\Sawon\Desktop\elucidata\viz2.py", line 72, in update_table
    fig.add_trace(go.Violin(x=final_df1[cols][df[cols] == mc],
NameError: name 'fig' is not defined

Thanks in advance.

1 Like

Hi,

You have to create a figure instance before adding traces:

# import plotly.graph_objects as go
fig = go.Figure()

Thanks It has worked. Can you help me to rotate the axis of the plot?

I want to rotate the graph so that those labels can be shown vertically instead of horizontally.

Does orientation="h" work for violin plots?

according to the documentation it works. But in my case it’s not working somehow.

Do you have a reproducible example that I can take a look?


I want to do this in this way.

Let me rephrase, could you share the code you tried so far, so I can try it?

import dash
from dash.dependencies import Input, Output
from dash import dash_table
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd
import plotly.graph_objects as go

df=pd.read_csv('data/chronos.csv')
cols=set(df.columns)
meta_df=pd.read_csv('data/metadata.csv')
tot_col=set(meta_df.columns)


app = dash.Dash(__name__)

app.layout = html.Div([
    html.H1("Elucidata Dashboard"),
    html.Hr(),
    html.Div([
    dcc.Dropdown(
        id='x_file-dropdown',
        options=[
            {'label': 'Chronos_data', 'value': 'chronos.csv'},
            {'label': 'CN_data', 'value': 'cn.csv'},
            {'label': 'Expression_data', 'value': 'expression.csv'}
        ],
        value='chronos.csv'
    ),
    ]),
    html.Div([
    dcc.Dropdown(
        id='x_col-dropdown',
        options=[
            {'label':i ,'value':i }
            for i in cols
        ],
        value='HOXD8'
    ),
    ]),
    html.Div([
    dcc.Dropdown(
        id='color_col-dropdown',
        options=[
            {'label':i ,'value':str(i) }
            for i in tot_col
        ],
        value='source'
    ),
    ]),

    
    html.Br(),
    html.Div( id='datatable-interactivity'),
    
])

@app.callback(
    Output('datatable-interactivity', 'children'),
    [Input('x_file-dropdown', 'value'),Input('x_col-dropdown', 'value'),Input('color_col-dropdown', 'value')]
)

def update_table(x_file,x_col,cols):
    xdf = pd.read_csv('data/'+x_file)
    print(x_file)
    xdf1=xdf[['Sample_ID',x_col]]
    zdf1=meta_df[['Sample_ID',cols]]
    final_df = pd.merge(xdf1, zdf1, on="Sample_ID")
    final_df1=final_df.dropna()
    meta_colors = set(final_df1[cols])
    for mc in meta_colors:
        fig.add_trace(go.Violin(x=final_df1[cols][df[cols] == mc],
                                y=df[x_col][df[cols] == mc],
                                name=mc,
                                box_visible=True,
                                #orientation="h",
                                meanline_visible=True))
        #fig.show()
        fig.update_layout(
            
            autosize=False,
            width=1500,
            height=1000,
            
            yaxis=dict(
                title_text="Y-axis Title",
                ticktext=["Very long label", "long label", "3", "label"],
                tickvals=[1, 2, 3, 4],
                tickmode="array",
                titlefont=dict(size=30),
            )
        )
    return html.Div([
        dcc.Graph(figure=fig)
    ])




if __name__ == '__main__':
    app.run_server(debug=True)

can’t share any data file :slight_smile:

I think you should have changed x <-> y with respect to your working example, and not only add orientation="h".

Thanks for your help.
I am trying to build a multipage dash board.
Link:
Dashboard Code

I am following this documentation ( URL Routing and Multiple Apps | Dash for Python Documentation | Plotly). But somehow the callback function is not working.
Can you help me please.

Please mark the answer to your first question as solved and start a new thread. I will be glad to help there.

Make sure to add some reproducible lines of code…