Select columns to plot in y

I want to allow the user to choose which columns of a data frame one wants to see on y. I tried so much meanwhile but I still can’t get it to work. I followed Line charts in Python but there is actually not an example given according to my needs.
The possible columns to choose from are ['V+', 'V-', 'I_tube', 'I_heat'].
My code so far is:


app = Dash(__name__)

app.layout = html.Div(
                        style = {},
                        children = [
                                    html.H4('test'),
                                    dcc.Graph(id="graph"
                                              ),
                                    html.Br(),
                                    dcc.Checklist(
                                                  id="signals",
                                                  options = ['V+', 'V-', 'I_tube', 'I_heat'],
                                                  value = ['V+'],
                                                  inline=True
                                                  ),
                                    ]
)


@app.callback(
              Output("graph", "figure"), 
              Input("signals", "value")
              )
def update_line_chart(signals):
    #df = all_df[all_df.columns == signals]
    df = all_df

    fig = px.line(df
                  , x = "time"
                  #, y = "I_heat"
                  #, y = df[signals]
                  #, y = signals['value']
                  #, y = df['value']
                  #, y = all_df.columns == signals['value']
                  , color = 'Device'
                  , hover_name="Device"
                  , template = 'plotly_dark'
                  )
    
    fig.update_layout(transition_duration=500)
    return fig

app.run_server()

I’m highly thankful for any input!

I think you should use dcc.RadioItems instead of dcc.Checklist. Because you want to see chart of each columns, not all.
You can do something as below:

import dash
from dash import dcc
from dash import html
import dash_bootstrap_components as dbc
from dash.dependencies import Input, Output
import pandas as pd

df = px.data.gapminder().query("continent=='Oceania'")

app = dash.Dash(__name__, title='Dashboard', external_stylesheets=[dbc.themes.BOOTSTRAP])

app.layout = html.Div([
    dcc.Graph(id='graph', 
              figure={}),
    dcc.RadioItems(id='radioitems', 
                  options=['lifeExp','gdpPercap'],
                 value='lifeExp')
])

@app.callback(Output('graph','figure'), 
              Input('radioitems','value'))

def update_graph(radioitems):
    fig = px.line(df, x="year", y=radioitems, color='country')
    return fig

if __name__ == "__main__":
    app.run_server(debug=False)
2 Likes

Thanks a lot, it’s working!

Just one (little?) comment: Indeed I would like to use Checklist instead of Radioitems, I guess? Or let’s say I would like to see two or more graphs in parallel, if possible? E.g. lifeExp and gdpPercap in parallel.
But when I simply replace Radioitems with Checklist I receive an error:

ValueError: All arguments should have the same length. The length of argument y is 9, whereas the length of previously-processed arguments [‘year’] is 24

Is there a(nother) way to do that?

1 Like

If you want to do that, I think you should use pandas melt to transform your data. Year will be columns, columns will be rows.

Ok, thank you. I actually did that but how do I do the plotting now?

P.S.: Btw, I thought a bit about it: In my case, each column ['V+', 'V-', 'I_tube', 'I_heat'] provides the same amount of entries, so there shouldn’t be any mismatch or so?

Can you provide your dataframe? Or I think something as below should work:

import dash
from dash import dcc
from dash import html
import dash_bootstrap_components as dbc
from dash.dependencies import Input, Output
import pandas as pd
import plotly.express as px
df = px.data.gapminder().query("continent=='Oceania'")
df = df[df['country'] == 'Australia']
df2 = df.melt(id_vars=['country','year'], value_vars=['lifeExp','gdpPercap'])

app = dash.Dash(__name__, title='Dashboard', external_stylesheets=[dbc.themes.BOOTSTRAP])

app.layout = html.Div([
    dcc.Graph(id='graph', 
              figure={}),
    dcc.Checklist(id='checklist', 
                  options=['lifeExp','gdpPercap'],
                  value=[])
])

@app.callback(Output('graph','figure'), 
              Input('checklist','value'))

def update_graph(checklist):
    if checklist == []:
        fig = px.line(df2,x='year',y='value',color='variable')     
        return fig
    elif checklist != []:
        dff = df2[df2['variable'].isin(checklist)]
        fig = px.line(dff,x='year',y='value',color='variable')
        return fig

if __name__ == "__main__":
    app.run_server(debug=False)
1 Like

Interesting to see how you solved that. Thank you very much, I’ll try to adjust this to my needs!

One last (tiny) question: Is it possible to give the graphs different shapes?
I tried it with:

    fig = px.line(df
                  , x = "time"
                  , y = signals
                  , color = 'Device'
                  #, line_dash = signals
                  , hover_name = "Device"
                  , template = 'plotly_dark'
                  )

but that doesn’t work (though I don’t understand why).

What does you mean about different shapes?

Means different appearances for each column, like in Linestyles — Matplotlib 3.7.1 documentation
Maybe even the same for markers but that would probably be quite the same.

The devices are automatically separated in colors thanks to df['Devices'].astype("category") and then using color = 'Device':

                 fig = px.line(df
                  , x = "time"
                  , y = signals
                  , color = 'Device'
                  #, line_dash = signals
                  , hover_name="Device"
                  , template = 'plotly_dark'
                  )

