Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
This repository was archived by the owner on Aug 29, 2025. It is now read-only.

Dash Tabs component #74

Closed
chriddyp wants to merge 86 commits into upload from tabs
Closed

Dash Tabs component #74

chriddyp wants to merge 86 commits into upload from tabs

Conversation

Copy link
Member

@chriddyp chriddyp commented Sep 14, 2017

No description provided.

randiaz95, LusterLeung, ricklentz, and vitasiku reacted with thumbs up emoji
Copy link
Member Author

mayijun, randiaz95, rodrigosnader, vitasiku, nico-vromans, and lawlietsoul reacted with thumbs up emoji danielfrg, chriddyp, chuckpr, will-franceys-depop, bolokoz, wphan, chinobing, aagostini-tada, amyoshino, JiayuanGuo, and 10 more reacted with hooray emoji

Copy link
Member Author

Copy link
Member Author

Try it out on the pre-release channel with

pip install dash-core-components==0.13.0-rc4

That example above:

import dash
from dash.dependencies import Input, Output
import dash_core_components as dcc
import dash_html_components as html
from loremipsum import get_sentences
app = dash.Dash()
app.scripts.config.serve_locally = True
app.layout = html.Div([
 dcc.Tabs(
 tabs=[
 {'label': 'Tab {}'.format(i), 'value': i} for i in range(1, 5)
 ],
 value=3,
 id='tabs'
 ),
 html.Div(id='tab-output')
], style={
 'width': '80%',
 'fontFamily': 'Sans-Serif',
 'margin-left': 'auto',
 'margin-right': 'auto'
})
@app.callback(Output('tab-output', 'children'), [Input('tabs', 'value')])
def display_content(value):
 data = [
 {
 'x': [1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012],
 'y': [219, 146, 112, 127, 124, 180, 236, 207, 236, 263,
 350, 430, 474, 526, 488, 537, 500, 439],
 'name': 'Rest of world',
 'marker': {
 'color': 'rgb(55, 83, 109)'
 },
 'type': ['bar', 'scatter', 'box'][int(value) % 3]
 },
 {
 'x': [1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012],
 'y': [16, 13, 10, 11, 28, 37, 43, 55, 56, 88, 105, 156, 270,
 299, 340, 403, 549, 499],
 'name': 'China',
 'marker': {
 'color': 'rgb(26, 118, 255)'
 },
 'type': ['bar', 'scatter', 'box'][int(value) % 3]
 }
 ]
 return html.Div([
 dcc.Graph(
 id='graph',
 figure={
 'data': data,
 'layout': {
 'margin': {
 'l': 30,
 'r': 0,
 'b': 30,
 't': 0
 },
 'legend': {'x': 0, 'y': 1}
 }
 }
 ),
 html.Div(' '.join(get_sentences(10)))
 ])
if __name__ == '__main__':
 app.run_server(debug=True)
radumas and jackparmer reacted with hooray emoji radumas, hermish, guenp, rafaelBadan, hanmq, Seedarchangel, amyoshino, oscarbatori, jackparmer, vitasiku, and shoegazerstella reacted with heart emoji

@chriddyp chriddyp changed the title (削除) first pass at a Tabs component (削除ここまで) (追記) Dash Tabs component (追記ここまで) Sep 14, 2017
Copy link
Member Author

Vertical view
tabs-vertical

timskovjacobsen and kts12345 reacted with thumbs up emoji

Copy link

TheoLvs commented Sep 15, 2017

Awesome ! Thank you very much

Copy link

Hey Chris, looking great! Tabs & Upload have taken Dash to the next level!

How did you get the tabs on the left-hand side? Had a look through the source, but struggling to figure it out.

Copy link
Member Author

@richard-muir Sorry about that! I forgot to publish my latest commits.
Here is the latest example:

pip install dash-core-components==0.13.0-rc5
pip install loremipsum
import dash
from dash.dependencies import Input, Output
import dash_core_components as dcc
import dash_html_components as html
from loremipsum import get_sentences
app = dash.Dash()
app.scripts.config.serve_locally = True
vertical = True
if not vertical:
 app.layout = html.Div([
 dcc.Tabs(
 tabs=[
 {'label': 'Market Value', 'value': 1},
 {'label': 'Usage Over Time', 'value': 2},
 {'label': 'Predictions', 'value': 3},
 {'label': 'Target Pricing', 'value': 4},
 ],
 value=3,
 id='tabs',
 vertical=vertical
 ),
 html.Div(id='tab-output')
 ], style={
 'width': '80%',
 'fontFamily': 'Sans-Serif',
 'margin-left': 'auto',
 'margin-right': 'auto'
 })
