-
Is there a way to add image carousels in a Dash Application? I didn’t see any component in Dash Libraries that would work.
-
I’d like to add a carousel to
Modal
pop-up. Would this be possible to do?
Hi @keval
There is an image carousel in the latest release of Dash Bootstrap Components v0.13.0. Here is the announcement:
@AnnMarieW Is there an example you can share that updates the items
property of the carousel from callback? I didn’t see it in the docs.
Hi @keval
Currently the items
prop can’t be updated once the Carousel
is animating. This may be a bug - I’ll investigate.
The workaround is to return an updated Carousel
to the children
prop of an html.Div
. Here is a mwe:
import dash
from dash.dependencies import Input, Output
import dash_bootstrap_components as dbc
import dash_html_components as html
app = dash.Dash(__name__, external_stylesheets=[dbc.themes.DARKLY])
img_style = {"height": "600px", "width": "800px"}
img1 = "https://user-images.githubusercontent.com/72614349/128213790-aaebac53-2e6d-4d20-a41d-647dc0a563d3.jpg"
img2 = "https://user-images.githubusercontent.com/72614349/128213795-e0eff265-2bda-48c7-b89b-0863dd582650.jpg"
img3 = "https://user-images.githubusercontent.com/72614349/128213796-7d660ce6-3e63-4c53-8cf1-dab33ba1b514.jpg"
img4 = "https://user-images.githubusercontent.com/72614349/128245336-faae1bd9-47bb-404c-b8f2-7c94ad981222.jpg"
carousel1 = dbc.Carousel(
items=[{"key": "1", "src": img1}, {"key": "2", "src": img2}],
controls=True,
indicators=True,
style=img_style,
)
carousel2 = dbc.Carousel(
items=[{"key": "3", "src": img3}, {"key": "4", "src": img4}],
controls=True,
indicators=True,
style=img_style,
)
app.layout = dbc.Container(
[
dbc.Row(
dbc.Col(
[
dbc.Button("Change slideshow", id="toggle", n_clicks=0),
html.Div(id="carousel"),
]
)
),
],
fluid=True,
)
@app.callback(
Output("carousel", "children"), Input("toggle", "n_clicks"),
)
def update_carousel(n):
if n % 2 > 0:
return carousel2
return carousel1
if __name__ == "__main__":
app.run_server(debug=True)
Thanks @AnnMarieW
For context, here’s my use case.
I have a bunch of geo-location, represented by black-dots in the attached GIF. Upon clicking each dot, a modal pop-ups with information about the location. I have added a image carousel (currently static images) to the modal pop-up.
I’d like these to be dynamic based on the location.
dbc.Modal(
[
dbc.ModalHeader("Lease Information", style={"color":"white"}),
dbc.ModalBody(
[
# Images
dbc.Carousel(
id="images",
items=[
{"key": "1", "src": "https://gmaps-images"},
{"key": "2", "src": "https://gmaps-images"},
{"key": "3", "src": "https://gmaps-images"},
],
controls=True,
indicators=True,
),
dbc.Label("Address:", style={"color":"white", "margin-right":"10px"}),
dbc.Label("Address:", id="Address"),
html.Br(),
]
),
dbc.ModalFooter(
[
dbc.Button("OK", className="mr-1"),
]
),
],
id="modal-1",
),
Say, we have a dictionary of location and associated images
img_dict = {'location 1': ['link to img1', 'link to img2'],
'location 2': ['link to img3', 'link to img4'] }
Now, I’d like to populate the items
property of the dbc.Carousel
from the callback, where the input to the callback function is click event and it looks up the values (images) of the location in the img_dict
@application.callback([
Output("modal-1","is_open"),
Output("carousel-1", "items"),
],
[
Input("map-graph","clickData"),
Input("close","n_clicks")
],
[
State("modal-1", "is_open")
],
)
def update_carousel(clickData, modal_close, is_open):
# click event for black dots on map-graph
if clickData:
res = json.dumps(clickData, indent=2)
Address = clickData["points"][0]["customdata"]["Address"]
list_of_images = img_dict[Address]
return (Address, list_if_images)
Is this currently possible to do? The workaround you have will require dbc.Carousel
object for each point/location on the map which could be into 100s.
Hi @keval I don’t understand the callback you posted - are there typos? There is no @app.callback and it looks like the return is only if clickData is None
?
But I think this callback should work per the mwe I posted. Try putting a html.Div(id="carousel")
in the dbc.ModalBody(...)
instead of dbc.Carousel(...)
.
Then in the callback change
Output("carousel-1", "items"),
to:
Output(“carousel”, “children”),
then include in the callback function:
carousel = dbc.Carousel(
items=img_dict[Address]
controls=True,
indicators=True,
)
return Address, carousel
Sorry about the typos. I was trying to minimize the number of lines of code for simplicity.
The callback should make sense now. Basically, I’d like to pass a list of string of images to items
property of the dbc.Carousel
.
I’ll try your recommended approach.
ok, and be sure that items
is formatted correctly for the Carousel. It needs to be a list of dicts like the following. It does’t look like img_dict[Address]
does that.
items=[
{"key": "1", "src": "https://gmaps-images"},
{"key": "2", "src": "https://gmaps-images"},
{"key": "3", "src": "https://gmaps-images"},
],
More of a general question but related to constructing list of dicts for carousel.
Is there a way to pass data / objects between the callbacks? I have used dcc.Store
to store the value of inputs
.
However, in this case, I am constructing a dictionary (for items property of carousel) in a different callback, but would like to reference it / do lookup in a separate callback.
How would you recommending doing something like that? Ideally, would like to not rewrite the code and reuse constructed objects like DataFrames, dictionaries, lists etc.
@keval Yes, using dcc.Store
is the recommended way to share data between callbacks. This should work well. A dictionary can be stored in the data
property of the dcc.Store
Hi @Reinger and welcome to the Dash community
Rather than using the Carousel
, it sounds like you are looking for a before and after image slider. If so check out this post: Image slider in Dash - #14 by Emil
You can find this component in @Emil’s Dash Extensions library
A post was split to a new topic: Storing a DataFrame in dcc.Store