I guess line_dash = signals is not working accordingly as signals is not a column plus not categorical.

Can you provide your sample dataframe?

Hi,
sure, yes, sorry for the delay. Here is the link to download a .csv file of it: Filebin | pag2dnsixti4ce9a

Hi, do you have expected Output of Graph? Does this below match with your requirement?

1 Like

Yes, that fits.

import dash
from dash import dcc
from dash import html
import dash_bootstrap_components as dbc
from dash.dependencies import Input, Output
import pandas as pd
import plotly.express as px
df = pd.read_csv('out.csv')

df2 = df.melt(id_vars=['Device','time'], value_vars=['V+','V-','I_tube','I_heat'])

app = dash.Dash(__name__, title='Dashboard', external_stylesheets=[dbc.themes.BOOTSTRAP])

app.layout = html.Div([
    dcc.Graph(id='graph', 
              figure={}),
    dcc.Checklist(id='checklist', 
                  options=['V+','V-','I_tube','I_heat'],
                  value=[])
])

@app.callback(Output('graph','figure'), 
              Input('checklist','value'))

def update_graph(checklist):
    if checklist == []:
        fig = px.line(df2,x='time',y='value',color='variable')
        fig.update_xaxes(type='category')
        return fig
    elif checklist != []:
        dff = df2[df2['variable'].isin(checklist)]
        fig = px.line(dff,x='time',y='value',color='variable')
        fig.update_xaxes(type='category')
        return fig

if __name__ == "__main__":
    app.run_server(debug=False)

You can use this code to run

1 Like

Hi, thanks a lot again!

I also moved along with the input from your first contribution (the syntax seems easier to me, have to figure out, which I’ll use, I assume, your last code is more efficient) and this is what I have now:


# Initialise the app
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, title='Dashboard', external_stylesheets=external_stylesheets)                # Include css files


colors = {
    'background': '#000000',
    'text': '#f3ff00'
}

# Define the app
app.layout = html.Div(children = [
    
                            html.Div([
                                    html.H4('Dauertest'),
                                    html.Div(children = ""),

                                    # Draw graph
                                    dcc.Graph(id = 'General' 
                                              , figure={}
                                              ),
                                    ]),
                                    dcc.Checklist(
                                                  id="signals",
                                                  options = ['V+', 'V-', 'I_tube', 'I_heat'],
                                                  value = ['V+', 'V-', 'I_tube'],
                                                  inline=True
                                                  ),
                                    html.Br(),
                                    html.Br(),
                                                                        
                            # New row
                            html.Div([
                                html.Div([                                    
                                    dcc.Graph(id = 'V+' 
                                              , figure={}
                                              ),
                                        ], className='six columns'),
                                html.Div([   
                                    dcc.Graph(id = 'V-' 
                                              , figure={}
                                              ),
                                        ], className='six columns'),
                                    ], className='row'),
                                    html.Br(),

                            # New row
                            html.Div([
                                html.Div([
                                    
                                            dcc.Graph(id = 'I_tube' 
                                                      , figure={}
                                                      ),
                                        ], className='six columns'),
                                html.Div([
                                            dcc.Graph(id = 'I_heat' 
                                                      , figure={}
                                                      ),
                                        ], className='six columns'),
                            ], className='row')
])


@app.callback(
              Output("General", "figure"), 
              Output("V+", "figure"), 
              Output("V-", "figure"), 
              Output("I_tube", "figure"), 
              Output("I_heat", "figure"), 
              Input("signals", "value")
              )
def update_line_chart(signals):
    fig_general = px.scatter(df
                  , x = "time"
                  , y = signals
                  , color = 'Device'
                  , symbol = signals
                  , hover_name = "Device"
                  , template = 'plotly_dark'
                  )

    
    fig_general.update_layout(
        transition_duration = 500
        , autosize = True
        , height = 700
        )
    
    
    fig_V_plus = px.scatter(df
                  , x = "time"
                  , y = "V+"
                  , color = 'Device'
                  , hover_name = "Device"
                  , template = 'plotly_dark'
                  ).update_layout(
                      transition_duration = 500
                      , autosize = True
                      )
    
    fig_V_minus = px.scatter(df
                  , x = "time"
                  , y = "V-"
                  , color = 'Device'
                  , hover_name = "Device"
                  , template = 'plotly_dark'
                  ).update_layout(
                      transition_duration = 500
                      , autosize = True
                      )
                      
    fig_I_heat = px.scatter(df
                  , x = "time"
                  , y = "I_heat"
                  , color = 'Device'
                  , hover_name = "Device"
                  , template = 'plotly_dark'
                  ).update_layout(
                      transition_duration = 500
                      , autosize = True
                      )
                      
    fig_I_tube = px.scatter(df
                  , x = "time"
                  , y = "I_tube"
                  , color = 'Device'
                  , hover_name = "Device"
                  , template = 'plotly_dark'
                  ).update_layout(
                      transition_duration = 500
                      , autosize = True
                      )
    
    return [fig_general, fig_V_plus, fig_V_minus, fig_I_heat, fig_I_tube]