else:
 app.layout = html.Div([
 html.Div(
 dcc.Tabs(
 tabs=[
 {'label': 'Market Value', 'value': 1},
 {'label': 'Usage Over Time', 'value': 2},
 {'label': 'Predictions', 'value': 3},
 {'label': 'Target Pricing', 'value': 4},
 ],
 value=3,
 id='tabs',
 vertical=vertical,
 style={
 'height': '100vh',
 'borderRight': 'thin lightgrey solid',
 'textAlign': 'left'
 }
 ),
 style={'width': '20%', 'float': 'left'}
 ),
 html.Div(
 html.Div(id='tab-output'),
 style={'width': '80%', 'float': 'right'}
 )
 ], style={
 'fontFamily': 'Sans-Serif',
 'margin-left': 'auto',
 'margin-right': 'auto',
 })
@app.callback(Output('tab-output', 'children'), [Input('tabs', 'value')])
def display_content(value):
 data = [
 {
 'x': [1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012],
 'y': [219, 146, 112, 127, 124, 180, 236, 207, 236, 263,
 350, 430, 474, 526, 488, 537, 500, 439],
 'name': 'Rest of world',
 'marker': {
 'color': 'rgb(55, 83, 109)'
 },
 'type': ['bar', 'scatter', 'box'][int(value) % 3]
 },
 {
 'x': [1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012],
 'y': [16, 13, 10, 11, 28, 37, 43, 55, 56, 88, 105, 156, 270,
 299, 340, 403, 549, 499],
 'name': 'China',
 'marker': {
 'color': 'rgb(26, 118, 255)'
 },
 'type': ['bar', 'scatter', 'box'][int(value) % 3]
 }
 ]
 return html.Div([
 dcc.Graph(
 id='graph',
 figure={
 'data': data,
 'layout': {
 'margin': {
 'l': 30,
 'r': 0,
 'b': 30,
 't': 0
 },
 'legend': {'x': 0, 'y': 1}
 }
 }
 ),
 html.Div(' '.join(get_sentences(10)))
 ])
if __name__ == '__main__':
 app.run_server(debug=True)
Akronix, amyoshino, SerDiaz, eloiup, Abhishekmamidi123, bustamania, and stenpiren reacted with heart emoji

Copy link

dotsdl commented Sep 19, 2017

Awesome @chriddyp! This is really going to make some incredible things possible with relatively little effort.

chriddyp, richard-muir, bolokoz, antonbakh, and gaw89 reacted with heart emoji

Copy link
Member Author

I have pushed v0.13.0rc8 to include the fixes from v0.12.7

Copy link
Member Author

chriddyp commented Nov 2, 2017

I have rebased this branch off of the latest version. Try this out with pip install dash-core-components==0.15.0rc1

Klimmy, ned2, 34code, lanreogun, jeanmidevacc, thomasmarshbintel, and sharpe5 reacted with thumbs up emoji radumas, amyoshino, and jeanmidevacc reacted with hooray emoji

Copy link

mtreu commented Nov 13, 2017
edited
Loading

This looks awesome! However, is there a way to change the color of a tab?

charliepowell, mewais, pmercatoris, emasontl, and mkhorton reacted with thumbs up emoji

Copy link

jbrav commented Nov 15, 2017
edited by chriddyp
Loading

Hey, @chriddyp thank you very much. I am trying to actually get different data on each tab. I am quite new in Python, but so far I have tried the following.

import dash
from dash.dependencies import Input, Output
import dash_core_components as dcc
import dash_html_components as html
from loremipsum import get_sentences
app = dash.Dash()
app.scripts.config.serve_locally = True
app.layout = html.Div([
 dcc.Tabs(
 tabs=[
 {'label': 'Tab {}'.format(i), 'value': i} for i in range(1, 4)
 ],
 value=4,
 id='tabs',
 ),
 html.Div(id='tab-output')
], style={
 'width': '80%',
 'fontFamily': 'Sans-Serif',
 'margin-left': 'auto',
 'margin-right': 'auto'
})
@app.callback(Output('tab-output', 'children'), [Input('tabs', 'value')])
def display_content(value):
 data = [
 {
 'x': [1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017],
 'y': [42, 41, 64, 54, 12, 54, 69, 12, 76, 35, 68,86, 56, 57, 65, 43, 91,85,12, 59, 76, 14, 16, 28, 40, 56, 52, 78,75, 67, 12, 52, 75, 43, 52, 54, 64, 62, 68],
 'name': 'Schroders',
 'marker': {
 'color': 'rgb(54, 82, 110)'
 },
 'type': ['bar', 'scatter'][int(value) % 2]
 },
 {
 'x': [1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017],
 'y': [52, 51, 74, 64, 22, 44, 59, 32, 16, 65, 18,16, 16, 27, 35, 13, 11,25,72, 19, 96, 64, 96, 68, 10, 96, 82, 18,25, 37, 72, 12, 25, 13, 32, 14, 24, 12, 98],
 'name': 'MSF ',
 'marker': {
 'color': 'rgb(26, 118, 255)'
 },
 'type': ['bar', 'scatter'][int(value) % 2]
 },
 {
 'x': [1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017],
 'y': [32, 11, 84, 94, 62, 14, 79, 52, 16, 15, 98,26, 36, 47, 15, 83, 31,45,22, 69, 16, 74, 46, 98, 70, 16, 22, 38,45, 17, 42, 22, 35, 83, 72, 44, 94, 22, 60],
 'name': 'OMS',
 'marker': {
 'color': 'rgb(55, 83, 109)'
 },
 'type': ['bar', 'scatter'][int(value) % 2]
 },
 ],
