1

For some reason, the code is not doing what is suppose to do, where ideally I want the title, dropdown, and the plot side by side, but currently its stacked against each other.

enter image description here

This is the code that vestland provided (thank you again!) for the app layout:

df_run_data = pd.DataFrame({'Hermes': {0: 'H11433-21', 1: 'H11433-21', 2: 'H11433-21', 3: 'H11433-21', 4: 'H11433-21', 5: 'H11433-21', 6: 'H11433-21', 7: 'H11433-22', 8: 'H11433-22', 9: 'H11433-22', 10: 'H11433-22', 11: 'H11433-22', 12: 'H11433-22', 13: 'H11433-22'}, 'Time': {0: 0.28, 1: 23.36, 2: 46.84, 3: 70.88, 4: 95.09, 5: 118.03, 6: 143.49, 7: 0.28, 8: 23.36, 9: 46.84, 10: 70.88, 11: 95.09, 12: 118.03, 13: 143.49}, 'Sample Type': {0: 'Broth', 1: 'Broth', 2: 'Broth', 3: 'Broth', 4: 'Broth', 5: 'Broth', 6: 'Broth', 7: 'Broth', 8: 'Broth', 9: 'Broth', 10: 'Broth', 11: 'Broth', 12: 'Broth', 13: 'Broth'}, 'Tank Weight Pre kg': {0: 0.249, 1: 0.254, 2: 0.318, 3: 0.389, 4: 
0.383, 5: 0.354, 6: 0.356, 7: 0.249, 8: 0.254, 9: 0.318, 10: 0.389, 11: 0.383, 12: 0.354, 13: 0.356}, 'Tank Weight Post kg': {0: 0.243, 1: 0.235, 2: 0.249, 3: 0.251, 4: 0.25, 5: 0.25, 6: 0.277, 7: 0.243, 8: 0.235, 9: 0.249, 10: 0.251, 11: 0.25, 12: 0.25, 13: 0.277}})
runs = df_run_data.Hermes.unique()
headers = list(df_run_data.columns.values)  

