4

This Question is continous from what Tim Dunn asking in this question.

@Kristian Haga already answer it. but I want to continue asking in answer section, it's forbidden by @Bhargav-rao.

He ask me to make the new one and really sure, someone will answer it.

to make everybody understood I copy and paste the Tim Dunn question and Khristian Haga answer here.

Tim dunn asking how to make layout in dash like this:

a full dashboard with full graph with some layout configuration.

@Kristian Haga already answer it by this script:

import plotly.express as px
from jupyter_dash import JupyterDash
import dash_core_components as dcc
import dash_html_components as html
import dash_bootstrap_components as dbc
from dash.dependencies import Input, Output
import plotly.express as px

# Iris bar figure
def drawFigure():
    return  html.Div([
        dbc.Card(
            dbc.CardBody([
                dcc.Graph(
                    figure=px.bar(
                        df, x="sepal_width", y="sepal_length", color="species"
                    ).update_layout(
                        template='plotly_dark',
                        plot_bgcolor= 'rgba(0, 0, 0, 0)',
                        paper_bgcolor= 'rgba(0, 0, 0, 0)',
                    ),
                    config={
                        'displayModeBar': False
                    }
                ) 
            ])
        ),  
    ])

# Text field
def drawText():
    return html.Div([
        dbc.Card(
            dbc.CardBody([
                html.Div([
                    html.H2("Text"),
                ], style={'textAlign': 'center'}) 
            ])
        ),
    ])

# Data
df = px.data.iris()

# Build App
app = JupyterDash(external_stylesheets=[dbc.themes.SLATE])

app.layout = html.Div([
    dbc.Card(
        dbc.CardBody([
            dbc.Row([
                dbc.Col([
                    drawText()
                ], width=3),
                dbc.Col([
                    drawText()
                ], width=3),
                dbc.Col([
                    drawText()
                ], width=3),
                dbc.Col([
                    drawText()
                ], width=3),
            ], align='center'), 
            html.Br(),
            dbc.Row([
                dbc.Col([
                    drawFigure() 
                ], width=3),
                dbc.Col([
                    drawFigure()
                ], width=3),
                dbc.Col([
                    drawFigure() 
                ], width=6),
            ], align='center'), 
            html.Br(),
            dbc.Row([
                dbc.Col([
                    drawFigure()
                ], width=9),
                dbc.Col([
                    drawFigure()
                ], width=3),
            ], align='center'),      
        ]), color = 'dark'
    )
])

# Run app and display result inline in the notebook
app.run_server(mode='external')

the result will be like this this:

so, I just continue the question by adding more question. more step

if i want make something like this...

enter image description here

how to do that...? sorry if the picture is awfull, i make it, in rush...

the different is:

  1. layout, i put a text top of every graph, but with a column section that separated it in to 2 section rows
  2. how if one of the content is a map?
  3. how if under all the content and the map and the text, there is a layer, with a transparent color.
  4. how to create sidebar
  5. how to make the title change if we press a button

any data, can be use it to explain... like what @Khristian Haga do, he use open source database.

several question I already found it and I put here to explain:

base on the clue in here:

i make a script like this:

first i make a css file and save it inside the assets folder, the file contain script like this:

html {
  height: 100%;}
body{
  margin:0;
  width:100%;
  height:100%;
  background-image: url("./backgroud1.png");
  background-size: cover;
  background-position: center;}

then i write a script like this:

EDIT: because 80% of my question already answered, I put the answer here. and several things that I explain before, I cut it, because of limitation of the character.

base on my self question and my answer on here, yeah sad i think...

i can make something like this: enter image description here

if i do something, with the dropdown and press button, it will become like this: enter image description here

now, the last step is put text and image on the layer, and change in the same time when I press the button. but i still don't know how to do that right now. but to make layout like the image above, this is the script.