def muestra_contenido(value):
 data1 = [
 {
 'x': [1940, 1950, 1960, 1970],
 'y': [1, 2, 3, 4],
 'name': 'test1',
 'marker': {
 'color': 'rgb(60, 41, 200)'
 },
 'type': ['bar', 'scatter'][int(value)%2]
 },
 {
 'x': [1940, 1950, 1960, 1970],
 'y': [5, 6, 7, 8],
 'name': 'test2',
 'marker': {
 'color': 'rgb(61, 42, 201)'
 },
 'type': ['bar', 'scatter'][int(value)%2]
 }
 ],
 return html.Div [(
 dcc.Graph(
 id='graph',
 figure={
 'data': data,
 'layout': {
 'margin': {
 'l': 30,
 'r': 0,
 'b': 30,
 't': 0
 },
 'legend': {'x': 0, 'y': 1}
 }
 }
 ),
 html.Div('Estoy haciendo una prueba para ver como funcionaria esto')
 )],
 return html.Div([
 dcc.Graph(
 id='graph1',
 figure={
 'data': data1,
 'layout': {
 'margin': {
 'l': 30,
 'r': 0,
 'b': 30,
 't': 0
 },
 'legend': {'x': 0, 'y': 1}
 }
 }
 ),
 html.Div('Estoy haciendo una prueba para ver como funcionaria esto')
 ])
if __name__ == '__main__':
 app.run_server(debug=True)

I would love if you could point where my error is. I have also tried to create another label, without success as it is apparent .

appym reacted with thumbs up emoji

Copy link
Member Author

@jbrav - Would you mind asking this implementation question in the dash community forum? https://community.plot.ly/c/dash. That'll keep things a little bit more organized for me and you're likely to get more people to help you out there. Thanks!

Copy link
Member Author

I've made a new prerelease off of master. Get the latest with:

pip install dash-core-components==0.21.0rc1

And check your version with:

>>> import dash_core_components as dcc
>>> print(dcc.__version__)
0.21.0rc1
dadokkio, HikingDev, weber-s, vantaka2, Ruckusist, anmmedinabe, rmarren1, jackparmer, and QCTW reacted with thumbs up emoji rmarren1 and jackparmer reacted with hooray emoji ColasDroin, radumas, rmarren1, and jackparmer reacted with heart emoji

Copy link

@chriddyp Do you think there's a way for dccs within tabs to remain active even if the tab isn't selected?

Here's a toy example of what I'm thinking:

import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
app = dash.Dash(__name__, static_folder='assets')
server = app.server
app.scripts.config.serve_locally=True
app.css.config.serve_locally=True
app.config['suppress_callback_exceptions']=True
app.layout = html.Div([
 dcc.Tabs(tabs = [
 {'label': 'Tab 1', 'value': 1},
 {'label': 'Tab 2', 'value': 2}
 ], id='tabs', value = 1),
 html.Div([], id='tab_output'),
 html.Div([], id='output')
])
@app.callback(
 Output('tab_output', 'children'),
 [Input('tabs', 'value')]
)
def show_dropdowns(value):
 if value == 1:
 return dcc.Dropdown(options = [
 {'label': 'A', 'value': 'A'},
 {'label': 'B', 'value': 'B'}
 ], id='dropdown1', value = 'A')
 if value == 2:
 return dcc.Dropdown(options = [
 {'label': 'C', 'value': 'C'},
 {'label': 'D', 'value': 'D'}
 ], id='dropdown2', value = 'C')
@app.callback(
 Output('output', 'children'),
 [Input('dropdown1', 'value'), Input('dropdown2', 'value')]
)
def format_text(d1, d2):
 return 'Your first dropdown says {} and your second dropdown says {}'.format(d1, d2)
if __name__ == '__main__':
 app.run_server(debug=True)

Ideally I'd like a user to be able to make selections in each tab, and have the main output draw from both tabs.