# Run the app
if __name__ == "__main__":
    app.run_server(  )

I wonder whether there is an easy way to allow different marker symbols for in:

    fig_general = px.scatter(df
                  , x = "time"
                  , y = signals
                  , color = 'Device'
                  #, symbol = signals
                  , hover_name = "Device"
                  , template = 'plotly_dark'
                  )

symbol = signals unfortunately does not work. From the resulting error I understand that four options differ from the entire dataframe x and y receive but I actually don’t get the syntax issue in general.
If not, no worries, I’ll embed your code into mine, which is finally totally sufficient. I only would like to know whether there is a way as I got a bit of understanding about the code and how plotly/dash works (at least in this context, here :slight_smile: ).

Well, I think I’ll move on with your code anyway as it allows other features more easily, like creating several plots with a shared x-axis.
However, thanks a lot again!

1 Like

Oh ok so now I understand what do you need. You can refer below code to make it.

import dash
from dash import dcc
from dash import html
import dash_bootstrap_components as dbc
from dash.dependencies import Input, Output
import pandas as pd
import plotly.express as px
df = pd.read_csv('out.csv')
df2 = df.melt(id_vars=['Device','time'], value_vars=['V+','V-','I_tube','I_heat'])


external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, title='Dashboard', external_stylesheets=external_stylesheets)                # Include css files


colors = {
    'background': '#000000',
    'text': '#f3ff00'
}

# Define the app
app.layout = html.Div(children = [
    
                            html.Div([
                                    html.H4('Dauertest'),
                                    html.Div(children = ""),

                                    # Draw graph
                                    dcc.Graph(id = 'General' 
                                              , figure={}
                                              ),
                                    ]),
                                    dcc.Checklist(
                                                  id="signals",
                                                  options = ['V+', 'V-', 'I_tube', 'I_heat'],
                                                  value = ['V+', 'V-', 'I_tube'],
                                                  inline=True
                                                  ),
                                    html.Br(),
                                    html.Br(),
                                                                        
                            # New row
                            html.Div([
                                html.Div([                                    
                                    dcc.Graph(id = 'V+' 
                                              , figure={}
                                              ),
                                        ], className='six columns'),
                                html.Div([   
                                    dcc.Graph(id = 'V-' 
                                              , figure={}
                                              ),
                                        ], className='six columns'),
                                    ], className='row'),
                                    html.Br(),

                            # New row
                            html.Div([
                                html.Div([
                                    
                                            dcc.Graph(id = 'I_tube' 
                                                      , figure={}
                                                      ),
                                        ], className='six columns'),
                                html.Div([
                                            dcc.Graph(id = 'I_heat' 
                                                      , figure={}
                                                      ),
                                        ], className='six columns'),
                            ], className='row')
])


@app.callback(
              Output("General", "figure"), 
              Output("V+", "figure"), 
              Output("V-", "figure"), 
              Output("I_tube", "figure"), 
              Output("I_heat", "figure"), 
              Input("signals", "value")
              )
def update_line_chart(signals):
    df3=df2[df2['variable'].isin(signals)]
    fig_general = px.scatter(df3
                  , x = "time"
                  , y = 'value'
                  , color = 'Device'
                  , symbol = 'variable'
                  , hover_name = "Device"
                  , template = 'plotly_dark'
                  )

    
    fig_general.update_layout(
        transition_duration = 500
        , autosize = True
        , height = 700
        )
    
    
    fig_V_plus = px.scatter(df
                  , x = "time"
                  , y = "V+"
                  , color = 'Device'
                  , hover_name = "Device"
                  , template = 'plotly_dark'
                  ).update_layout(
                      transition_duration = 500
                      , autosize = True
                      )
    
    fig_V_minus = px.scatter(df
                  , x = "time"
                  , y = "V-"
                  , color = 'Device'
                  , hover_name = "Device"
                  , template = 'plotly_dark'
                  ).update_layout(
                      transition_duration = 500
                      , autosize = True
                      )
                      
    fig_I_heat = px.scatter(df
                  , x = "time"
                  , y = "I_heat"
                  , color = 'Device'
                  , hover_name = "Device"
                  , template = 'plotly_dark'
                  ).update_layout(
                      transition_duration = 500
                      , autosize = True
                      )
                      
    fig_I_tube = px.scatter(df
                  , x = "time"
                  , y = "I_tube"
                  , color = 'Device'
                  , hover_name = "Device"
                  , template = 'plotly_dark'
                  ).update_layout(
                      transition_duration = 500
                      , autosize = True
                      )
    
    return [fig_general, fig_V_plus, fig_V_minus, fig_I_heat, fig_I_tube]
# Run the app
if __name__ == "__main__":
    app.run_server(debug=False, port=8054)

1 Like

Awesome, thank you very much!

I don’t wanna stretch out your help but as you’re already quite familiar with my stuff I would like to make you aware of another concernI raised :slight_smile: : Use same x-axis (time) for multiple (sub)plots but keep y-axis independent