import dash
import dash_core_components as dcc
import dash_html_components as html
from plotly import graph_objs as go
import dash_bootstrap_components as dbc
import plotly.express as px
from dash.dependencies import Input, Output, State
import pandas as pd

# this is the data of the city
data = [['a','b','d','h'],
       ['a','b','d','i'],
       ['a','b','e','j'],
       ['a','b','e','k'],
       ['a','c','f','l'],
       ['a','c','f','m'],
       ['a','c','g','n'],
       ['a','c','g','o'],
       ['z','x','p','a1'],
       ['z','x','p','a2'],
       ['z','x','q','a3'],
       ['z','x','q','a4'],
       ['z','y','r','a5'],
       ['z','y','r','a6'],
       ['z','y','s','a7'],
       ['z','y','s','a8']]

df = pd.DataFrame(data)
df.columns = ['city', 'district', 'area', 'subarea']

city_list = list(set(df['city'].to_list()))
city_list.insert(0,'all city')

#function to help  typing code more shorter in the changing title section
# subarea
# ===============
def search_area_from_subarea(area_name):
    area_level = list(set(df[df.loc[:, 'subarea'] == area_name]['area'].to_list()))[0]
    return area_level

def search_district_from_subarea(area_name):
    area_level = list(set(df[df.loc[:, 'subarea'] == area_name]['district'].to_list()))[0]
    return area_level

def search_city_from_subarea(area_name):
    area_level = list(set(df[df.loc[:, 'subarea'] == area_name]['city'].to_list()))[0]
    return area_level

# area
# ===============
def search_district_from_area(area_name):
    area_level = list(set(df[df.loc[:, 'area'] == area_name]['district'].to_list()))[0]
    return area_level

def search_city_from_area(area_name):
    area_level = list(set(df[df.loc[:, 'area'] == area_name]['city'].to_list()))[0]
    return area_level

# district
# ============
def search_city_from_district(area_name):
    area_level = list(set(df[df.loc[:, 'district'] == area_name]['city'].to_list()))[0]
    return area_level

layer1 = html.Div([
        dbc.Col([
            html.Hr(),
            # top side
            # for title text
            dbc.Row([],id='left_side1',
             style={
            'margin-top': '-4px',
            'margin-left': '0px',
            'width': '609px',
            'height': '36px',
            'backgroundColor': 'rgba(120,0,0,0.4)'
            }
                      ),
            # for graph, etc
            dbc.Row([],id='left_side2', 
             style={
            'margin-top': '5px',
            'margin-left': '0px',
            'width': '609px',
            'height': '215px',
            'backgroundColor': 'rgba(120,0,0,0.4)'
            }
                      ),
            #middle
            # for title text
            dbc.Row([],id='left_side3',
            style={
            'margin-top': '9px',
            'margin-left': '0px',
            'width': '314px',
            'height': '36px',
            'backgroundColor': 'rgba(0,0,50,0.4)'
            }
                      ),
            # for graph, etc
            dbc.Row([],id='left_side4',
            style={
            'margin-top': '5px',
            'margin-left': '0px',
            'width': '314px',
            'height': '215px',
            'backgroundColor': 'rgba(0,0,50,0.4)'
            }
                      ),
            #bawah
            # for title text
            dbc.Row([],id='left_side5',
            style={
            'margin-top': '9px',
            'margin-left': '0px',
            'width': '609px',
            'height': '36px',
            'backgroundColor': 'rgba(0,0,120,0.4)'
            }
                      ),
            # for graph, etc
            dbc.Row([],id='left_side6',
            style={
            'margin-top': '5px',
            'margin-left': '0px',
            'width': '609px',
            'height': '215px',
            'backgroundColor': 'rgba(0,0,120,0.4)'
            }
                      ),
        ])
])