Something like this doesn't work now because the tabs change the layout, and it's impossible for both dccs to exist at the same time.

Copy link
Member Author

@charleyferrari - All of the inputs of a callback need to be visible in the layout at the same time in order for them to fire the callback. You could keep them layout by just toggling the visibility, like:

app.layout = html.Div([
 dcc.Tabs(...),
 dcc.Dropdown(id='dropdown1', style={'display': 'none'}, ...)
 dcc.Dropdown(id='dropdown2', style={'display': 'none'}, ...)
])
@app.callback(Output('dropdown1', 'style'), [Input('tabs', 'value')])
def update_dropdown(value):
 return {'display': 'block' if value == 1 else 'none'}
@app.callback(Output('dropdown2', 'style'), [Input('tabs', 'value')])
def update_dropdown(value):
 return {'display': 'block' if value == 2 else 'none'}

Copy link

Is there was a way to use Tabs offline? I would like to create an HTML dashboard with plots arranged in tabs which I can email to people who don't have Python installed (due to security requirements I also cannot use Dash server).

This can be done using Bokeh but I would prefer using Plotly as it's much more user friendly. Any help would really be appreciated. Thanks

@chriddyp

Copy link
Member Author

Is there was a way to use Tabs offline? I would like to create an HTML dashboard with plots arranged in tabs which I can email to people who don't have Python installed (due to security requirements I also cannot use Dash server).

This is a separate issue than what is presented in this PR. In any case, this isn't possible now with Dash but it will be in the future. There is a WIP PR here: plotly/dash-renderer#7

Forander reacted with thumbs up emoji

Copy link

Thanks for the quick response Chris. What would you suggest if I'm looking to create something like this? Is it possible to arrange something myself by saving Plotly plots as divs?

Copy link
Member Author

Thanks for the quick response Chris. What would you suggest if I'm looking to create something like this? Is it possible to arrange something myself by saving Plotly plots as divs?

Can you ask this in the community forum? https://community.plot.ly/c/dash. The discussion in this thread should be related to this PR.

Forander reacted with thumbs up emoji

Copy link

This is an extremely useful PR, congrats @chriddyp ! Can we maybe have a (rough) estimation of when this could be merged? I am interested in using it for a client facing application so I would feel a lot better using master!

gerdm reacted with thumbs up emoji WolVesz and Dimkoim reacted with heart emoji

Copy link

QCTW commented Apr 19, 2018
edited
Loading

Thanks for the great work. @chriddyp

I encountered one problem when I tried to place an upload component (https://dash.plot.ly/dash-core-components/upload) inside a tab, it can not properly display the upload block. If I don't put the upload component (the same codes) in the tab, the upload block can properly display...

Is this normal?

Copy link

ghost commented Apr 26, 2018

Hi Chris,
I am using the tabs in the vertical=True mode. (see screen shot) Why is my tab background color not extending past the original screen size - on the scroll down?
Is this a bug? Or, am I doing something wrong? I love the tabs addition, but without this background-color-extension on the scroll-down it makes it look un-professional.
Can you help?
Best regards,
~BB

image

image

Copy link

jen0liu commented May 2, 2018
edited
Loading

@chriddyp for Tabs, it's not included in the latest release (0.22). I had to revert back to an older version 0.21.rc01 which means I can't use some other new cool features people added to dash-core-component. Can you please see if you can merge to the latest branch? Thanks.

thomasmarshbintel, eliasdoehne, OleMussmann, AlexanderNadjalin, rodriguesmsb, RobertasStrazd, oriolmirosa, kyranstar, vantaka2, pixinixi, and 3 more reacted with thumbs up emoji

Copy link

If it can be merged that would be great since scattermapbox doesn't work with this branch and I love the tabs way too much.

Copy link

slash31 commented May 12, 2018

+1 on having this re-integrated into the train. Thanks for all of your hard work!

RagingRoosevelt, OleMussmann, zatreanu, rodriguesmsb, RobertasStrazd, mkhorton, kyleabeauchamp, garrettifland, and Nemecsek reacted with thumbs up emoji

Copy link

Major firepower with this tab pre release, the programming gods are happy :).

Copy link

I too am interested in seeing this PR updated for the latest release.

Copy link
Member Author

Thank you everyone so much for the reviews and feedback ❤️

We have incorporated this feedback into a new revision of the Tabs component here: #213.

thomasmarshbintel, Abhishekmamidi123, Nemecsek, alitarraf, and jacobkimmel reacted with thumbs up emoji thomasmarshbintel and jacobkimmel reacted with laugh emoji

Copy link

Hi Chris, ... can you help with a situation wherein i have to update real time using dcc.Interval as component-Interval is not part of 0.21.0rcxx .
Thanks in Advance.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

AltStyle によって変換されたページ (->オリジナル) /