Chapter 17 Quiz: Interactive Visualization — plotly, Dashboard Thinking
Instructions: This quiz tests your understanding of Chapter 17. Answer all questions before checking the solutions. For multiple choice, select the best answer — some options may be partially correct. For code analysis questions, predict the behavior without running the code. Total points: 100.
Section 1: Multiple Choice (8 questions, 5 points each)
Question 1. What is the primary advantage of interactive visualization over static visualization?
- (A) Interactive charts always look more professional
- (B) Interactive charts load faster than static images
- (C) Interactive charts allow the audience to explore data through hover, zoom, filter, and animation
- (D) Interactive charts are easier to create
Answer
**Correct: (C)** The core advantage is *exploration*. Interactive charts let the audience ask their own questions by hovering for details, zooming into regions of interest, filtering by category, and watching animations unfold. This is especially valuable for dense datasets and non-technical audiences. Interactive charts are not necessarily more professional (A), faster (B), or easier to create (D) — those claims are situation-dependent.Question 2. Which plotly.express parameter adds a time slider and play button to a chart?
- (A)
animation_frame - (B)
animation_group - (C)
time_slider - (D)
frame_col
Answer
**Correct: (A)** `animation_frame` specifies the column that defines the time steps. plotly automatically adds a play button and slider. `animation_group` (B) specifies which column identifies the same entity across frames (for smooth transitions) — it is important but does not create the animation by itself. `time_slider` (C) and `frame_col` (D) are not valid plotly parameters.Question 3. What data column format does plotly require for the locations parameter in a world choropleth map?
- (A) Full country names (e.g., "United States of America")
- (B) Two-letter country abbreviations (e.g., "US")
- (C) ISO 3166-1 alpha-3 country codes (e.g., "USA") by default
- (D) Latitude and longitude coordinates
Answer
**Correct: (C)** By default, `px.choropleth()` expects ISO 3166-1 alpha-3 codes (three-letter codes like "USA", "GBR", "BRA"). You can use other formats by specifying `locationmode` — for example, `locationmode="country names"` accepts full country names — but alpha-3 codes are the default and most reliable. Latitude/longitude (D) is used for `scatter_geo`, not choropleth.Question 4. In a Dash app, what is the role of a callback function?
- (A) It defines the visual layout of the dashboard
- (B) It runs when a user interacts with a control (Input) and returns updated values for chart components (Outputs)
- (C) It connects the Dash app to a database
- (D) It exports the dashboard to an HTML file
Answer
**Correct: (B)** A callback is a Python function decorated with `@app.callback()`. It specifies one or more Inputs (user-interactive components like dropdowns) and one or more Outputs (chart components to update). When any Input changes, Dash calls the function with the new input values and updates the specified Outputs with the return values. The layout (A) is defined separately. Database connections (C) and HTML export (D) are unrelated.Question 5. Which method exports a plotly figure as a standalone HTML file?
- (A)
fig.save("chart.html") - (B)
fig.write_html("chart.html") - (C)
fig.export("chart.html") - (D)
fig.to_html("chart.html")
Answer
**Correct: (B)** `fig.write_html("filename.html")` is the correct method. It creates a self-contained HTML file with embedded JavaScript. The `include_plotlyjs` parameter controls whether the plotly.js library is embedded (large file, works offline) or loaded from a CDN (small file, requires internet). `to_html()` exists but returns an HTML string rather than writing to a file.Question 6. Why should you set range_x and range_y in animated plotly charts?
- (A) To make the chart render faster
- (B) To prevent axis ranges from changing between frames, which makes the animation disorienting
- (C) To reduce the file size of the exported HTML
- (D) plotly requires explicit ranges for animation to work
Answer
**Correct: (B)** Without fixed ranges, plotly recalculates the axis limits for each animation frame. If the data range changes across frames, dots appear to jump around not because the data changed, but because the coordinate system shifted. Fixed ranges ensure that position on the screen consistently maps to the same data value, making movement meaningful. plotly does not require explicit ranges (D) — it works without them, just poorly.Question 7. What is the relationship between plotly.express and plotly.graph_objects?
- (A) They are completely separate libraries with no connection
- (B) plotly.express is a high-level wrapper that creates plotly.graph_objects figures under the hood
- (C) plotly.graph_objects is a newer replacement for plotly.express
- (D) plotly.express handles interactive charts while plotly.graph_objects handles static charts
Answer
**Correct: (B)** `plotly.express` functions create `plotly.graph_objects.Figure` objects. Every `px.scatter()` call returns a `go.Figure` that you can further customize with `update_layout()`, `update_traces()`, etc. This is analogous to how seaborn creates matplotlib Figure/Axes objects. `plotly.express` is not a separate system — it is a convenient shorthand for the most common `graph_objects` patterns.Question 8. Which Dash component creates an interactive dropdown menu?
- (A)
html.Dropdown() - (B)
dcc.Dropdown() - (C)
dash.Dropdown() - (D)
dcc.Select()
Answer
**Correct: (B)** `dcc.Dropdown()` (from Dash Core Components) creates an interactive dropdown. The `html` module provides basic HTML elements (divs, headings, paragraphs). The `dcc` module provides interactive components (dropdowns, sliders, graphs, checkboxes). There is no `dash.Dropdown()` (C) or `dcc.Select()` (D) in standard Dash.Section 2: True or False (3 questions, 5 points each)
Question 9. True or false: plotly charts rendered in a Jupyter notebook can be interacted with (hover, zoom, pan) directly in the notebook.
Answer
**True.** plotly integrates with Jupyter notebooks and renders interactive charts inline. You can hover over points, zoom, pan, and use the toolbar without opening a separate browser window. This is one of plotly's key advantages for exploratory data analysis in notebooks.Question 10. True or false: A Dash app runs as a local web server, and the dashboard is viewed in a web browser.
Answer
**True.** When you call `app.run()`, Dash starts a Flask-based web server (typically on `http://127.0.0.1:8050`). You open this URL in a browser to see the dashboard. The Python code handles data processing and callback logic on the server side, while the browser renders the HTML and JavaScript.Question 11. True or false: To create an animated choropleth in plotly, you must manually create one map per time step and stitch them together.
Answer
**False.** plotly handles animation automatically. You pass your full DataFrame (with all years) and set `animation_frame="year"`. plotly creates the individual frames, the play button, and the slider internally. You do not need to create separate maps or manage frame transitions yourself.Section 3: Short Answer (4 questions, 5 points each)
Question 12. Explain the difference between hover_name and hover_data in plotly.express functions.
Answer
`hover_name` specifies a column whose values appear as the **bold title** of the tooltip. It is typically the identifier for each observation (e.g., country name, player name). `hover_data` specifies additional columns (or a dictionary with format strings) that appear as secondary information in the tooltip. You can use both together: `hover_name` for the main label and `hover_data` for supporting details.Question 13. Name three interactive actions a user can perform on a default plotly chart without any custom configuration.
Answer
(1) **Hover** over a data point to see a tooltip with values. (2) **Zoom** by dragging a rectangular selection box. (3) **Pan** by holding shift and dragging (or selecting the pan tool). Other valid answers: double-click to reset zoom, click legend items to toggle trace visibility, use the toolbar to switch between zoom/pan/select modes, lasso select, or download as PNG.Question 14. What is the purpose of the animation_group parameter in plotly animated charts? What happens if you omit it?
Answer
`animation_group` tells plotly which column uniquely identifies each entity across animation frames. For example, `animation_group="country"` means "this dot represents the same country in every frame." This enables smooth transitions where dots slide from their old position to their new position. If you omit it, plotly cannot track entities across frames, so dots may appear to blink in and out rather than moving smoothly.Question 15. Name two advantages and two disadvantages of exporting a plotly chart with include_plotlyjs=True versus include_plotlyjs="cdn".
Answer
**`include_plotlyjs=True` (self-contained):** Advantages: (1) works offline, no internet needed; (2) recipient does not need to install anything or have internet access. Disadvantages: (1) large file size (~3-5 MB per file); (2) if sharing multiple charts, the library is duplicated in each file. **`include_plotlyjs="cdn"` (CDN-loaded):** Advantages: (1) very small file size (~10-50 KB); (2) always loads the latest plotly.js version. Disadvantages: (1) requires internet access to view; (2) if the CDN goes down or changes, the chart breaks.Section 4: Applied Scenarios (3 questions, 5 points each)
Question 16. A health ministry wants to track vaccination progress across their country's 30 provinces over 10 years. They want to identify which provinces are falling behind and which are improving. Recommend a plotly visualization and write the code.
Answer
An animated line chart with one line per province, or an animated bar chart sorted by coverage:fig = px.line(df, x="year", y="coverage_pct",
color="province",
hover_name="province",
title="Provincial Vaccination Trends")
fig.show()
Alternatively, an animated bar chart that re-sorts each year:
fig = px.bar(df, x="coverage_pct",
y="province",
animation_frame="year",
orientation="h",
range_x=[40, 100],
title="Provincial Coverage Rankings")
fig.show()
The bar chart version is sometimes called a "bar chart race" and is effective for showing rank changes over time.
Question 17. You build a Dash dashboard with a dropdown (6 regions) and a slider (20 years). A colleague says "That's 120 combinations — how do you know your callback handles all of them?" What testing strategy would you use?
Answer
Strategies: (1) **Test edge cases** — earliest year, latest year, each region individually. (2) **Check for empty results** — some region-year combinations may have no data; the callback should handle this gracefully (e.g., show an empty chart with a message rather than crashing). (3) **Add validation in the callback** — check if the filtered DataFrame is empty and return a placeholder figure. (4) **Automated testing** — loop through all 120 combinations in a test script, calling the callback function directly (Dash callbacks are regular Python functions). (5) **Manual smoke test** — click through 10-15 representative combinations to verify the charts update correctly.Question 18. Your dataset has 500,000 rows. When you create a px.scatter(), the chart is extremely slow to render and interact with. Suggest three approaches to make it usable.
Answer
(1) **Sample the data** — use `df.sample(5000)` to plot a random subset. Fast, but loses some information. (2) **Aggregate** — use `groupby` to compute means or medians by group, reducing 500K rows to hundreds. Changes the chart type from scatter to bar or grouped scatter. (3) **Use `px.density_heatmap()`** — bin the data into a 2D grid and show density as color, instead of plotting individual points. plotly renders this efficiently because it is a grid of rectangles, not 500K separate markers. Other valid approaches: use `datashader` for server-side rendering, or use plotly's WebGL rendering mode (`render_mode="webgl"` in some chart types).Section 5: Code Analysis (2 questions, 5 points each)
Question 19. What will this Dash callback do when the user selects "EURO" from the dropdown?
@app.callback(
Output("my-chart", "figure"),
Input("region-dropdown", "value")
)
def update_chart(selected_region):
filtered = df[df["region"] == selected_region]
fig = px.scatter(filtered,
x="gdp_per_capita",
y="coverage_pct",
hover_name="country")
fig.update_layout(
title=f"Coverage: {selected_region}")
return fig
Answer
When the user selects "EURO": (1) Dash calls `update_chart("EURO")`. (2) The function filters the DataFrame to rows where `region == "EURO"`. (3) It creates a scatter plot of GDP vs. coverage for European countries only, with country names in the hover tooltip. (4) The layout is updated to show "Coverage: EURO" as the title. (5) The figure is returned, and Dash updates the Graph component with `id="my-chart"` to display the new chart. The user sees an interactive scatter plot of only European countries.Question 20. Identify the problem with this animated choropleth code:
fig = px.choropleth(df,
locations="iso_alpha",
color="coverage_pct",
animation_frame="year",
color_continuous_scale="YlGnBu")
fig.show()
Answer
The code will technically work, but it has a significant usability problem: **the color range is not fixed** (`range_color` is not specified). This means the color scale readjusts with each animation frame. If one year has coverage ranging from 60-95% and another has 40-99%, the same shade of blue means different values in different frames. A country could appear to change color not because its coverage changed, but because the scale shifted. The fix is to add a fixed color range:fig = px.choropleth(df,
locations="iso_alpha",
color="coverage_pct",
animation_frame="year",
color_continuous_scale="YlGnBu",
range_color=[40, 100])
This also lacks `hover_name` for country identification, but the primary issue is the unfixed color scale.