Quantcast
Channel: 🎛️ Dash - Plotly Community Forum

DataTable: How to filter a boolean column?

$
0
0

Hello,

I have a Dash DataTable with a column that contains a boolean value:

image

The original values were 0 and 1 but I transformed them into the X n V emojis shown for a better UX.

I have native filtering enabled on my DataTable. How can I let users filter by X or V? Is there a way for me to replace the default text filter with a dropwdown list? Or 2 radio buttons?

Can I get this done without having to dive into React and overriding the relevant React components?

Thanks,
urig

PS - I’ve tried setting the value using a custom javascript script but the results is that I see that the value is set, filtering doesn’t work and after a second, the value is erased (?!)

window.setTimeout(work, 2000)

function work() {
  filter = document.querySelector('*[class="dash-filter column-5"] div input[type="text"]')
  filter.value = "✔️";
}

2 posts - 2 participants

Read full topic


Validate coordinates (points) within a polygon

$
0
0

Friends I am working on a map made with Dash-Leaflet but it turns out that I am capturing data with
EditControl from the frontend, I capture that data from the callback, I store that information in the browser’s memory and pass it to a function to later be able to validate if within those polygons there is any point that I have in another list, I am investigating the documentation and I can’t find how to perform that validation, I need help.

I have an example in geopandas that works, but geopandas is very heavy and the server is frozen, I hope you can help me find the best way so that the code does not saturate the server.


pdv_geo = gpd.GeoDataFrame(pdv, geometry=gpd.points_from_xy(pdv.Longitud, pdv.Latitud))

cities = pdv_geo.sjoin(barrios, how="left", predicate='intersects')

resuelt = cities.drop(columns=["GLOBALID", "Shape_Length", "Shape_Area", "SCATIPO", "index_right"])

resuelt.to_excel("dataset/datos_unificados_completos.xlsx", index=False, sheet_name="pdv")

1 post - 1 participant

Read full topic

Dash 2.x Feature Preview: Simplified callbacks

$
0
0

Hey Dash Community,

I’m excited about some new features we’re working on to make callbacks easier, more concise and use less boilerplate. I have a pull request in the works and would love to get some community feedback while it’s under review. Helpful questions to think about:

  1. Do you prefer the new features or the current way? why?
  2. Is there anything is the new features you found confusing?
  3. Anything that can be improved?

Improvements

  • Simplifies the syntax for determining which input triggered a callback.
  • Makes code more concise by adding ctx as an alias for dash.callback_context
  • Adds the convenience of using dot notation to access the ctx dictionary
  • Simplifies the callback function signature for callbacks with many Inputs.
  • Makes it easier to get the dictionary ids when using pattern matching callbacks.

Background

Currently, when you have multiple Inputs in a callback, you might do something like this to determine which input triggered the callback:

@callback(
    Output("graph", "figure"), Input("btn-1", "n_clicks"), Input("btn-2", "n_clicks")
)
def display(btn1, btn2):
    ctx = dash.callback_context
    button_id = ctx.triggered[0]['prop_id'].split('.')[0]

    if button_id == "btn-1":
         return update_graph1()
    if button_id == "btn-2":
         return update_graph2()

One of the goals is to eliminate boilerplate such as:

ctx = dash.callback_context
button_id = ctx.triggered[0]['prop_id'].split('.')[0]

:point_right: Introducing: dash.ctx