layer2 = html.Div([
    html.Hr(),
    #  for title text
    dbc.Col([
            dbc.Row([],id='mid_side1',
            style={
            'margin-top': '-540px',
            'margin-left': '330px',
            'width': '609px',
            'height': '36px',
            'backgroundColor': 'rgba(0,120,0,0.4)'
            }
                      ),
    # for graph, etc
    dbc.Row([],id='mid_side2',
    style={
    'margin-top': '5px',
    'margin-left': '330px',
    'width': '609px',
    'height': '215px',
    'backgroundColor': 'rgba(0,120,0,0.4)'
    }
              ),
     # for title text
    
            dbc.Row([],id='mid_side3',
            style={
            'margin-top': '9px',
            'margin-left': '625px',
            'width': '609px',
            'height': '36px',
            'backgroundColor': 'rgba(120,0,120,0.4)'
            }
                      ),
    # for graph, etc
    dbc.Row([],id='mid_side4',
    style={
    'margin-top': '5px',
    'margin-left': '625px',
    'width': '609px',
    'height': '215px',
    'backgroundColor': 'rgba(120,0,120,0.4)'
    }
              )
            ])
        ])

layer3 = html.Div([
    html.Hr(),
    # for title text
    dbc.Col([
            dbc.Row([],id='right_side1',
            style={
            'margin-top': '-548px',
            'margin-left': '957px',
            'width': '579px',
            'height': '36px',
            'backgroundColor': 'rgba(0,120,120,0.4)'
            }
                      ),
    # for graph, etc
    dbc.Row([],id='right_side2',
    style={
    'margin-top': '5px',
    'margin-left': '957px',
    'width': '579px',
    'height': '215px',
    'backgroundColor': 'rgba(0,120,120,0.4)'
    }
              ),
     # for title text
    
            dbc.Row([],id='right_side3',
            style={
            'margin-top': '9px',
            'margin-left': '1251px',
            'width': '285px',
            'height': '36px',
            'backgroundColor': 'rgba(50,120,0,0.4)'
            }
                      ),
    # for graph, etc
    dbc.Row([],id='right_side4',
    style={
    'margin-top': '5px',
    'margin-left': '1251px',
    'width': '285px',
    'height': '215px',
    'backgroundColor': 'rgba(50,120,0,0.4)'
    }
              )
            ])
        ])

layer4 = html.Div([])

layer_boxes = html.Div([
    layer1,
    layer2,
    layer3,
    layer4],
      style={
            'margin-top': '0px',
            'margin-left': '323px',
            'width': '1568px',
            'height': '813px',
            'backgroundColor': 'rgba(0,0,0,0.3)'
            }
                      )

SIDEBAR_STYLE = {
                  "position": "fixed",
                  "top": '-15px',
                  "left": '0',
                  "bottom": '0',
                  "width": "16rem",
                  "height": "100%",
                  "padding": "2rem 1rem",
                  "background-color": "rgba(0, 0, 0, 0.2)",
                  'align': 'center'
                  }
app = dash.Dash()
app.layout= html.Div([
   
   dbc.Nav(
       [html.Div([html.Img(src='https://www.gravatar.com/avatar/f2d20dc48eff4d12e2352d39018a41af?s=48&d=identicon&r=PG&f=1') 
             ],style={'height':'100px', 
                        'width':'100px',
                        'margin-top': '-6px',
                        'margin-left': '97px'}),
        dcc.Dropdown(
             id='menu_city', clearable=False,
             value='all city', options=[
             {'label': c1, 'value': c1}
             for c1 in city_list]),

          dcc.Dropdown(
             id='menu_district', clearable=False,
             value='all district'),
            dcc.Dropdown(
             id='menu_area', clearable=False,
             value='all area'),
                dcc.Dropdown(
             id='menu_subarea', clearable=False,
             value='all subarea'),
           html.Hr(),
           dbc.Button(id='button_show',children="SHOW DATA", color="info", className="mr-1")
         ],style=SIDEBAR_STYLE )
     , html.Div([
        dbc.Row(
            dbc.Col([
                html.H3(id='title_for_test')],
                align='right', width={'size': '10', 
                                      'offset': '2',}, style={'margin-left': '323px',
                                                              'margin-top': '-9px',
                                                              'color': 'rgb(255,255,255)',
                                                              'fontSize': '22px',
                                                              'height' : '100%'}
            )
              ),
         layer_boxes
           ])
      ])