#how to use div https://stackoverflow.com/questions/62234909/layout-management-in-plotly-dash-app-how-to-position-html-div
app.layout = html.Div([

    dbc.Row([dbc.Col(html.H1('Nitrogen Balance', style = {'text-align': 'center'}))]),
    
    dbc.Row([dbc.Col(html.Label('Select Run',style={'font-weight': 'bold', "text-align": "start", 'font-size': 25}), width = 6, className = 'bg-primary ps-4'),
             dbc.Col(html.Label('Select Run',style={'font-weight': 'bold', "text-align": "start", 'font-size': 25}), width = 6, className = 'bg-primary ps-4')

            ], justify = 'start'),
    
    dbc.Row([dbc.Col([dcc.Dropdown(id='Hermes',
                    options=[{'label': i, 'value': i} for i in runs],   #df_run_data['Hermes']], #user will see this
                    value= None, #[i for i in df_run_data['Hermes']],  #default values to show runs
                    multi=True,
                    # style={'width':'40%','display': 'inline-block'}
                    )], width = 6, className = 'bg-secondary ps-4 pe-4'),
    
            dbc.Col([dcc.Dropdown(id='Columns',
                    options=[{'label': i, 'value': i} for i in headers],   #df_run_data['Hermes']], #user will see this
                    value= None, #[i for i in df_run_data['Hermes']],  #default values to show runs
                    multi=True,
                    # style={'width':'40%','display': 'inline-block'}
                    )], width = 6, className = 'bg-secondary ps-4 pe-4'),
            
            ], justify = 'start'
           ),
    html.Div(id ='output_container', children=[]),
    #html.Br(), #break here we want the space between divider and graph
    dbc.Row([dbc.Col([dcc.Graph(id='balance',figure={},
                    # style={'width': '80vh', 'height': '50vh'}
                    )], width = 6),
             dbc.Col([dcc.Graph(id='balance1',figure={},
                    # style={'width': '80vh', 'height': '50vh'}
                    
                    )], width = 6)])
 
])
wew044
  • 49
  • 6
  • [This answer](https://stackoverflow.com/a/64979139/5094044) should set you on the right path. – coralvanda Jun 23 '22 at 01:28
  • I may need a little more help. Now my "Select Run" are stuck together – wew044 Jun 25 '22 at 00:51
  • Check out how to set the wrap property for flexbox, and then make sure the width of your containing element isn't wide enough to allow the elements to live side by side. It will then move them to a stacked arrangement. – coralvanda Jun 25 '22 at 12:42
  • @WayneWu I see you've changed your question quite a bit. That's not often considered good practice around here, but I think we'll be fine if we just make sure to finish the whole thing. If you take the time to share a sample of your data as described here [Pandas: How to easily share a sample dataframe using df.to_dict()?](https://stackoverflow.com/questions/63163251/pandas-how-to-easily-share-a-sample-dataframe-using-df-to-dict/63163254#63163254), then I'm sure we'll find a solution in the end. – vestland Jun 28 '22 at 19:46

1 Answers1

1

Short answer:

For better control of the positioning of your Dash components, you should consider following a pattern with:

app.layout = hmtl.Div([dbc.Row([dbc.Col()])])

Or in your case, something more resembling this:

app.layout = hmtl.Div([dbc.Row([<header>])
                       dbc.Row([dbc.Col([<label>]),
                                dbc.Col([<label>])]),
                       dbc.Row([dbc.Col([<dropdown>]),
                                dbc.Col([<dropdown>])]),
                       dbc.Row([dbc.Col([<graph>]),
                                dbc.Col([<graph>])])])

Full details in the two snippets below where the first one produces this app:

enter image description here

The details:

This contribution won't be a direct answer to your question regarding the behavior of the particular components you're using, but hopefully it will be a solution to the underlying problem, namely getting the different components to play well together when designing Plotly Dash Apps. And perhaps even provide you a platform on which you can build your future Plotly Dash Apps.

It's often considered good practice to construct Dash Apps using a container, either dbc.Container or html.Div, that holds a number of rows dbc.Row() that in turn hold a number of columns dbc.Col() which at last hold your Plotly Dash Components either from one or more of these resources:

from dash import Dash, html, dcc
import dash_bootstrap_components as dbc

This approach lets you position any component exactly where you would like. And through fine-tuning with Style or className, you can make different components with different features and defaults line up and behave nicely.

For example, like this:

App / Code output 1

enter image description here

From here, if you'd like to know where each components start, end and align to eachother, you can decorate them using, for example, className='bg-primary' and get this:

App / Code output 2

enter image description here

Code snippet 1

from jupyter_dash import JupyterDash
from dash import Dash, html, dcc
import dash_bootstrap_components as dbc
import pandas as pd
import plotly.express as px

app = Dash(external_stylesheets=[dbc.themes.BOOTSTRAP])

surfacing = pd.DataFrame({'Barcode':[1,2,3],
                         'Machine':[3,2,1]})

coating = pd.DataFrame({'Barcode':[1,2,3],
                         'Machine':[3,2,1]})

runs = ['A', 'B']
headers = ['A', 'B']

app.layout = html.Div([
    dbc.Row([dbc.Col(html.H1('Nitrogen Balance', style = {'text-align': 'center'}))]),
    
    dbc.Row([dbc.Col(html.Label('Select Run',style={'font-weight': 'bold', "text-align": "start", 'font-size': 25}), width = 6, className = 'bg-primary ps-4'),
             dbc.Col(html.Label('Select Run',style={'font-weight': 'bold', "text-align": "start", 'font-size': 25}), width = 6, className = 'bg-primary ps-4')

            ], justify = 'start'),
    
    dbc.Row([dbc.Col([dcc.Dropdown(id='Hermes',
                            options=[{'label': i, 'value': i} for i in runs],   #df_run_data['Hermes']], #user will see this
                            value= None, #[i for i in df_run_data['Hermes']],  #default values to show runs
                            multi=True,
                            # style={'width':'40%','display': 'inline-block'}
                            )], width = 6, className = 'bg-secondary ps-4 pe-4'),
            
            dbc.Col([dcc.Dropdown(id='Columns',
                            options=[{'label': i, 'value': i} for i in headers],   #df_run_data['Hermes']], #user will see this
                            value= None, #[i for i in df_run_data['Hermes']],  #default values to show runs
                            multi=True,
                            # style={'width':'40%','display': 'inline-block'}
                            )], width = 6, className = 'bg-secondary ps-4 pe-4'),
            
            ], justify = 'start'
           ),
    dbc.Row([dbc.Col([dcc.Graph(id='balance',figure={},
                                # style={'width': '80vh', 'height': '50vh'}
                               )], width = 6),
             dbc.Col([dcc.Graph(id='balance1',figure={},
                                # style={'width': '80vh', 'height': '50vh'}
                                
                               )], width = 6)])
 
])


app.run_server(debug=True)

Code snippet 2

from jupyter_dash import JupyterDash
from dash import Dash, html, dcc
import dash_bootstrap_components as dbc
import pandas as pd
import plotly.express as px

app = JupyterDash(external_stylesheets=[dbc.themes.BOOTSTRAP])

surfacing = pd.DataFrame({'Barcode':[1,2,3],
                         'Machine':[3,2,1]})

coating = pd.DataFrame({'Barcode':[1,2,3],
                         'Machine':[3,2,1]})

runs = ['A', 'B']
headers = ['A', 'B']

app.layout = html.Div([
    dbc.Row([dbc.Col(html.H1('Nitrogen Balance', style = {'text-align': 'center'}))]),
    
    dbc.Row([dbc.Col(html.Label('Select Run',style={'font-weight': 'bold', "text-align": "start", 'font-size': 25}), width = 6, className = 'ps-4'),
             dbc.Col(html.Label('Select Run',style={'font-weight': 'bold', "text-align": "start", 'font-size': 25}), width = 6, className = 'ps-4')

            ], justify = 'start'),
    
    dbc.Row([dbc.Col([dcc.Dropdown(id='Hermes',
                            options=[{'label': i, 'value': i} for i in runs],   #df_run_data['Hermes']], #user will see this
                            value= None, #[i for i in df_run_data['Hermes']],  #default values to show runs
                            multi=True,
                            # style={'width':'40%','display': 'inline-block'}
                            )], width = 6, className = 'ps-4 pe-4'),
            
            dbc.Col([dcc.Dropdown(id='Columns',
                            options=[{'label': i, 'value': i} for i in headers],   #df_run_data['Hermes']], #user will see this
                            value= None, #[i for i in df_run_data['Hermes']],  #default values to show runs
                            multi=True,
                            # style={'width':'40%','display': 'inline-block'}
                            )], width = 6, className = 'ps-4 pe-4'),
            
            ], justify = 'start'
           ),
    dbc.Row([dbc.Col([dcc.Graph(id='balance',figure={},
                                # style={'width': '80vh', 'height': '50vh'}
                               )], width = 6),
             dbc.Col([dcc.Graph(id='balance1',figure={},
                                # style={'width': '80vh', 'height': '50vh'}
                                
                               )], width = 6)])
 
])


app.run_server(debug=True)
vestland
  • 55,229
  • 37
  • 187
  • 305
  • Thank you vestland, really appreciate how you break it down. I have tried your code but its not outputting the same results. – wew044 Jun 28 '22 at 18:36
  • I also tried the "Text" portion suggested by this link, and all it did was having texts stacked vertically. https://stackoverflow.com/questions/63592900/plotly-dash-how-to-design-the-layout-using-dash-bootstrap-components – wew044 Jun 28 '22 at 18:58
  • Not getting the same results? For the EXACT same snippets as I've provided? – vestland Jun 28 '22 at 19:00
  • yeah I even copied and paste your SNIPPET 1 code to make sure I didnt have any typos – wew044 Jun 28 '22 at 20:34
  • I shared the data in the post. let me know if that is correct format. – wew044 Jun 28 '22 at 20:49
  • @WayneWu I just tried the snippet in your question with the data, and I'm still seeing the exact same results as you can see in my original suggestions. Which versions are you running of Plotly and Dash? I've got Plotly `5.6.0` and Dash `2.0.0` – vestland Jun 28 '22 at 21:19
  • thats weird... and I have Dash 2.4.1 and Plotly 5.8.0 – wew044 Jun 28 '22 at 21:35
  • 1
    nevermind, it work. I knew there was soemthing wrong. I restarted my computer and it did exactly what you showed. thanks a bunch! :) – wew044 Jun 28 '22 at 22:54
  • @WayneWu You're welcome! Glad it worked out in the end. – vestland Jun 28 '22 at 23:17