ctx is an new concise name for dash.callback_context`. It’s convenient to include with the import statements like this:

from dash import Dash, html, Input, Output, ctx

Now you can eliminate this line of code

ctx = dash.callback_context

:point_right: Introducing: ctx.triggered_ids

You can use the new ctx.triggered_ids dictionary to see which input triggered the callback:

Tada: No boilerplate!

@callback(
    Output("graph", "figure"), Input("btn-1", "n_clicks"), Input("btn-2", "n_clicks")
)
def display(btn1, btn2):
   if  "btn-1.n_clicks" in ctx.triggered_ids:
       return update_graph1()
   if  "btn-2.n_clicks" in ctx.triggered_ids:
      return update_graph2()

ctx.triggered_ids is a dictionary of the component ids and props that triggered the callback.
When using pattern matching callbacks, it also has the dictionary form of the ids rather than just the stringified version with no white spaces that’s available currently.

ctx.triggered_ids:

  • keys (str) : the “prop_id”, composed of the component id and the prop name
  • values (str or dict): component id.

For example, with regular callback, the ctx.triggered_ids dict would look something like:

{"btn-1.n_clicks": "btn-1"}

With pattern matching ids:

{'{"index":0,"type":"filter-dropdown"}.value': {"index":0,"type":"filter-dropdown"}}


:point_right: Introducing: ctx.args_grouping

Sure, the above syntax using the new ctx.triggered_ids is an improvement, but wouldn’t in be great if you could use a variable name instead of the component id and prop string? Maybe something like:

if variable_name.triggered:
     do_something()

Well, now you can! By using flexible callback signatures and the new ctx.args_grouping, your callback can look like this:

@app.callback(
    Output("container", "children"),
    inputs=dict(btn1=Input("btn-1", "n_clicks"), btn2=Input("btn-2", "n_clicks")),
)
def display(btn1, btn2):
    c = ctx.args_grouping
    if c.btn1.triggered:
        return f"Button 1 clicked {btn1} times"
    elif c.btn2.triggered:
        return f"Button 2 clicked {btn2} times"
    else:
        return "No clicks yet"

ctx.args_grouping is a dict of the inputs used with flexible callback signatures. The keys are the variable names and the values are dictionaries containing:

  • “id”: (string or dict) the component id. If it’s a pattern matching id, it will be a dict.
  • “id_str”: (str) for pattern matching ids, it’s the strigified dict id with no white spaces.
  • “property”: (str) The component property used in the callback
  • “value”: the value of the component property at the time the callback was fired
  • “triggered”: (bool)Whether this input triggered the callback

So, in the above example, if you click the Button 1, then ctx.args_grouping would contain:

{
    'btn1': {'id': 'btn-1', 'property': 'n_clicks', 'triggered': True, 'value': 1},
    'btn2': {'id': 'btn-2',   'property': 'n_clicks', 'triggered': False,  'value': None}
}

:point_right: New: Access the ctx.args_grouping dict with a dot notation:

To get the value of the callback Input, wouldn’t you rather type c.btn1.value than c["btn1"]["value"]?

c = ctx.args_grouping

# get the prop values like this:
c["btn1"]["value"]

# Or you can use the dot notation:
c.btn1.value

# See if it triggered the callback like this:
if c.btn1.triggered:
   do_something()


:cake: Simplified callback function signature

Here’s my favorite thing about the new ctx.args_grouping: You don’t need to repeat all the variable names in the callback function. This is super convenient when you have a large callback with many inputs.

See issue #1810 Feature Request: Support Dash callback closer to function signature
and the related discussion on the forum: Proposal: New callback syntax closer to function signature

I think this can also make learning callbacks easier for people new to Dash. There is often confusion around how variables are named in the function, as discussed in this post Newbie finds naming snobbish

In the example below note that:

  • all_inputs is the only arg in the callback function:
  • The variable names are beside each input under the callback decorator

@app.callback(
    Output("container", "children"),
    inputs={
        "all_inputs": {
            "btn1": Input("btn-1", "n_clicks"),
            "btn2": Input("btn-2", "n_clicks"),
            "btn3": Input("btn-3", "n_clicks"),
            "dropdown1": Input("dropdown-1", "value"),
            "dropdown2": Input("dropdown-2", "value"),
            "store": State("store", "data"),
        }
    },
)
def display(all_inputs):
    c = ctx.args_grouping.all_inputs  

    if c.btn1.triggered:
        return f"Button 1 clicked {c.btn1.value} times"
    elif c.btn2.triggered:
        return f"Button 2 clicked {c.btn2.value} times"
   #  ... etc
    else:
        "no update"




:cake: Easier to get the dict id when using pattern matching callbacks.

When using pattern matching callbacks, it’s often necessary to get the component’s dictionary id in a callback. However, the current dash.callback_context.triggered only has the "prop_id" which is a stringified dictionary with no white space.
To turn it back into a real Python dictionary, it’s necessary to parse the string and use json loads.

Here is an example of the current dash.callback_context.triggered.

[
  {
    'prop_id': '{"index":0,"type":"filter-dropdown"}.value',
    'value': 'NYC'
  }
]

Skip the string parse and json loads! Instead, use either of the new ctx.triggered_ids or ctx.args_grouping to get the index of the button that triggered the callback.

Example 1: ctx.triggered_ids

import numpy as np
import plotly.express as px
from dash import Dash, Input, Output, ctx, dcc, html, ALL

N=5

app = Dash(__name__)


def make_figure(n):
    x = np.linspace(0, 8, 81)
    y = x ** int(n)
    return px.scatter(x=x, y=y)


app.layout = html.Div(
    [
        html.Div(
            [html.Button(f"x^{i}", id={"index":i}) for i in range(N)]
        ),
        dcc.Graph(id="graph"),
    ]
)

@app.callback(
    Output("graph", "figure"), Input({"index":ALL}, "n_clicks")
)
def update_graph(btns):
    if ctx.triggered:
        
        # This gets the key, which is the stringified dict id: "  
        prop_id=ctx.triggered_ids.first()
        
        # This gets the value which is the component's dictionary `id`:
        dict_id= ctx.triggered_ids[prop_id]
        
        # This gets the index number of the button the triggered the callback.  
        n= dict_id.index
        
        return make_figure(n)
    return {}


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

More info on .first()

.first() is a handy method that’s available with the ctx.triggered_ids dictionary.
It acts like .get() but if it has no arguments it returns the first key.


Example 2: ctx.args_grouping

Here is the same app, but instead it uses the new ctx.args_grouping to get the index of the button that triggered the callback:

import numpy as np
import plotly.express as px
from dash import Dash, Input, Output, ctx, dcc, html, ALL

N=5

app = Dash(__name__)


def make_figure(n):
    x = np.linspace(0, 8, 81)
    y = x ** int(n)
    return px.scatter(x=x, y=y)


app.layout = html.Div(
    [
        html.Div(
            [html.Button(f"x^{i}", id={"index":i}) for i in range(N)]
        ),
        dcc.Graph(id="graph"),
    ]
)

@app.callback(
    Output("graph", "figure"), dict(btns=Input({"index":ALL}, "n_clicks"))
)
def update_graph(btns):
    # Since we are using {"index":ALL}, then
    # ctx.args_grouping.btns is a list of dicts - one dict for each button.
    for btn in ctx.args_grouping.btns:
        if btn.triggered:
            n = btn.id.index
            return make_figure(n)
    return {}


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



I’m looking forward to feedback on any or all of the new features proposed!

You can find the pull request here: Improved `callback_context` by AnnMarieW · Pull Request #1952 · plotly/dash · GitHub

3 posts - 2 participants

Read full topic

Using an icon (html.I) in a dbc.Alert results in a multiple values for argument 'id'

$
0
0

Probably a noob mistake but I am trying to set an Icon in front of my warning message and am following the example here Icons - dbc docs . The only difference is that I have an id defined and it is not in the examples.

dbc.Alert(
            [html.I(className="bi bi-check-circle-fill me-2")],
              'User data updated',
              id='user_update_alert',
              is_open=False,
              dismissable=True,
              fade=True,
              color="success",
              duration=2000
              ),

I end up getting an error

Traceback (most recent call last):
  File "...tw_mod\visualize\tw_user_navbar.py", line 114, in <module>
    dbc.Alert(
  File "D:\ProgramData\Anaconda3\lib\site-packages\dash\development\base_component.py", line 425, in wrapper
    return func(*args, **kwargs)
TypeError: __init__() got multiple values for argument 'id'

Is there something I am not understanding about the html.I component? The code runs fine without it.

2 posts - 2 participants

Read full topic

dcc.Input Auto Complete Issues and looking for tips and tricks

$
0
0

Hi, I am trying to create an dcc.Input or dbc.Input that has an autocomplete, I want the autocomplete to select from a list. I have added a list under html.Datalist(id=‘vars’, children=vars_, hidden=‘hidden’) where vars_ from children = vars_ is just a python list of strings for example [‘item1’, ‘item2’, ‘item3’, …]. I would like the autocomplete to select from this list but for some reason it is not working. Also, if possible I would like the user to be able to type item1, and then for item2 it brings up the same auto complete list ignoring the text before the comma. This isnt a must have, at this point I would be happy with just get the autocomplete working as it should. I have tried using a drop down but I want to be able to select the same item multiple times and the items will have a little bit of variation from what is in the list. Below is the code for the dcc.Input.

Also, If anyone knows of a good place I could find examples of components using all the different arguments that would be very helpful. A lot of the arguments say ( string ; optional) but don’t give examples of what a valid string or input would be.

dbc.InputGroup([ dcc.Input(id=‘parameter’, type=‘list’, autoComplete=True,list=‘vars’, autoFocus=True),
html.Datalist(id=‘vars’, children=vars_, hidden=‘hidden’)], size=“md”)

Thank you in advanced for any help!

2 posts - 1 participant

Read full topic

Border-left and border-right not work in style_data_conditional

$
0
0

I have a Datatable build with Dash Python. I am trying to set up the border-left for some columns in style_data_coditional. What I notice is that I am not able to set the border-left nor border-right. Although the border-top and border-bottom are set successfully in the callback function.
run_condition1 = {
“if”: {
“column_id”: id,
“filter_query”: “{” + str(id) + “} = ‘Run (1)\u0020’”,
},
“color”: “#5e9e4c”,
“fontWeight”: “bolder”,
“border-top”: “2px solid red”,
“border-bottom”: “2px solid red”,
“border-left”: “2px solid red”,
“border-right”: “2px solid red”,
}

        style_data_conditional.append(run_condition1)

image

This is the CSS in Chrome developer tool window:

I can manually add the border-left or border-right to element.style and it shows up in the datatable.
image
image

Does anybody know what’s going on here?

1 post - 1 participant

Read full topic

Texture Mapped VTK objects

$
0
0

Hi all,

I have been messing around with Dash VTK. I have been trying to figure out how to map images onto models. Does anyone have any examples of this in dash? I was able to do this in plain vtk but then I don’t think there’s a way to import a regular vtk actor into dash vtk.

Just looking to learn more about Dash VTK so any information or examples are appreciated.

1 post - 1 participant

Read full topic

Textarea not horizontally draggable

$
0
0

Hi all,

I am using a simple text area as:

html.Textarea(rows=5,cols=10)

(you can just put the above in any of your functional app.py)

I can drag it bigger vertically but not horizontally. Any idea what is wrong?

1 post - 1 participant

Read full topic


Go.Scatter Help - Plotting 2 numpy.ndarrays

$
0
0

Hello, sorry if this a double post but my first post disappeared when I tried to add a ‘tag’ and I may have deleted it.

I am having an issue plotting a visual in a DashApp that I am building - I am new to Python and Dash - just FYI that my mistake may be trivial, however it has me stuck for a few days now.

Let me explain the setup and then I will post the code. I am taking time series data and assigning it to a dataframe (there are more than one time series tags so I moved that to a dataframe and not just a single dimension list). This dataframe gets plotted and then one of the data signals, has a Fast Fourier Transform performed on it. This is a canned function, with some additional housekeeping, that appears to currently be working - I am left with 2 arrays which are ID’d as numpy.ndarrays and both have a length of 3590 elements. The values range from X = 0-50 and the Y = 16.1-16.4. I did not chop off any sig figs or round - maybe this is an issue?

Below are three snippets: first, the FFT function - this seems to work. Second, the layout - this setup also seems to work on another graphic. Third, the callback - I set this similar to my other go.scatter using the dataframe however in this case I am trying to plot the array - in this case the size is 3590 - in some other cases it may be larger / longer and comes from the FFT function.

Finally - I took this example from a tutorial: Beginner’s Guide to Building a Multi-Page App using Dash, Plotly and Bootstrap | by Meredith Wan | Towards Data Science
Giving credit and also mentioning - I changed the code and something I need but I am not sure exactly how it is being used is the line: dff = df[df.Period == Dia_Met_name]
I know that when I remove it - it does not work.

Thanks in advance.

FFT Function

dat=df0.values
N=dat.size-1
sample_rate=N/(df0.index.max()-df0.index.min()).total_seconds() # sample rate in points per seconds
duration=N/sample_rate
y=rfft(dat)
x=rfftfreq(2*N,1/sample_rate)
y2=np.abs(y)

Layout

dbc.Row([
    dbc.Col(html.H5(children='Discrete Fast Fourier Transform', className="text-center"),
            className="mt-4")
]),

dcc.Graph(id='fft_graph')
    ]),

Callback

@app.callback(
Output(‘fft_graph’, ‘figure’),
[Input(‘Dia_Met’, ‘value’)])
def update_fft(Dia_Met_name):
dff = df[df.Period == Dia_Met_name]

data = [go.Scatter(x = x[1:], y = y2[1:],
                   mode='markers', name='FFT')
]
layout = go.Layout(
    yaxis={'title':"Freq"},
    xaxis={'title':"X axis"}

)
return {'data': data, 'layout': layout}

2 posts - 1 participant

Read full topic

Is there a way to create a heatmap for a floor plan in Plotly?

$
0
0

Hi guys!

I’m wondering if is possible to create a heatmap folium like but withing a building floor plan. Something like the image below.


source: Creating a heat map in Live view Web | TIBCO Community

I’m an architect, and new to dash plotly (programming in general) but already managed to deploy one dashboard to heroku, and this is my next goal with this incredible library.

If you guys could give me some help e or advice, I would appreciate!

1 post - 1 participant

Read full topic

How to call setProps of a child component?

$
0
0

I would like to be able to edit some component properties of child components. Say for example that I want to create a wrapper component Wrapper that changes the value of some_prop to some_value of its child component (let’s assume that there is one and only one child for simplicity). I can do the edit itself like this,

const Wrapper = ({children}) => {
    children.props._dashprivate_layout.props.some_prop = "some_value"
    return <Fragment>{children}</Fragment>;
}

I have confirmed that it works if i read the value of some_prop from a callback in Dash. However, the value change does not cause a callback invocation.

I believe that what I essentially need to do is call setProps on the child object to invoke the callback - but is that possible at all? How could I do that? Maybe @chriddyp or @alexcjohnson knows?

Any ideas are welcome :slight_smile:

1 post - 1 participant

Read full topic

Issue plotting FFT from numpy.ndarray

$
0
0

I am having an issue when I try to generate a FFT of a data set and then plot this in a Dashapp using go.scatter() function. I am new to programming - please be gentle.

  1. Here is my function - it takes a dataframe that I already plot, performs an FFT and some housekeeping on the data and then provides a sample rate for the x axis. The two data arrays X and Y end up being 3590 in size and their type is numpy.ndarray. The function is pasted after the full comments for reference

  2. Below, I attached the layout - I use the exact same layout (with different names) to plot the time series data that is the base data set for the FFT. (please note that in this snippet - I included the graph that works (this is the top graph in the code) and the code for the graph that does not work - fft_graph. Thanks.

  3. Below that, I include the plot code - I try to use go.scatter and drop the array x=[1:] in order to plot the 3590 point array. When the graphic publishes, there is not data and only data point at the origin.

The x data ranges from 0-50 and the Y data is a frequency of roughly 16.1-16.4… There are many figs in the data - hardly any are significant, I could truncate the number quite a bit if this is the issue. Please note (I have tried other syntax of array calling, such as x=[1:10] or x=[1:3590] or x=[1] - all attempts fail to provide a visual - all attempts compile and load with no errors.

Thanks in advance…

Function Code (FFT)

dat=df0.values
N=dat.size-1
sample_rate=N/(df0.index.max()-df0.index.min()).total_seconds() # sample rate in points per seconds
duration=N/sample_rate
y=rfft(dat)
x=rfftfreq(2*N,1/sample_rate)
y2=np.abs(y)
print(len(x))
print(len(y2))
print(min(x), max(x))
print(min(y2), max(y2))
#print(x)
#print(y2)
print(type(x))
print(type(y2))

app.layout = dbc.Container([
dbc.Row([
        dbc.Col(html.H5(children='Focus Measurement - A Window in Time', className="text-center"),
                className="mt-4")
    ]),

    dcc.Graph(id='graph_by_period',
              hoverData={'points': [{'x': '11-May'}]}),


    dbc.Row([
        dbc.Col(html.H5(children='Discrete Fast Fourier Transform', className="text-center"),
                className="mt-4")
    ]),

    dcc.Graph(id='fft_graph')
        ]),
])

@app.callback(
    Output('fft_graph', 'figure'),
    [Input('Dia_Met', 'value')])
def update_fft(Dia_Met):
    #dfft = pd.DataFrame({'x': x, 'y': y})

    data = [go.Scatter(x=x[1:], y=y2[1:],
                       mode='lines', name='FFT')
    ]
    layout = go.Layout(
        yaxis={'title':"Freq"},
        xaxis={'title':"X axis"}

    )
    return {'data': data, 'layout': layout}

1 post - 1 participant

Read full topic

Checklist example doesn't work Dash 2.0

$
0
0

I’m trying to use examples from the documentation but the examples no longer work without extensive component definition. In checklist documentation this is given as the first exapmle:

dcc.Checklist(['New York City', 'Montreal', 'San Francisco'], 'Montreal')

But results in

Exception has occurred: TypeError
`id` prop must be a string or dict, not ['New York City', 'Montreal', 'San Francisco']

Even if I define the component attributes:

checklist1 = dcc.Checklist(id="checklist1", options=['New York City', 'Montreal', 'San Francisco'], value='Montreal')

I don’t see the options listed in my app:
Screenshot from 2022-03-09 08-06-07

However, this code works fine:

checklist1 = dcc.Checklist(
   options=[
       {'label': 'New York City', 'value': 'New York City'},
       {'label': 'Montreal', 'value': 'Montreal'},
       {'label': 'San Francisco', 'value': 'San Francisco'},
   ],
   value='Montreal'
)

So to use a valid checklist requires manually defining the label and value of each entry which is tedious and harder when I’m trying to teach beginners.

Any suggestions? I filed a bug report

1 post - 1 participant

Read full topic

How do you manage crossfiltering with multiple charts/filters?

$
0
0

I’ve been struggling with managing filters. By that, I mean that I have a data source with many fields. I have multiple charts, say, one for counts per year, another for counts per city, and another for counts per person (these are made up and I have many more in my real data). I want the user to be able to click the year bar chart to filter all the data shown to be from that year. For example, the user clicks the 2020 bar, and the city and person charts are showing data from only 2020. This works great. But then i want the user to be able to click a city, say Paris, and now only data from from 2020 in Paris is being shown in the person chart. However, when I do this, the year chart updates as well.

My questions is how do you manage crossfiltering in that way?

My current methods use a dcc.Store object to store the current filtered data, with a callback that is triggered when any of the charts are clicked. I know where my error is (clickData isn’t persistent, so when I click the city chart after the year chart, the year click is empty and thus it isn’t filtered for), but I feel like there must be an easier way?

1 post - 1 participant

Read full topic

Trigger a callback on dbc.Carousel change

$
0
0

Is it possible to trigger a callback when the active item of a dbc.Carousel is changed?

What I’m trying to do is add a link to the images of the carousel, and one way I thought might work is to wrap the whole thing in html.A and, when the active item of the carousel is changed, update the link and the carousel with the new active item. But I’m not sure what I should include as my input for the callback. I’m pretty sure you can do this using something like radio buttons to control the carousel, but I’d prefer to be able to use the internal controls of the carousel, if possible.

Thanks

1 post - 1 participant

Read full topic


Dash Cognito Auth Logout

$
0
0

Hi, I have managed to use this package here to authorize login for my users. However, I am having trouble designing a logout system.

So far, what I’ve done is code up the following method in the class defined here. It essentially calls the revoke endpoint documented here. The revoke endpoint returns a 200 response.

    def logout_request(self):
        if self.is_authorized():
            client_id = self.cognito_bp.client_id
            client_secret = self.cognito_bp.client_secret
            
            token = session.get("cognito_oauth_token")["refresh_token"]

            resp = cognito.post(
                "/oauth2/revoke",
                params={"token": token},
                headers={"Content-Type": "application/x-www-form-urlencoded"},
                auth=HTTPBasicAuth(client_id, client_secret)
                )
            assert resp.ok, resp.text
    
            del self.cognito_bp.token

            session.clear()

            return render_template("logout.html")

        else:
            return self.login_request()

Then, in the application.py folder, I have a Flask route defined:

@application.route("/logout", methods=["GET", "POST"])
def logout_user():
      return auth.logout_request()

However, for some reason, the system still keeps me logged in. I feel like I need to delete a cookie server side. Any ideas on how to accomplish this? Jumping ahead, how would I be able to design a multi page concept given that I have written an explicit server route for the “logout” endpoint?

1 post - 1 participant

Read full topic

Multiselect Dropdown with "Select All" option

$
0
0

I have 3 features: Region, Country and City. For simplicity I will keep the first 2 for now but I would like to apply the same logic to the City dropdown.

I have radioitems for regions: EMEA, APAC, Americas, All. I have a dropdown for country. The way I have it now is that the country dropdown will automatically update the options based on the user’s choice in the region (e.g. if user chooses APAC from the radio button, they can only see countries for APAC).

How can I add in the dropdown a Select All option? Bearing in mind that for some regions I have a lot of countries (ideally I want that when the user chooses Select All, I want just ‘All’ to be displayed in the dropdown rather then choosing a list of all countries.

This is the code I have so far:

# Create country options for regions
country_options = {
    'EMEA': ['France', 'Germany', 'Greece', 'Hungary', 'Italy', 'Kenya', 'Lithuania', 'Norway', 'Romania', 'Russia', 'South Africa', 'Spain', 'United Kingdom'],
    'APAC': ['Australia', 'China', 'Japan', 'New Zealand', 'Singapore', 'South Korea', 'Taiwan', 'Thailand'],
    'Americas': ['Canada', 'Chile', 'Colombia', 'United States'],
    'All': ['France', 'Germany', 'Greece', 'Hungary', 'Italy', 'Kenya', 'Lithuania', 'Norway', 'Romania', 'Russia', 'South Africa', 'Spain', 'United Kingdom', 'Australia', 'China', 'Japan', 'New Zealand',
            'Singapore', 'South Korea', 'Taiwan', 'Thailand', 'Canada', 'Chile', 'Colombia', 'United States']
}

# Region radioitems
html.Label('Region:'),
dcc.RadioItems(id='region_radio', className='radio',
               options=[{'label': str(c), 'value': c} for c in sorted(df['Region'].unique())] + [{'label': 'All regions' , 'value': 'All'}]),

# Country dropdown
html.Label('Country:'),
dcc.Dropdown(id='country_checklist',
             value=[],
             multi=True)


# CALLBACKS
# Update country checklist based on user input in region
@callback(
    Output('country_checklist', 'options'),
    Input('region_radio', 'value')
)
def set_country_options(selected_region):
    if not selected_region:
        return dash.no_update
    else:
        return [{'label': i, 'value': i} for i in sorted(country_options[selected_region])]

This is my output now:

image

I need to select all countries one by one. How can I add a select all option (also “Select All” is chosen, I just want the dropdown to read “All”, I don’t want to have the whole list displayed.

1 post - 1 participant

Read full topic

DashTable tooltip incorrectly displayed when using sort

$
0
0

The tooltip appears in the incorrect position after sorting the table. I ran a quick test using a snippet from DataTable Tooltips | Dash for Python Documentation | Plotly, and just added sort_action="native". How can this be resolved? Or any suggestions/workarounds?

from dash import Dash, dash_table

app = Dash(__name__)

app.layout = dash_table.DataTable(
    data=[
        {'shop': 'Bakersfield', 'sales': 4, 'goal': 10},
        {'shop': 'Berkeley', 'sales': 10, 'goal': 1},
        {'shop': 'Big Bear Lake', 'sales': 5, 'goal': 4}
    ],
    columns=[
        {'id': 'shop', 'name': 'Store Location'},
        {'id': 'sales', 'name': 'Sales Revenue'},
        {'id': 'goal', 'name': 'Revenue Goal'},
    ],
    tooltip_data=[
        {
            'shop': 'Location at Bakersfield',
            'sales': '$4M in Revenue',
            'goal': {'value': '6M **under** Goal', 'type': 'markdown'}
        },
        {
            'shop': 'Location at Berkeley',
            'sales': '$10M in Revenue',
            'goal': {'value': '9M **over** Goal', 'type': 'markdown'}
        },
        {
            'shop': 'Location at Big Bear Lake',
            'sales': '$5M in Revenue',
            'goal': {'value': '1M **over** Goal', 'type': 'markdown'}
        },
    ],
    tooltip_delay=0,
    tooltip_duration=None,
    sort_action="native",

)

if __name__ == '__main__':
    app.run_server(debug=True)

1 post - 1 participant

Read full topic

Allowing user to select what variables they want to see on a graph

$
0
0

Is there a way to allow users to choose what they want to be displayed on the graph?

Something similar to this:

So the graph initially loads with 1 and then if the user clicks 2 for example, the chart will become Rentable Area by Country rather than Annual Rent by Country.

Can someone please point me to the right direction of how I can achieve that with dash ? I tried using a button but it does not work as in the callback I already have a submit button to generate this graph.

2 posts - 2 participants

Read full topic

dcc.Dropdown increase the dropdown size

$
0
0

Hey guys, was wondering how to increase the dcc.Dropdown size so that it shows all the options rather than the first six and a vertical scrollbar as it is doing currently in the image attached

My current dcc.Dropdown is:

            dcc.Dropdown(
                id='jobsite-dropdown',
                className="control-dropdown",
                clearable=False,
                options=[{"label": config_builder.get_site_display_name(site), "value": site} for site in site_name_list],  #type:ignore
                style={'cursor': 'pointer'},
                value=job_site
            ),

In a normal html select tagi think you can specify a size attribute as follows:

<select name="cars" id="cars" size="3">

1 post - 1 participant

Read full topic

Page not found for Multipage app when running the code as a module

$
0
0

Dash version 2.2.0 and dash-labs is installed

I am creating a multipage app with the latest dash version and trying to execute the scripts as python package. I get an error of page not found even when the pages folder exists with the relevant .py files. However, when I run the file (app.py) as a script (from Pycharm’s Run button option in the IDE), the app works fine.

I am using the example from Adams github repo: Dash-by-Plotly/Dash_More_Advanced_Shit/Multipage_app at master · Coding-with-Adam/Dash-by-Plotly · GitHub

The folder hierarchy is:

├───folder1
│   ├───folder2
│   │   └───pages
│   │       app.py   

And I run the script as python -m folder1.folder2.app

Is there anything extra step to run the script as a module?

Note: I was already using dash all this time and running it as a module which worked fine. Now, I want to upgrade the app to multipage app.

Thanks!

1 post - 1 participant

Read full topic

Please help with Dash Cytoscape node position if possible

$
0
0

I am trying to learn Dash Cytoscape and wanted to perform the following:
generate a graph with networkx, apply a fruchterman-reingold algorithm to position the nodes, convert the data to the cytoscape format and display it in a Dash app. Here is the code:

""" from networkx
    to Dash cytoscape
    """
import dash_cytoscape as cyto
from dash import Dash, html
import networkx as nx

SCALING_FACTOR = 100  # try using to scatter nodes

app = Dash(__name__)

# 1) generate a networkx graph
G = nx.les_miserables_graph()

# 2) apply a netowrkx layouting algorithm
pos = nx.fruchterman_reingold_layout(G, k=0.1, iterations=2000, threshold=1e-10)

# 3) convert networkx graph to cytoscape format
cy = nx.cytoscape_data(G)

# 4.) Add the dictionary key label to the nodes list of cy
for n in cy["elements"]["nodes"]:
    for k, v in n.items():
        v["label"] = v.pop("value")

# 5.) Add the coords you got from (2) as coordinates of nodes in cy
for n, p in zip(cy["elements"]["nodes"], pos.values()):
    n["pos"] = {"x": int(p[0] * SCALING_FACTOR), "y": int(p[1] * SCALING_FACTOR)}

# 6.) Take the results of (3)-(5) and write them to a list, like elements_ls
elements = cy["elements"]["nodes"] + cy["elements"]["edges"]

app.layout = html.Div(
    [
        cyto.Cytoscape(
            id="cytoscape-layout-6",
            elements=elements,
            style={"width": "100%", "height": "800px"},
            layout={"name": "preset"},  # "preset" to use the pos coords
        )
    ]
)


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

I am not seeing the nodes appear where they should be. As a matter of fact they all seem to be at the same coordinate collapsing into a single node.

Hopefully the runnable code comments will help understanding what I’m trying to do. Thank you for any help.

PS Is there some good tutorial on how to use other layout algorithm directly from Dash Cytoscape? I often need Fruchterman-Rheingold and force-atlas.

1 post - 1 participant

Read full topic


dbc.Col + Pattern matching callback not working as expected

$
0
0

So here’s a minimum example of my code and I’m not sure why the col components that I’m adding in a pattern matching callback aren’t working as I would expect? They’re not the right size and they’re not filling in the parent container? Any help would be much appreciated. The goal is for the items of the pattern matching callback to responsively fill in the space, which equates to setting them to size 6 width on xs + sm displays and 12 width on md displays and upwards. Thanks!

from dash import html, dcc, Input, Output, State, Dash
import dash_bootstrap_components as dbc

style = dbc.themes.BOOTSTRAP

app = Dash(__name__, external_stylesheets=[style])

# Placeholder application layout
app.layout = dbc.Container([
    dbc.Row(
        [
            dbc.Col(
                [
                    dbc.Button(
                        "Placeholder Button", className="", id="button", n_clicks=0,
                    ),
                    dbc.Row(html.Div(id="test_id", children=[])),
                ],
                width=6
            ),
        ],
    ),
], fluid=True,)

@app.callback(
    Output("test_id", "children"),
    Input("button", "n_clicks"),
    State("test_id", "children"),
    prevent_initial_call=True,
    # State("cov_factors_store", "data"),
)
def display_dropdowns(n_clicks, container):
    # Should just have a callback that deals with the store component, and then everything else follows from that.
    new_dropdown = dbc.Col(
        dcc.Dropdown(
            options=[
                {"label": "NYC", "value": "New York City"},
                {"label": "MTL", "value": "Montreal"},
                {"label": "SF", "value": "San Francisco"},
                {"label": "LA", "value": "Los Angeles"},
                {"label": "TOKYO", "value": "Tokyo"},
            ],
            id={"type": "factor_dropdown", "index": n_clicks},
        ),
        className="mb-2 px-0",
        xs=6,
        md=12,
    )
    container.append(new_dropdown)
    return container

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

1 post - 1 participant

Read full topic

Display different components based on callback output condition

$
0
0

Is it possible to return different types of components based on what a callback returns?

app.layout = dbc.Placeholder(id="fill_it")

@app.callback(
    Output(
        dict(       #<-- single Output accepts a dict of possibilities
             "1st" = dict(  #<--- identifier
                 component_id = "fill_it", 
                 component_property = content
             ),
            "2nd" = dict(
                component_id = "fill_it",
                component_property = content
            )
        )
    ),
    Input(component_id='fill_dropdown', component_property='value')
)
def filler(value):
    if (value is None):
        key = "1st"
        content = _
    elif (value is not None):
        key = "2nd"
        content = _
    return key, content

Based on the returned key, a different element from the Output dict is rendered. Something like that. Or you could have a SubOutput(key).

The reason why I ask is that it feels like there are a lot of questions out there about making adjustments based on what the data layer returns:

I am pretty sure Jinja’s Python handlebars (static front end) can do this.

2 posts - 1 participant

Read full topic

Dash to send two requests in parallel to the backen

$
0
0

Hi,

My dash app is just a front for a restful API. The backend analyses data. The data is stored in another restful api. Data is huge. The backend stores some parameters. Requesting the parameters is fast, instantaneous. But requesting data over long periods takes 10 seconds.

I have a dropdown to select a store to analyse. When I select, it sends a request to the backend to retrieve the parameters. The backend instantiates the store, with all its available tools of data fetching and analysis, then stores it in a cache, sends the parameters to the backend, with an id to the store instance.

I have a button to request the data for that store. But I would like the first callback (from the dropdown) to start a process to retrieve the data through another request and store it in the front server in a dcc.Store when the request is done. And in the meantime, the user can do some other stuff.

How can I preload that data without disturbing the user?

1 post - 1 participant

Read full topic