# =================================
# confifuration to set district dropdown menu change base selection on city dropdown menu
@app.callback(dash.dependencies.Output('menu_district','options'),
              [Input('menu_city', 'value')])
              
def set_list(selected_options):
    if selected_options == 'all city':
        temp_list = list(set(df['district'].to_list()))
        temp_list.insert(0, 'all district')
        return [{'label': i, 'value': i} for i in temp_list]
    else:
        temp_list = list(set(df[df.loc[:,'city'] == selected_options]['district'].to_list()))
        temp_list.insert(0, 'all district')
        return [{'label': i, 'value': i} for i in temp_list]
# -----------------------------
# configuration to prevent district dropdown menu error
@app.callback(dash.dependencies.Output('menu_district','value'),
              [Input('menu_district', 'options')])
              
def set_list(selected_options):
    return selected_options[0]['value']




# =======================================
# confifuration to set area dropdown menu change base selection on district dropdown menu

@app.callback(dash.dependencies.Output('menu_area','options'),
              [Input('menu_city', 'value')],
              [Input('menu_district', 'value')],
             multi = True)
              
def set_list(selected_options1, selected_options2):
    # 2 input, means: 2**2 possibility
    #print('1',selected_options1)
    #print('2', selected_options2)
    
    if selected_options1 == 'all city' and selected_options2 == 'all district':
        temp_list = list(set(df['area'].to_list()))
        temp_list.insert(0, 'all area')
        return [{'label': i, 'value': i} for i in temp_list]
    
    if selected_options1 != 'all city' and selected_options2 == 'all district':
        temp_list = list(set(df[(df.loc[:,'district'] == selected_options2)]['area'].to_list()))
        temp_list.insert(0, 'all area')
        return [{'label': i, 'value': i} for i in temp_list]
    
    if selected_options1 == 'all city' and selected_options2 != 'all district':
        temp_list = list(set(df[(df.loc[:,'district'] == selected_options2)]['area'].to_list()))
        temp_list.insert(0, 'all area')
        return [{'label': i, 'value': i} for i in temp_list]
    
    if selected_options1 != 'all city' and selected_options2 != 'all district':
        temp_list = list(set(df[(df.loc[:,'city'] == selected_options1) & (df.loc[:,'district'] == selected_options2)]['area'].to_list()))
        temp_list.insert(0, 'all area')
        return [{'label': i, 'value': i} for i in temp_list]
    
# -----------------------------
# configuration to prevent area dropdown menu error

@app.callback(dash.dependencies.Output('menu_area','value'),
              [Input('menu_area', 'options')])




# ========================================
# confifuration to set subarea dropdown menu change base selection on area dropdown menu

@app.callback(dash.dependencies.Output('menu_subarea','options'),
              [Input('menu_city', 'value')],
              [Input('menu_district', 'value')],
              [Input('menu_area', 'value')],
              multi=True
             )
              
