Very frustrating learning Dash - Need help on Bar Chart interacting with another Bar Chart

I am trying to build a simple dashboard using 2 bar charts. It ought to be easy, but I am finding the documentation is not designed for beginners.

I have created a simple CSV file with State, City, and Sales columns. All I want to do is display a Sales by State chart and a Sales by City chart underneath it. the interaction I am trying to build is to hover over a State bar, and have the City chart only show cities in that State. Sounds simple.

I can get the two charts up easily enough as independent charts. I cannot get the interactivity to work.

I have tried following and understanding the Interactive tutorial, but one of the samples is too simple. It does not have a chart working with another chart. The other sample is too complex. It uses time series and a very complex set of code to handle x and y components and values. I can follow what that example is doing, but when I try to adapt it to bar charts and a much simpler set of data (i.e State, city, Amount), I cannot get it to work. By work, I mean when I try adding the callback, the code fails entirely. when I take the callback and “def update” out, the charts are displayed properly, just with no interactivity.

I have tried to use the examples in the Dash documentation for Bar Charts. I have tried using the examples in Plotly documentation. My biggest challenge seems to be that most of these examples use data that is input manually into the code. I am trying to use a CSV file, which I can do for two independent charts. I just cannot figure out how to construct the callback when a CSV file is involved.

I think the problem is akin to attending a poetry class to learn how to write iambic pentameter or haiku, but the teacher gives you a dictionary and nothing else. The words are all in the dictionary, but the dictionary does not show how to put them together to form either type of poetry.

Does anybody have a suggestion other than work through the documentation?

Sorry to vent. I think Dash and Plotly offer a lot. If I can learn how to use them, I plan on offering them in a university-level course on visualizations. At the present pace of things, I won’t be proficient enough in Dash Plotly to teach it until the next century. Any thoughts or help would be greatly appreciated.

Hey @Jfrick100,

Sorry to hear your experience has been so frustrating so far.

Here’s a minimal example I just came up with that hopefully does what you want. I don’t know the format of your CSV so I don’t know if I’m answering that specific question, but it has the right hover / bar chart behaviour as far as I could tell from your description of what you want to achieve.

The summary is to use hoverData of the Graph component to recover the identity of the bar that was hovered over (in the way I set it up that gives me the state so I can easily filter my data to dynamically build a second bar chart).

import dash
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd
import plotly.graph_objs as go
from dash.dependencies import Input, Output


df = pd.DataFrame({
    "state": ["CA", "CA", "CA", "NY", "NY"],
    "city": ["Los Angeles", "San Francisco", "Fresno", "New York", "Buffalo"],
    "sales": [120, 180, 40, 240, 10]
})

state_df = df.drop("city", axis=1).groupby("state").sum()

STATE_GRAPH = go.Figure([go.Bar(x=state_df.index, y=state_df.sales)])

app = dash.Dash()

app.layout = html.Div([
    dcc.Graph(id="state-bar", figure=STATE_GRAPH),
    dcc.Graph(id="city-bar")
])


@app.callback(Output("city-bar", "figure"), [Input("state-bar", "hoverData")])
def on_hover(hover_data):
    if not hover_data:
        return dash.no_update

    # get the state
    state = hover_data["points"][0]["x"]

    sales = df.loc[df.state == state]

    return go.Figure([go.Bar(x=sales.city, y=sales.sales)])


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

Your code worked exactly the way I need. Thank you.

And added “thank you” is in order. There were several important things I learned about dash coding beyond how to solve my immediate problem.

In playing with your code and trial and error with changing it, I think I can more clearly state the overall issue.

  1. The Dash documentation is at a very atomic level. It list a component, decorator, or other item, but it does not go into detail about that item or parameters or settings.

  2. There are few examples of how to accomplish a higher level task, I.e. there are few examples of how to put the components, etc. together and that explain why.

  3. What examples I see do not show the difference between key words and variables. For example, “hover” can be used as a variable name, but I mistook it for a key word.

  4. The examples in the Dash tutorial seem to use inconsistent code. In one example, a graph was define in the dcc.graph section, but in another example, the graph was defined in a def section. There was no explanation as to this difference.

At any rate, I greatly appreciate your posting.

James

Tom,

Thanks again for your post.

How did you learn Dash and Plotly? Are there any resources other than the official documentation? I am looking for samples of code, such as the one you generously posted, that show how to put together the various pieces.

What I mean is this:

  • I used to work for MicroStrategy. Their education was much like the Dash and Plotly documentation I have seen so far. MicroStrategy gave the commands and parameters but very few samples of how to put together code in order to develop visualizations and put them into a dashboard.
  • Tableau came along and has been beating the pants off MicroStrategy. I think that it wasn’t the beauty of Tableau that made it such a great tool. A person new to visualizations could search a vast number of samples, videos, and other ways to learn, and from these, learn how to use Tableau.

For Dash and Plotly, do references exist that do that? Or would I do as well to monitor this site and learn from examples that are posted here?

Again, thanks for your earlier code. It helped tremendously.

James

Hey James,

To be completely honest I don’t actually remember for certain, but I’m pretty sure I read through the tutorial in order on the docs site. I also looked at apps other people had built, both the examples that are online and a couple that colleagues of mine had built. This forum is a great way to discover things other people have built, particularly the show and tell threads.

In terms of picking up tricks for how to do specific things, I found resources like dash-recipes useful, but it’s a little bit out of date these days. There’s lots of good questions and answers on the forum here, and often they link to issues on GitHub that have more information or context, I find that useful too. The Dash FAQ has useful advice for a bunch of things.

Nowadays I mostly know about features I need when I make apps. I stay on top of new features by reading changelogs when new version of Dash or the component packages are released. Which isn’t to say I know how to accomplish everything I want to do before I start coding. For example, I had not used the hoverData prop of Graph before reading your question. I found it by reading the docstring for Graph and it seemed like a good bet for what would be needed to get the hover interactivity. Then I made a simple first version of the app that when I hovered over the first graph, the callback simply displayed the hoverdata in a html.Div and printed to the python console. By doing that I could figure out I needed state = hover_data["points"][0]["x"].

So in summary, what worked for me was just reading through tutorials, examples and other’s code to get a sense of the standard programming patterns, and then trial and error / iterative development when I’m making my own apps. None of which is particularly specific to Dash of course, but hopefully that helps you.

2 Likes