def set_list(selected_options1,selected_options2, selected_options3):
    # 3 input = 2**3 possibility
    
    # possibility 1:
    if selected_options1 == 'all city' and selected_options2 == 'all district' and selected_options3 == 'all area':
        temp_list = list(set(df['subarea'].to_list()))
        temp_list.insert(0, 'all subarea')
        return [{'label': i, 'value': i} for i in temp_list]
    
    # possibility 2:
    if selected_options1 == 'all city' and selected_options2 == 'all district' and selected_options3 != 'all area':
        temp_list = list(set(df[(df.loc[:,'area'] == selected_options3)]['subarea'].to_list()))
        temp_list.insert(0, 'all subarea')
        return [{'label': i, 'value': i} for i in temp_list]
    # possibility 3:
    if selected_options1 == 'all city' and selected_options2 != 'all district' and selected_options3 == 'all area':
        temp_list = list(set(df[(df.loc[:,'district'] == selected_options2)]['subarea'].to_list()))
        temp_list.insert(0, 'all subarea')
        return [{'label': i, 'value': i} for i in temp_list]
    # possibility 4:
    if selected_options1 != 'all city' and selected_options2 == 'all district' and selected_options3 == 'all area':
        temp_list = list(set(df[(df.loc[:,'city'] == selected_options1)]['subarea'].to_list()))
        temp_list.insert(0, 'all subarea')
        return [{'label': i, 'value': i} for i in temp_list]
    
    
    # possibility 5:
    if selected_options1 != 'all city' and selected_options2 != 'all district' and selected_options3 == 'all area':
        temp_list = list(set(df[(df.loc[:,'city'] == selected_options1) & (df.loc[:,'district'] == selected_options2)]['subarea'].to_list()))
        temp_list.insert(0, 'all subarea')
        return [{'label': i, 'value': i} for i in temp_list]
    
    # possibility 6:
    if selected_options1 != 'all city' and selected_options2 == 'all district' and selected_options3 != 'all area':
        temp_list = list(set(df[(df.loc[:,'city'] == selected_options1) & (df.loc[:,'area'] == selected_options3)]['subarea'].to_list()))
        temp_list.insert(0, 'all subarea')
        return [{'label': i, 'value': i} for i in temp_list]
    
    # possibility 7:
    if selected_options1 == 'all city' and selected_options2 != 'all district' and selected_options3 != 'all area':
        temp_list = list(set(df[(df.loc[:,'district'] == selected_options2) & (df.loc[:,'area'] == selected_options3)]['subarea'].to_list()))
        temp_list.insert(0, 'all subarea')
        return [{'label': i, 'value': i} for i in temp_list]
    
    # possibility 8:
    if selected_options1 != 'all city' and selected_options2 != 'all district' and selected_options3 != 'all area':
        temp_list = list(set(df[(df.loc[:,'city'] == selected_options1) & (df.loc[:,'district'] == selected_options2) & (df.loc[:,'area'] == selected_options3)]['subarea'].to_list()))
        temp_list.insert(0, 'all subarea')
        return [{'label': i, 'value': i} for i in temp_list]
    
    
# -----------------------------
# configuration to prevent subarea dropdown menu error
@app.callback(dash.dependencies.Output('menu_subarea','value'),
              [Input('menu_subarea', 'options')])

def set_list(selected_options):
    return selected_options[0]['value']


#configuration callback button
@app.callback(dash.dependencies.Output('title_for_test','children'),
              [Input('button_show', 'n_clicks' )],
              [State('menu_city', 'value')],
              [State('menu_district', 'value')],
              [State('menu_area', 'value')],
              [State('menu_subarea', 'value')],
             multi=True)

def eksekusi(n_clicks, number1, number2, number3, number4):
    
    
    # provinsi
    if number1 == 'all city' and number2 == 'all district' and number3 == 'all area' and number4 == 'all subarea':
        return 'DEMOGRAFIC DATA OF MY STATE'
    
    
    # city / city
    if number1 != 'all city' and number2 == 'all district' and number3 == 'all area' and number4 == 'all subarea':
        return 'DEMOGRAFIC DATA OF ' + number1 + ' CITY'
        
        
    # district    
    if (number1 == 'all city' or number1 != 'all city') and number2 != 'all district' and number3 == 'all area' and number4 == 'all subarea':
        return 'DEMOGRAFIC DATA DISTRICT ' + number2 + ', CITY ' + search_city_from_district(number2)


    # area
    if (number1 == 'all city' or number1 != 'all city') and (number2 == 'all district' or number2 != 'all district') and number3  != 'all area' and number4 == 'all subarea':
        return 'DEMOGRAFIC DATA AREA ' + number3 ,html.Br(), 'DISTRICT ' + search_district_from_area(number3) +  ', CITY ' + search_city_from_area(number3)

    # subarea
    if (number1 == 'all city' or number1 != 'all city') and (number2 != 'all district' or number2 == 'all district') and (number3  != 'all area' or number3  == 'all area') and number4 != 'all subarea':
        return 'DEMOGRAFIC DATA SUBAREA ' + number4 + ', AREA ' + search_area_from_subarea(number4),html.Br(),'DISTRICT ' + search_district_from_subarea(number4) + ', CITY ' + search_city_from_subarea(number4)


if __name__ == "__main__":
    app.run_server(host='127.0.0.1', port='8051')

NOTE: because of the limitation of the characters, i delete what I already type before...

especially about drive you element manually like play a game (with keyboard), until you feel it's already in the right place, after that, view the perimeter, then copy it to your script.

it's play it, in inspect element (one of options menu that shown, when you right click the browser). by the way, i'm not delete the picture, i preview it below. hope you can imagine it.

next time if i already know how to callback the press button to change the graph in dashboard, i will post in answer section. here the picture that i used to explain some step that i already edit / delete because of limitation from stackoverflow.com. copy format style image1 edit by yourself, a helper menu will show image2

double-click the number after typing, raise or decrease the number value with up / down arrow from keyboard, the element will move, or change, base on raised / decreased value. after you feel match with your taste, see the value, copy to your code. that the easy way you set your code value.

so this is the list of my question that already answer.

  1. layout, i put a text top of every graph, but with a column section that separated it in to 2 section rows. ANSWERED
  2. how if one of the content is a map? ANSWERED
  3. how if under all the content and the map and the text, there is a layer, with a transparent color. ANSWERED
  4. how to create sidebar. ANSWRED
  5. how to make the title change if we press a button. ANSWERED.

new question:

  1. how to make not only title change, but the graph change to after press the button. because, multioutput of the callback is not easy to handle.
Wahyu Bram
  • 413
  • 1
  • 7
  • 13
  • 1
    You'll have better luck getting a useful answer if you show us what you've tried yourself. SO is not a forum where you can just leave a request like that and expect to be served a fully working example. Please learn [ask] a question and provide a code snippet with sample data. So go back to the answer you mentioned in your question, read a little more on plotly and then come back and show us what you've tried. There are many in here that are eager to help, but your question has to meet SO standards. Good luck and see you soon! – vestland Aug 30 '20 at 15:32
  • but how Tim Dunn can ask like that and me not? see this link: https://stackoverflow.com/questions/63592900/plotly-dash-how-to-design-the-layout-using-dash-bootstrap-components/63650724#63650724. I already give the link in my question. – Wahyu Bram Aug 30 '20 at 16:56
  • 1
    Fair question. Tims question is arguably off-topic too. But that question was at least more focused, and possible to answer with a more general example. You, on the other hand, are asking SO users to deliver a very specific and detailed setup without providing some sample data or showing any effort to solve your problem ypurself. So while Tims question does not meet *some* of the SO question requirements, your question hardly meets *any at all*. Again, please look at [ask] and things will become much more clear to you. – vestland Aug 30 '20 at 17:43
  • I'm sorry before..., if i make uncomfortable, but in that link, I try to continue the topic with asking, a continous step of the Tim question after the Khristian Haga answer. but https://stackoverflow.com/users/4099593/bhargav-rao, delete my question. what I mean is, I'm asking similar with Tim, the different is, how to put a layer under all the graph that Kristian make and how to set the topic change base the dropdown menu choice. I put the question in the answer section to make sure Kristian see it, and hope he answer it. – Wahyu Bram Aug 30 '20 at 18:50
  • Ok, i follow your advise.... I edit the question... – Wahyu Bram Aug 30 '20 at 19:33

0 Answers0