Spaces:
Running
Running
antonymilne
commited on
Commit
•
dda021c
1
Parent(s):
2465927
Update demo
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- README.md +60 -71
- app.py +3 -3
- assets/css/custom.css +18 -8
- chart_groups.py +2 -4
- custom_charts.py +198 -127
- custom_components.py +20 -13
- pages/__init__.py +0 -4
- pages/_factories.py +52 -23
- pages/_pages_utils.py +39 -87
- pages/correlation.py +45 -15
- pages/deviation.py +60 -17
- pages/distribution.py +54 -30
- pages/examples/area.py +1 -9
- pages/examples/bar.py +3 -20
- pages/examples/boxplot.py +1 -11
- pages/examples/bubble.py +2 -12
- pages/examples/bubble_map.py +2 -20
- pages/examples/butterfly.py +24 -35
- pages/examples/choropleth.py +2 -16
- pages/examples/column_and_line.py +23 -38
- pages/examples/connected_scatter.py +2 -12
- pages/examples/diverging_bar.py +3 -28
- pages/examples/diverging_stacked_bar.py +68 -0
- pages/examples/donut.py +1 -9
- pages/examples/dot_map.py +1 -19
- pages/examples/dumbbell.py +22 -27
- pages/examples/funnel.py +1 -9
- pages/examples/gantt.py +2 -13
- pages/examples/heatmap.py +1 -11
- pages/examples/histogram.py +1 -9
- pages/examples/line.py +1 -9
- pages/examples/magnitude_column.py +3 -19
- pages/examples/ordered_bar.py +5 -21
- pages/examples/ordered_column.py +5 -20
- pages/examples/paired_bar.py +8 -21
- pages/examples/paired_column.py +2 -20
- pages/examples/parallel_coordinates.py +2 -14
- pages/examples/pie.py +1 -9
- pages/examples/radar.py +4 -14
- pages/examples/sankey.py +26 -47
- pages/examples/scatter.py +1 -9
- pages/examples/scatter_matrix.py +1 -13
- pages/examples/stacked_bar.py +1 -10
- pages/examples/stacked_column.py +1 -10
- pages/examples/stepped_line.py +1 -17
- pages/examples/time_column.py +5 -25
- pages/examples/treemap.py +2 -19
- pages/examples/violin.py +1 -11
- pages/examples/waterfall.py +11 -35
- pages/flow.py +16 -14
README.md
CHANGED
@@ -1,14 +1,3 @@
|
|
1 |
-
---
|
2 |
-
title: Visual Vocabulary
|
3 |
-
emoji: 🎨
|
4 |
-
colorFrom: blue
|
5 |
-
colorTo: purple
|
6 |
-
sdk: docker
|
7 |
-
pinned: false
|
8 |
-
license: apache-2.0
|
9 |
-
short_description: Vizro - Visual vocabulary
|
10 |
-
---
|
11 |
-
|
12 |
# Visual vocabulary
|
13 |
|
14 |
### Welcome to our visual vocabulary dashboard! 🎨
|
@@ -49,66 +38,66 @@ The dashboard is still in development. Below is an overview of the chart types f
|
|
49 |
|
50 |
Sure, here's the table with all columns aligned for better readability:
|
51 |
|
52 |
-
| Chart Type | Status | Category | Credits & sources
|
53 |
-
| --------------------- | ------ | ------------------------ |
|
54 |
-
| Arc | ❌ | Part-to-whole |
|
55 |
-
| Area | ✅ | Time | [Filled area plot with px](https://plotly.com/python/filled-area-plots/)
|
56 |
-
| Bar | ✅ | Magnitude | [Bar chart with px](https://plotly.com/python/bar-charts/)
|
57 |
-
| Barcode | ❌ | Distribution |
|
58 |
-
| Beeswarm | ❌ | Distribution |
|
59 |
-
| Boxplot | ✅ | Distribution | [Box plot with px](https://plotly.com/python/box-plots/)
|
60 |
-
| Bubble | ✅ | Correlation | [Scatter plot with px](https://plotly.com/python/line-and-scatter/)
|
61 |
-
| Bubble map | ✅ | Spatial | [Bubble map in px](https://plotly.com/python/bubble-maps/)
|
62 |
-
| Bubble timeline | ❌ | Time |
|
63 |
-
| Bullet | ❌ | Magnitude |
|
64 |
-
| Bump | ❌ | Ranking |
|
65 |
-
| Butterfly | ✅ | Deviation, Distribution | [Pyramid charts in Plotly](https://plotly.com/python/v3/population-pyramid-charts/)
|
66 |
-
| Chord | ❌ | Flow |
|
67 |
-
| Choropleth | ✅ | Spatial | [Choropleth map with px](https://plotly.com/python/choropleth-maps/)
|
68 |
-
| Column | ✅ | Magnitude, Time | [Bar chart with px](https://plotly.com/python/bar-charts/)
|
69 |
-
| Column and line | ✅ | Correlation, Time | [Multiple chart types in Plotly](https://plotly.com/python/graphing-multiple-chart-types/)
|
70 |
-
| Connected scatter | ✅ | Correlation, Time | [Line plot with px](https://plotly.com/python/line-charts/)
|
71 |
-
| Cumulative curve | ❌ | Distribution |
|
72 |
-
| Diverging bar | ✅ | Deviation | [Bar chart with px](https://plotly.com/python/bar-charts/)
|
73 |
-
| Diverging stacked bar |
|
74 |
-
| Donut | ✅ | Part-to-whole | [Pie chart with px](https://plotly.com/python/pie-charts/)
|
75 |
-
| Dot map | ✅ | Spatial | [Bubble map in px](https://plotly.com/python/bubble-maps/)
|
76 |
-
| Dumbbell | ✅ | Distribution | [Dumbbell plots in Plotly](https://community.plotly.com/t/how-to-make-dumbbell-plots-in-plotly-python/47762)
|
77 |
-
| Fan | ❌ | Time |
|
78 |
-
| Flow map | ❌ | Spatial |
|
79 |
-
| Funnel | ✅ | Part-to-whole | [Funnel plot with px](https://plotly.com/python/funnel-charts/)
|
80 |
-
| Gantt | ✅ | Time | [Gantt chart with px](https://plotly.com/python/gantt/)
|
81 |
-
| Gridplot | ❌ | Part-to-whole |
|
82 |
-
| Heatmap | ✅ | Time | [Heatmaps with px](https://plotly.com/python/heatmaps/)
|
83 |
-
| Correlation matrix | ❌ | Correlation |
|
84 |
-
| Histogram | ✅ | Distribution | [Histograms with px](https://plotly.com/python/histograms/)
|
85 |
-
| Line | ✅ | Time | [Line plot with px](https://plotly.com/python/line-charts/)
|
86 |
-
| Lollipop | ❌ | Ranking, Magnitude |
|
87 |
-
| Marimekko | ❌ | Magnitude, Part-to-whole |
|
88 |
-
| Network | ❌ | Flow |
|
89 |
-
| Ordered bar | ✅ | Ranking | [Bar chart with px](https://plotly.com/python/bar-charts/)
|
90 |
-
| Ordered bubble | ❌ | Ranking |
|
91 |
-
| Ordered column | ✅ | Ranking | [Bar chart with px](https://plotly.com/python/bar-charts/)
|
92 |
-
| Paired bar | ✅ | Magnitude | [Histograms with px](https://plotly.com/python/histograms/)
|
93 |
-
| Paired column | ✅ | Magnitude | [Histograms with px](https://plotly.com/python/histograms/)
|
94 |
-
| Parallel coordinates | ✅ | Magnitude | [Parallel coordinates plot with px](https://plotly.com/python/parallel-coordinates-plot/)
|
95 |
-
| Pictogram | ❌ | Magnitude |
|
96 |
-
| Pie | ✅ | Part-to-whole | [Pie chart with px](https://plotly.com/python/pie-charts/)
|
97 |
-
| Radar | ✅ | Magnitude | [Radar chart with px](https://plotly.com/python/radar-chart/)
|
98 |
-
| Radial | ❌ | Magnitude |
|
99 |
-
| Sankey | ✅ | Flow | [Sankey diagram in Plotly](https://plotly.com/python/sankey-diagram/)
|
100 |
-
| Scatter | ✅ | Correlation | [Scatter plot with px](https://plotly.com/python/line-and-scatter/)
|
101 |
-
| Scatter matrix | ✅ | Correlation | [Scatter matrix with px](https://plotly.com/python/splom/)
|
102 |
-
| Slope | ❌ | Ranking, Time |
|
103 |
-
| Sparkline | ❌ | Time |
|
104 |
-
| Stacked bar | ✅ | Part-to-whole | [Histograms with px](https://plotly.com/python/histograms/)
|
105 |
-
| Stacked column | ✅ | Part-to-whole | [Histograms with px](https://plotly.com/python/histograms/)
|
106 |
-
| Stepped line | ✅ | Time | [Line plot with px](https://plotly.com/python/line-charts/)
|
107 |
-
| Surplus deficit line | ❌ | Deviation |
|
108 |
-
| Treemap | ✅ | Part-to-whole | [Treemap with px](https://plotly.com/python/treemaps/)
|
109 |
-
| Venn | ❌ | Part-to-whole |
|
110 |
-
| Violin | ✅ | Distribution | [Violin plot with px](https://plotly.com/python/violin/)
|
111 |
-
| Waterfall | ✅ | Part-to-whole, Flow | [Waterfall charts in Plotly](https://plotly.com/python/waterfall-charts/)
|
112 |
|
113 |
## How to contribute
|
114 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
# Visual vocabulary
|
2 |
|
3 |
### Welcome to our visual vocabulary dashboard! 🎨
|
|
|
38 |
|
39 |
Sure, here's the table with all columns aligned for better readability:
|
40 |
|
41 |
+
| Chart Type | Status | Category | Credits & sources | API |
|
42 |
+
| --------------------- | ------ | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
43 |
+
| Arc | ❌ | Part-to-whole | | |
|
44 |
+
| Area | ✅ | Time | [Filled area plot with px](https://plotly.com/python/filled-area-plots/) | [px.area](https://plotly.com/python-api-reference/generated/plotly.express.area) |
|
45 |
+
| Bar | ✅ | Magnitude | [Bar chart with px](https://plotly.com/python/bar-charts/) | [px.bar](https://plotly.com/python-api-reference/generated/plotly.express.bar) |
|
46 |
+
| Barcode | ❌ | Distribution | | |
|
47 |
+
| Beeswarm | ❌ | Distribution | | |
|
48 |
+
| Boxplot | ✅ | Distribution | [Box plot with px](https://plotly.com/python/box-plots/) | [px.box](https://plotly.github.io/plotly.py-docs/generated/plotly.express.box) |
|
49 |
+
| Bubble | ✅ | Correlation | [Scatter plot with px](https://plotly.com/python/line-and-scatter/) | [px.scatter](https://plotly.com/python-api-reference/generated/plotly.express.scatter) |
|
50 |
+
| Bubble map | ✅ | Spatial | [Bubble map in px](https://plotly.com/python/bubble-maps/) | [px.scatter_map](https://plotly.github.io/plotly.py-docs/generated/plotly.express.scatter_map) |
|
51 |
+
| Bubble timeline | ❌ | Time | | |
|
52 |
+
| Bullet | ❌ | Magnitude | | |
|
53 |
+
| Bump | ❌ | Ranking | | |
|
54 |
+
| Butterfly | ✅ | Deviation, Distribution | [Pyramid charts in Plotly](https://plotly.com/python/v3/population-pyramid-charts/) | [go.Bar](https://plotly.com/python-api-reference/generated/plotly.graph_objects.Bar.html) |
|
55 |
+
| Chord | ❌ | Flow | | |
|
56 |
+
| Choropleth | ✅ | Spatial | [Choropleth map with px](https://plotly.com/python/choropleth-maps/) | [px.choropleth](https://plotly.github.io/plotly.py-docs/generated/plotly.express.choropleth.html) |
|
57 |
+
| Column | ✅ | Magnitude, Time | [Bar chart with px](https://plotly.com/python/bar-charts/) | [px.bar](https://plotly.com/python-api-reference/generated/plotly.express.bar.html) |
|
58 |
+
| Column and line | ✅ | Correlation, Time | [Multiple chart types in Plotly](https://plotly.com/python/graphing-multiple-chart-types/) | [go.Bar](https://plotly.com/python-api-reference/generated/plotly.graph_objects.Bar.html) and [go.Scatter](https://plotly.com/python-api-reference/generated/plotly.graph_objects.Scatter.html) |
|
59 |
+
| Connected scatter | ✅ | Correlation, Time | [Line plot with px](https://plotly.com/python/line-charts/) | [px.line](https://plotly.com/python-api-reference/generated/plotly.express.line) |
|
60 |
+
| Cumulative curve | ❌ | Distribution | | |
|
61 |
+
| Diverging bar | ✅ | Deviation | [Bar chart with px](https://plotly.com/python/bar-charts/) | [px.bar](https://plotly.com/python-api-reference/generated/plotly.express.bar) |
|
62 |
+
| Diverging stacked bar | ✅ | Deviation | [Plotly forum - diverging stacked bar](https://community.plotly.com/t/need-help-in-making-diverging-stacked-bar-charts/34023/2) | [go.Bar](https://plotly.com/python-api-reference/generated/plotly.graph_objects.Bar.html) |
|
63 |
+
| Donut | ✅ | Part-to-whole | [Pie chart with px](https://plotly.com/python/pie-charts/) | [px.pie](https://plotly.com/python-api-reference/generated/plotly.express.pie) |
|
64 |
+
| Dot map | ✅ | Spatial | [Bubble map in px](https://plotly.com/python/bubble-maps/) | [px.scatter_map](https://plotly.github.io/plotly.py-docs/generated/plotly.express.scatter_map) |
|
65 |
+
| Dumbbell | ✅ | Distribution | [Dumbbell plots in Plotly](https://community.plotly.com/t/how-to-make-dumbbell-plots-in-plotly-python/47762) | [px.scatter](https://plotly.com/python-api-reference/generated/plotly.express.scatter.html) and [add_shape](https://plotly.com/python/shapes/) |
|
66 |
+
| Fan | ❌ | Time | | |
|
67 |
+
| Flow map | ❌ | Spatial | | |
|
68 |
+
| Funnel | ✅ | Part-to-whole | [Funnel plot with px](https://plotly.com/python/funnel-charts/) | [px.funnel](https://plotly.com/python/funnel-charts/) |
|
69 |
+
| Gantt | ✅ | Time | [Gantt chart with px](https://plotly.com/python/gantt/) | [px.timeline](https://plotly.com/python-api-reference/generated/plotly.express.timeline.html) |
|
70 |
+
| Gridplot | ❌ | Part-to-whole | | |
|
71 |
+
| Heatmap | ✅ | Time | [Heatmaps with px](https://plotly.com/python/heatmaps/) | [px.density_heatmap](https://plotly.com/python-api-reference/generated/plotly.express.density_heatmap.html) |
|
72 |
+
| Correlation matrix | ❌ | Correlation | | |
|
73 |
+
| Histogram | ✅ | Distribution | [Histograms with px](https://plotly.com/python/histograms/) | [px.histogram](https://plotly.github.io/plotly.py-docs/generated/plotly.express.histogram) |
|
74 |
+
| Line | ✅ | Time | [Line plot with px](https://plotly.com/python/line-charts/) | [px.line](https://plotly.com/python-api-reference/generated/plotly.express.line) |
|
75 |
+
| Lollipop | ❌ | Ranking, Magnitude | | |
|
76 |
+
| Marimekko | ❌ | Magnitude, Part-to-whole | | |
|
77 |
+
| Network | ❌ | Flow | | |
|
78 |
+
| Ordered bar | ✅ | Ranking | [Bar chart with px](https://plotly.com/python/bar-charts/) | [px.bar](https://plotly.com/python-api-reference/generated/plotly.express.bar.html) |
|
79 |
+
| Ordered bubble | ❌ | Ranking | | |
|
80 |
+
| Ordered column | ✅ | Ranking | [Bar chart with px](https://plotly.com/python/bar-charts/) | [px.bar](https://plotly.com/python-api-reference/generated/plotly.express.bar.html) |
|
81 |
+
| Paired bar | ✅ | Magnitude | [Histograms with px](https://plotly.com/python/histograms/) | [px.histogram](https://plotly.github.io/plotly.py-docs/generated/plotly.express.histogram) |
|
82 |
+
| Paired column | ✅ | Magnitude | [Histograms with px](https://plotly.com/python/histograms/) | [px.histogram](https://plotly.github.io/plotly.py-docs/generated/plotly.express.histogram) |
|
83 |
+
| Parallel coordinates | ✅ | Magnitude | [Parallel coordinates plot with px](https://plotly.com/python/parallel-coordinates-plot/) | [px.parallel_coordinates](https://plotly.com/python-api-reference/generated/plotly.express.parallel_coordinates.html) |
|
84 |
+
| Pictogram | ❌ | Magnitude | | |
|
85 |
+
| Pie | ✅ | Part-to-whole | [Pie chart with px](https://plotly.com/python/pie-charts/) | [px.pie](https://plotly.com/python-api-reference/generated/plotly.express.pie) |
|
86 |
+
| Radar | ✅ | Magnitude | [Radar chart with px](https://plotly.com/python/radar-chart/) | [px.line_polar](https://plotly.com/python-api-reference/generated/plotly.express.line_polar) |
|
87 |
+
| Radial | ❌ | Magnitude | | |
|
88 |
+
| Sankey | ✅ | Flow | [Sankey diagram in Plotly](https://plotly.com/python/sankey-diagram/) | [go.Sankey](https://plotly.github.io/plotly.py-docs/generated/plotly.graph_objects.Sankey.html) |
|
89 |
+
| Scatter | ✅ | Correlation | [Scatter plot with px](https://plotly.com/python/line-and-scatter/) | [px.scatter](https://plotly.com/python-api-reference/generated/plotly.express.scatter) |
|
90 |
+
| Scatter matrix | ✅ | Correlation | [Scatter matrix with px](https://plotly.com/python/splom/) | [px.scatter_matrix](https://plotly.github.io/plotly.py-docs/generated/plotly.express.scatter_matrix.html) |
|
91 |
+
| Slope | ❌ | Ranking, Time | | |
|
92 |
+
| Sparkline | ❌ | Time | | |
|
93 |
+
| Stacked bar | ✅ | Part-to-whole | [Histograms with px](https://plotly.com/python/histograms/) | [px.histogram](https://plotly.github.io/plotly.py-docs/generated/plotly.express.histogram) |
|
94 |
+
| Stacked column | ✅ | Part-to-whole | [Histograms with px](https://plotly.com/python/histograms/) | [px.histogram](https://plotly.github.io/plotly.py-docs/generated/plotly.express.histogram) |
|
95 |
+
| Stepped line | ✅ | Time | [Line plot with px](https://plotly.com/python/line-charts/) | [px.line](https://plotly.com/python-api-reference/generated/plotly.express.line) |
|
96 |
+
| Surplus deficit line | ❌ | Deviation | | |
|
97 |
+
| Treemap | ✅ | Part-to-whole | [Treemap with px](https://plotly.com/python/treemaps/) | [px.treemap](https://plotly.com/python-api-reference/generated/plotly.express.treemap.html) |
|
98 |
+
| Venn | ❌ | Part-to-whole | | |
|
99 |
+
| Violin | ✅ | Distribution | [Violin plot with px](https://plotly.com/python/violin/) | [px.violin](https://plotly.com/python-api-reference/generated/plotly.express.violin.html) |
|
100 |
+
| Waterfall | ✅ | Part-to-whole, Flow | [Waterfall charts in Plotly](https://plotly.com/python/waterfall-charts/) | [go.Waterfall](https://plotly.github.io/plotly.py-docs/generated/plotly.graph_objects.Waterfall.html) |
|
101 |
|
102 |
## How to contribute
|
103 |
|
app.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
"""App configuration for dashboard."""
|
2 |
|
3 |
-
from typing import
|
4 |
|
5 |
import vizro.models as vm
|
6 |
from chart_groups import ALL_CHART_GROUP, CHART_GROUPS, ChartGroup, IncompletePage
|
@@ -60,7 +60,7 @@ def make_homepage_container(chart_group: ChartGroup) -> vm.Container:
|
|
60 |
)
|
61 |
|
62 |
|
63 |
-
def _remove_duplicates(pages:
|
64 |
# Deduplicate pages that have the same title. Using reversed means that the page that is kept is the first one
|
65 |
# in the dashboard. This will be the one that the card on the homepage links to.
|
66 |
return list({page.title: page for page in reversed(pages)}.values())
|
@@ -111,4 +111,4 @@ app = Vizro().build(dashboard)
|
|
111 |
server = app.dash.server
|
112 |
|
113 |
if __name__ == "__main__":
|
114 |
-
app.run()
|
|
|
1 |
"""App configuration for dashboard."""
|
2 |
|
3 |
+
from typing import Union
|
4 |
|
5 |
import vizro.models as vm
|
6 |
from chart_groups import ALL_CHART_GROUP, CHART_GROUPS, ChartGroup, IncompletePage
|
|
|
60 |
)
|
61 |
|
62 |
|
63 |
+
def _remove_duplicates(pages: list[Union[vm.Page, IncompletePage]]) -> list[Union[vm.Page, IncompletePage]]:
|
64 |
# Deduplicate pages that have the same title. Using reversed means that the page that is kept is the first one
|
65 |
# in the dashboard. This will be the one that the card on the homepage links to.
|
66 |
return list({page.title: page for page in reversed(pages)}.values())
|
|
|
111 |
server = app.dash.server
|
112 |
|
113 |
if __name__ == "__main__":
|
114 |
+
app.run(port=8051)
|
assets/css/custom.css
CHANGED
@@ -10,22 +10,36 @@ img[src*="#chart-icon"] {
|
|
10 |
width: 100%;
|
11 |
}
|
12 |
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
.code-clipboard {
|
|
|
14 |
font-size: 20px;
|
15 |
-
|
16 |
-
|
17 |
-
|
|
|
|
|
18 |
}
|
19 |
|
20 |
.code-clipboard-container {
|
21 |
background: var(--surfaces-bg-card);
|
22 |
-
font-family: monospace;
|
23 |
max-height: 500px;
|
24 |
overflow: auto;
|
25 |
padding: 1rem;
|
26 |
position: relative;
|
27 |
}
|
28 |
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
.code-clipboard-container::-webkit-scrollbar-thumb {
|
30 |
border-color: var(--surfaces-bg-card);
|
31 |
}
|
@@ -73,10 +87,6 @@ img[src*="#chart-icon"] {
|
|
73 |
margin: 0;
|
74 |
}
|
75 |
|
76 |
-
.intro-text p a {
|
77 |
-
font-size: inherit;
|
78 |
-
}
|
79 |
-
|
80 |
.intro-text ul:last-of-type {
|
81 |
margin-bottom: 0;
|
82 |
}
|
|
|
10 |
width: 100%;
|
11 |
}
|
12 |
|
13 |
+
.open-in-new {
|
14 |
+
font-size: inherit;
|
15 |
+
margin-left: 4px;
|
16 |
+
vertical-align: middle;
|
17 |
+
}
|
18 |
+
|
19 |
.code-clipboard {
|
20 |
+
float: right;
|
21 |
font-size: 20px;
|
22 |
+
}
|
23 |
+
|
24 |
+
.code-clipboard pre {
|
25 |
+
font-family: monospace;
|
26 |
+
margin-bottom: 12px;
|
27 |
}
|
28 |
|
29 |
.code-clipboard-container {
|
30 |
background: var(--surfaces-bg-card);
|
|
|
31 |
max-height: 500px;
|
32 |
overflow: auto;
|
33 |
padding: 1rem;
|
34 |
position: relative;
|
35 |
}
|
36 |
|
37 |
+
.code-clipboard-container .pycafe-link,
|
38 |
+
.code-clipboard-container .pycafe-link:focus {
|
39 |
+
line-height: unset;
|
40 |
+
margin-bottom: 12px;
|
41 |
+
}
|
42 |
+
|
43 |
.code-clipboard-container::-webkit-scrollbar-thumb {
|
44 |
border-color: var(--surfaces-bg-card);
|
45 |
}
|
|
|
87 |
margin: 0;
|
88 |
}
|
89 |
|
|
|
|
|
|
|
|
|
90 |
.intro-text ul:last-of-type {
|
91 |
margin-bottom: 0;
|
92 |
}
|
chart_groups.py
CHANGED
@@ -2,7 +2,6 @@
|
|
2 |
|
3 |
import itertools
|
4 |
from dataclasses import dataclass
|
5 |
-
from typing import List
|
6 |
|
7 |
import pages.correlation
|
8 |
import pages.deviation
|
@@ -36,8 +35,8 @@ class ChartGroup:
|
|
36 |
"""Represents a group of charts like "Deviation"."""
|
37 |
|
38 |
name: str
|
39 |
-
pages:
|
40 |
-
incomplete_pages:
|
41 |
intro_text: str
|
42 |
icon: str = "" # ALL_CHART_GROUP is the only one that doesn't require an icon.
|
43 |
|
@@ -51,7 +50,6 @@ deviation_chart_group = ChartGroup(
|
|
51 |
name="Deviation",
|
52 |
pages=pages.deviation.pages,
|
53 |
incomplete_pages=[
|
54 |
-
IncompletePage("Diverging stacked bar"),
|
55 |
IncompletePage(title="Surplus deficit filled line"),
|
56 |
],
|
57 |
icon="Contrast Square",
|
|
|
2 |
|
3 |
import itertools
|
4 |
from dataclasses import dataclass
|
|
|
5 |
|
6 |
import pages.correlation
|
7 |
import pages.deviation
|
|
|
35 |
"""Represents a group of charts like "Deviation"."""
|
36 |
|
37 |
name: str
|
38 |
+
pages: list[vm.Page]
|
39 |
+
incomplete_pages: list[IncompletePage]
|
40 |
intro_text: str
|
41 |
icon: str = "" # ALL_CHART_GROUP is the only one that doesn't require an icon.
|
42 |
|
|
|
50 |
name="Deviation",
|
51 |
pages=pages.deviation.pages,
|
52 |
incomplete_pages=[
|
|
|
53 |
IncompletePage(title="Surplus deficit filled line"),
|
54 |
],
|
55 |
icon="Contrast Square",
|
custom_charts.py
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
"""Contains custom charts used inside the dashboard."""
|
2 |
|
3 |
-
from typing import
|
4 |
|
5 |
import pandas as pd
|
6 |
import vizro.plotly.express as px
|
@@ -13,181 +13,185 @@ from vizro.models.types import capture
|
|
13 |
# it can get out of sync. But probably we don't want the docstrings in the short code snippet.
|
14 |
# Ultimately these charts will probably move to vizro.charts anyway.
|
15 |
@capture("graph")
|
16 |
-
def butterfly(data_frame: pd.DataFrame,
|
17 |
-
"""Creates a
|
18 |
|
19 |
A butterfly chart is a type of bar chart where two sets of bars are displayed back-to-back, often used to compare
|
20 |
two sets of data.
|
21 |
|
22 |
Args:
|
23 |
-
data_frame
|
24 |
-
|
25 |
-
|
26 |
-
|
27 |
|
28 |
Returns:
|
29 |
-
go.Figure:
|
30 |
|
31 |
"""
|
32 |
-
fig =
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
go.Bar(
|
43 |
-
x=data_frame[x2],
|
44 |
-
y=data_frame[y],
|
45 |
-
orientation="h",
|
46 |
-
name=x2,
|
47 |
-
)
|
48 |
)
|
49 |
-
|
|
|
|
|
|
|
|
|
|
|
50 |
return fig
|
51 |
|
52 |
|
53 |
@capture("graph")
|
54 |
-
def sankey(data_frame: pd.DataFrame, source: str, target: str, value: str, labels:
|
55 |
-
"""Creates a
|
56 |
|
57 |
A Sankey chart is a type of flow diagram where the width of the arrows is proportional to the flow rate.
|
58 |
It is used to visualize the flow of resources or data between different stages or categories.
|
59 |
|
60 |
-
Args:
|
61 |
-
data_frame (pd.DataFrame): The data source for the chart.
|
62 |
-
source (str): The name of the column in the data frame for the source nodes.
|
63 |
-
target (str): The name of the column in the data frame for the target nodes.
|
64 |
-
value (str): The name of the column in the data frame for the values representing the flow between nodes.
|
65 |
-
labels (List[str]): A list of labels for the nodes.
|
66 |
-
|
67 |
-
Returns:
|
68 |
-
go.Figure: A Plotly Figure object representing the Sankey chart.
|
69 |
-
|
70 |
For detailed information on additional parameters and customization, refer to the Plotly documentation:
|
71 |
https://plotly.com/python/reference/sankey/
|
72 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
73 |
"""
|
74 |
-
|
75 |
-
data=
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
]
|
91 |
)
|
92 |
-
fig.update_layout(barmode="relative")
|
93 |
-
return fig
|
94 |
|
95 |
|
96 |
@capture("graph")
|
97 |
-
def column_and_line(
|
98 |
-
|
|
|
|
|
|
|
|
|
|
|
99 |
|
100 |
This function generates a chart with a bar graph for one variable (y-axis 1) and a line graph for another variable
|
101 |
(y-axis 2), sharing the same x-axis. The y-axes for the bar and line graphs are synchronized and overlaid.
|
102 |
|
103 |
Args:
|
104 |
-
data_frame
|
105 |
-
|
106 |
-
|
107 |
-
|
|
|
108 |
|
109 |
Returns:
|
110 |
-
go.Figure:
|
111 |
|
112 |
"""
|
113 |
-
|
|
|
|
|
|
|
|
|
114 |
|
115 |
-
|
116 |
-
|
117 |
-
|
|
|
|
|
|
|
118 |
)
|
119 |
|
120 |
-
|
121 |
-
|
122 |
-
secondary_y=True,
|
123 |
-
)
|
124 |
|
125 |
-
fig.update_layout(
|
126 |
-
xaxis={"type": "category", "title": x},
|
127 |
-
yaxis={"tickmode": "sync", "title": y_column},
|
128 |
-
yaxis2={"tickmode": "sync", "overlaying": "y", "title": y_line},
|
129 |
-
)
|
130 |
|
131 |
return fig
|
132 |
|
133 |
|
134 |
@capture("graph")
|
135 |
-
def categorical_column(data_frame: pd.DataFrame,
|
136 |
-
"""Creates
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
142 |
# So ticks are aligned with bars when xaxes values are numbers (e.g. years)
|
143 |
fig.update_xaxes(type="category")
|
144 |
return fig
|
145 |
|
146 |
|
147 |
@capture("graph")
|
148 |
-
def waterfall(data_frame: pd.DataFrame, x: str, y: str, measure:
|
149 |
-
"""Creates a waterfall chart
|
150 |
|
151 |
A Waterfall chart visually breaks down the cumulative effect of sequential positive and negative values,
|
152 |
showing how each value contributes to the total.
|
153 |
|
154 |
-
Args:
|
155 |
-
data_frame (pd.DataFrame): The data source for the chart.
|
156 |
-
x (str): Column name in `data_frame` for x-axis values.
|
157 |
-
y (str): Column name in `data_frame` for y-axis values.
|
158 |
-
measure (List[str]): List specifying the type of each bar, can be "relative", "total", or "absolute".
|
159 |
-
|
160 |
-
Returns:
|
161 |
-
go.Figure: A Plotly Figure object representing the Waterfall chart.
|
162 |
-
|
163 |
For additional parameters and customization options, see the Plotly documentation:
|
164 |
https://plotly.com/python/reference/waterfall/
|
165 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
166 |
"""
|
167 |
-
|
168 |
-
go.Waterfall(
|
169 |
-
|
170 |
-
y=data_frame[y],
|
171 |
-
measure=data_frame[measure],
|
172 |
-
)
|
173 |
)
|
174 |
-
fig.update_layout(showlegend=False)
|
175 |
-
return fig
|
176 |
|
177 |
|
178 |
@capture("graph")
|
179 |
-
def radar(data_frame, **kwargs) -> go.Figure:
|
180 |
-
"""Creates a radar chart
|
181 |
|
182 |
A radar chart is a type of data visualization in which there are three or more
|
183 |
variables represented on axes that originate from the same central point.
|
184 |
|
185 |
Args:
|
186 |
-
data_frame
|
187 |
-
**kwargs: Keyword arguments
|
|
|
188 |
|
189 |
Returns:
|
190 |
-
|
191 |
|
192 |
"""
|
193 |
fig = px.line_polar(data_frame, **kwargs)
|
@@ -196,40 +200,107 @@ def radar(data_frame, **kwargs) -> go.Figure:
|
|
196 |
|
197 |
|
198 |
@capture("graph")
|
199 |
-
def dumbbell(data_frame: pd.DataFrame,
|
200 |
-
"""Creates a dumbbell chart
|
201 |
|
202 |
A dumbbell plot is a type of dot plot where the points, displaying different groups, are connected with a straight
|
203 |
line. They are ideal for illustrating differences or gaps between two points.
|
204 |
|
|
|
|
|
205 |
Args:
|
206 |
-
data_frame
|
207 |
-
|
208 |
-
|
209 |
-
|
210 |
|
211 |
Returns:
|
212 |
-
go.Figure:
|
213 |
-
|
214 |
-
Inspired by: https://community.plotly.com/t/how-to-make-dumbbell-plots-in-plotly-python/47762
|
215 |
-
|
216 |
"""
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
222 |
fig.add_shape(
|
|
|
223 |
type="line",
|
224 |
layer="below",
|
225 |
-
y0=y_value,
|
226 |
-
y1=y_value,
|
227 |
-
x0=group[x].min(),
|
228 |
-
x1=group[x].max(),
|
229 |
line_color="grey",
|
230 |
line_width=3,
|
231 |
)
|
232 |
|
233 |
-
# Increase size of dots
|
234 |
fig.update_traces(marker_size=12)
|
235 |
return fig
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
"""Contains custom charts used inside the dashboard."""
|
2 |
|
3 |
+
from typing import Union
|
4 |
|
5 |
import pandas as pd
|
6 |
import vizro.plotly.express as px
|
|
|
13 |
# it can get out of sync. But probably we don't want the docstrings in the short code snippet.
|
14 |
# Ultimately these charts will probably move to vizro.charts anyway.
|
15 |
@capture("graph")
|
16 |
+
def butterfly(data_frame: pd.DataFrame, **kwargs) -> go.Figure:
|
17 |
+
"""Creates a butterfly chart based on px.bar.
|
18 |
|
19 |
A butterfly chart is a type of bar chart where two sets of bars are displayed back-to-back, often used to compare
|
20 |
two sets of data.
|
21 |
|
22 |
Args:
|
23 |
+
data_frame: DataFrame for the chart. Can be long form or wide form.
|
24 |
+
See https://plotly.com/python/wide-form/.
|
25 |
+
**kwargs: Keyword arguments to pass into px.bar (e.g. x, y, labels).
|
26 |
+
See https://plotly.com/python-api-reference/generated/plotly.express.bar.html.
|
27 |
|
28 |
Returns:
|
29 |
+
go.Figure: Butterfly chart.
|
30 |
|
31 |
"""
|
32 |
+
fig = px.bar(data_frame, **kwargs)
|
33 |
+
|
34 |
+
orientation = fig.data[0].orientation
|
35 |
+
x_or_y = "x" if orientation == "h" else "y"
|
36 |
+
|
37 |
+
# Create new x or y axis with scale reversed (so going from 0 at the midpoint outwards) to do back-to-back bars.
|
38 |
+
fig.update_traces({f"{x_or_y}axis": f"{x_or_y}2"}, selector=1)
|
39 |
+
fig.update_layout({f"{x_or_y}axis2": fig.layout[f"{x_or_y}axis"]})
|
40 |
+
fig.update_layout(
|
41 |
+
{f"{x_or_y}axis": {"autorange": "reversed", "domain": [0, 0.5]}, f"{x_or_y}axis2": {"domain": [0.5, 1]}}
|
|
|
|
|
|
|
|
|
|
|
|
|
42 |
)
|
43 |
+
|
44 |
+
if orientation == "h":
|
45 |
+
fig.add_vline(x=0, line_width=2, line_color="grey")
|
46 |
+
else:
|
47 |
+
fig.add_hline(y=0, line_width=2, line_color="grey")
|
48 |
+
|
49 |
return fig
|
50 |
|
51 |
|
52 |
@capture("graph")
|
53 |
+
def sankey(data_frame: pd.DataFrame, source: str, target: str, value: str, labels: list[str]) -> go.Figure:
|
54 |
+
"""Creates a Sankey chart based on go.Sankey.
|
55 |
|
56 |
A Sankey chart is a type of flow diagram where the width of the arrows is proportional to the flow rate.
|
57 |
It is used to visualize the flow of resources or data between different stages or categories.
|
58 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
59 |
For detailed information on additional parameters and customization, refer to the Plotly documentation:
|
60 |
https://plotly.com/python/reference/sankey/
|
61 |
|
62 |
+
Args:
|
63 |
+
data_frame: DataFrame for the chart.
|
64 |
+
source: The name of the column in data_frame for source nodes.
|
65 |
+
target: The name of the column in data_frame for target nodes.
|
66 |
+
value: The name of the column in data_frame for the values representing the flow between nodes.
|
67 |
+
labels: A list of labels for the nodes.
|
68 |
+
|
69 |
+
Returns:
|
70 |
+
go.Figure: Sankey chart.
|
71 |
"""
|
72 |
+
return go.Figure(
|
73 |
+
data=go.Sankey(
|
74 |
+
node={
|
75 |
+
"pad": 16,
|
76 |
+
"thickness": 16,
|
77 |
+
"label": labels,
|
78 |
+
},
|
79 |
+
link={
|
80 |
+
"source": data_frame[source],
|
81 |
+
"target": data_frame[target],
|
82 |
+
"value": data_frame[value],
|
83 |
+
"label": labels,
|
84 |
+
"color": "rgba(205, 209, 228, 0.4)",
|
85 |
+
},
|
86 |
+
),
|
87 |
+
layout={"barmode": "relative"},
|
|
|
88 |
)
|
|
|
|
|
89 |
|
90 |
|
91 |
@capture("graph")
|
92 |
+
def column_and_line(
|
93 |
+
data_frame: pd.DataFrame,
|
94 |
+
x: Union[str, pd.Series, list[str], list[pd.Series]],
|
95 |
+
y_column: Union[str, pd.Series, list[str], list[pd.Series]],
|
96 |
+
y_line: Union[str, pd.Series, list[str], list[pd.Series]],
|
97 |
+
) -> go.Figure:
|
98 |
+
"""Creates a combined column and line chart based on px.bar and px.line.
|
99 |
|
100 |
This function generates a chart with a bar graph for one variable (y-axis 1) and a line graph for another variable
|
101 |
(y-axis 2), sharing the same x-axis. The y-axes for the bar and line graphs are synchronized and overlaid.
|
102 |
|
103 |
Args:
|
104 |
+
data_frame: DataFrame for the chart. Can be long form or wide form.
|
105 |
+
See https://plotly.com/python/wide-form/.
|
106 |
+
x: Either a name of a column in data_frame, or a pandas Series or array_like object.
|
107 |
+
y_column: Either a name of a column in data_frame, or a pandas Series or array_like object.
|
108 |
+
y_line: Either a name of a column in data_frame, or a pandas Series or array_like object.
|
109 |
|
110 |
Returns:
|
111 |
+
go.Figure: Combined column and line chart.
|
112 |
|
113 |
"""
|
114 |
+
# We use px.bar and px.line so that we get the plotly express hoverdata, axes titles etc. Bar is used arbitrarily
|
115 |
+
# selected as the "base" plot and then line added on top of it. This means manually incrementing
|
116 |
+
# color_discrete_sequence for the line plot so that the colors are not the same for bar and line.
|
117 |
+
bar = px.bar(data_frame, x=x, y=y_column)
|
118 |
+
fig = make_subplots(figure=bar, specs=[[{"secondary_y": True}]])
|
119 |
|
120 |
+
line = px.line(
|
121 |
+
data_frame,
|
122 |
+
x=x,
|
123 |
+
y=y_line,
|
124 |
+
markers=True,
|
125 |
+
color_discrete_sequence=fig.layout.template.layout.colorway[len(bar.data) :],
|
126 |
)
|
127 |
|
128 |
+
for trace in line.data:
|
129 |
+
fig.add_trace(trace, secondary_y=True)
|
|
|
|
|
130 |
|
131 |
+
fig.update_layout(yaxis2={"tickmode": "sync", "overlaying": "y", "title": line.layout.yaxis.title})
|
|
|
|
|
|
|
|
|
132 |
|
133 |
return fig
|
134 |
|
135 |
|
136 |
@capture("graph")
|
137 |
+
def categorical_column(data_frame: pd.DataFrame, **kwargs) -> go.Figure:
|
138 |
+
"""Creates categorical bar chart based on px.bar.
|
139 |
+
|
140 |
+
Args:
|
141 |
+
data_frame: DataFrame for the chart. Can be long form or wide form.
|
142 |
+
See https://plotly.com/python/wide-form/.
|
143 |
+
**kwargs: Keyword arguments to pass into px.bar (e.g. x, y, labels).
|
144 |
+
See https://plotly.com/python-api-reference/generated/plotly.express.bar.html.
|
145 |
+
|
146 |
+
Returns:
|
147 |
+
go.Figure: Categorical column chart.
|
148 |
+
|
149 |
+
"""
|
150 |
+
fig = px.bar(data_frame, **kwargs)
|
151 |
# So ticks are aligned with bars when xaxes values are numbers (e.g. years)
|
152 |
fig.update_xaxes(type="category")
|
153 |
return fig
|
154 |
|
155 |
|
156 |
@capture("graph")
|
157 |
+
def waterfall(data_frame: pd.DataFrame, x: str, y: str, measure: list[str]) -> go.Figure:
|
158 |
+
"""Creates a waterfall chart based on go.Waterfall.
|
159 |
|
160 |
A Waterfall chart visually breaks down the cumulative effect of sequential positive and negative values,
|
161 |
showing how each value contributes to the total.
|
162 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
163 |
For additional parameters and customization options, see the Plotly documentation:
|
164 |
https://plotly.com/python/reference/waterfall/
|
165 |
|
166 |
+
Args:
|
167 |
+
data_frame: TDataFrame for the chart.
|
168 |
+
x: Column name in data_frame for x-axis values.
|
169 |
+
y: Column name in data_frame for y-axis values.
|
170 |
+
measure: List specifying the type of each bar, can be "relative", "total", or "absolute".
|
171 |
+
|
172 |
+
Returns:
|
173 |
+
go.Figure: Waterfall chart.
|
174 |
"""
|
175 |
+
return go.Figure(
|
176 |
+
data=go.Waterfall(x=data_frame[x], y=data_frame[y], measure=data_frame[measure]),
|
177 |
+
layout={"showlegend": False},
|
|
|
|
|
|
|
178 |
)
|
|
|
|
|
179 |
|
180 |
|
181 |
@capture("graph")
|
182 |
+
def radar(data_frame: pd.DataFrame, **kwargs) -> go.Figure:
|
183 |
+
"""Creates a radar chart based on px.line_polar.
|
184 |
|
185 |
A radar chart is a type of data visualization in which there are three or more
|
186 |
variables represented on axes that originate from the same central point.
|
187 |
|
188 |
Args:
|
189 |
+
data_frame: DataFrame for the chart.
|
190 |
+
**kwargs: Keyword arguments to pass into px.line_polar (e.g. r, theta).
|
191 |
+
See https://plotly.com/python-api-reference/generated/plotly.express.line_polar.html.
|
192 |
|
193 |
Returns:
|
194 |
+
go.Figure: A Plotly Figure object of the radar chart.
|
195 |
|
196 |
"""
|
197 |
fig = px.line_polar(data_frame, **kwargs)
|
|
|
200 |
|
201 |
|
202 |
@capture("graph")
|
203 |
+
def dumbbell(data_frame: pd.DataFrame, **kwargs) -> go.Figure:
|
204 |
+
"""Creates a dumbbell chart based on px.scatter.
|
205 |
|
206 |
A dumbbell plot is a type of dot plot where the points, displaying different groups, are connected with a straight
|
207 |
line. They are ideal for illustrating differences or gaps between two points.
|
208 |
|
209 |
+
Inspired by: https://community.plotly.com/t/how-to-make-dumbbell-plots-in-plotly-python/47762
|
210 |
+
|
211 |
Args:
|
212 |
+
data_frame: DataFrame for the chart. Can be long form or wide form.
|
213 |
+
See https://plotly.com/python/wide-form/.
|
214 |
+
**kwargs: Keyword arguments to pass into px.scatter (e.g. x, y, labels).
|
215 |
+
See https://plotly.com/python-api-reference/generated/plotly.scatter.html.
|
216 |
|
217 |
Returns:
|
218 |
+
go.Figure: Dumbbell chart.
|
|
|
|
|
|
|
219 |
"""
|
220 |
+
fig = px.scatter(data_frame, **kwargs)
|
221 |
+
|
222 |
+
orientation = fig.data[0].orientation
|
223 |
+
x_or_y = "x" if orientation == "h" else "y"
|
224 |
+
y_or_x = "y" if orientation == "h" else "x"
|
225 |
+
|
226 |
+
# Add lines between every pair of points.
|
227 |
+
for x_or_y_0, x_or_y_1, y_or_x_0, y_or_x_1 in zip(
|
228 |
+
fig.data[0][x_or_y],
|
229 |
+
fig.data[1][x_or_y],
|
230 |
+
fig.data[0][y_or_x],
|
231 |
+
fig.data[1][y_or_x],
|
232 |
+
):
|
233 |
fig.add_shape(
|
234 |
+
**{f"{x_or_y}0": x_or_y_0, f"{x_or_y}1": x_or_y_1, f"{y_or_x}0": y_or_x_0, f"{y_or_x}1": y_or_x_1},
|
235 |
type="line",
|
236 |
layer="below",
|
|
|
|
|
|
|
|
|
237 |
line_color="grey",
|
238 |
line_width=3,
|
239 |
)
|
240 |
|
|
|
241 |
fig.update_traces(marker_size=12)
|
242 |
return fig
|
243 |
+
|
244 |
+
|
245 |
+
@capture("graph")
|
246 |
+
def diverging_stacked_bar(data_frame: pd.DataFrame, **kwargs) -> go.Figure:
|
247 |
+
"""Creates a diverging stacked bar chart based on px.bar.
|
248 |
+
|
249 |
+
This type of chart is a variant of the standard stacked bar chart, with bars aligned on a central baseline to
|
250 |
+
show both positive and negative values. Each bar is segmented to represent different categories.
|
251 |
+
|
252 |
+
This function is not suitable for diverging stacked bar charts that include a neutral category. The first half of
|
253 |
+
bars plotted are assumed to be negative ("Disagree") and the second half are assumed to be positive ("Agree").
|
254 |
+
|
255 |
+
Inspired by: https://community.plotly.com/t/need-help-in-making-diverging-stacked-bar-charts/34023
|
256 |
+
|
257 |
+
Args:
|
258 |
+
data_frame: DataFrame for the chart. Can be long form or wide form.
|
259 |
+
See https://plotly.com/python/wide-form/.
|
260 |
+
**kwargs: Keyword arguments to pass into px.bar (e.g. x, y, labels).
|
261 |
+
See https://plotly.com/python-api-reference/generated/plotly.express.bar.html.
|
262 |
+
|
263 |
+
Returns:
|
264 |
+
go.Figure: Diverging stacked bar chart.
|
265 |
+
"""
|
266 |
+
fig = px.bar(data_frame, **kwargs)
|
267 |
+
|
268 |
+
# Fix legend position according to the order of traces. This ensures that "Strongly disagree" comes before
|
269 |
+
# "Disagree".
|
270 |
+
for i, trace in enumerate(fig.data):
|
271 |
+
trace.update(legendrank=i)
|
272 |
+
|
273 |
+
if "color_discrete_sequence" not in kwargs and "color_discrete_map" not in kwargs:
|
274 |
+
# Make a discrete diverging colorscale by sampling the right number of colors.
|
275 |
+
# Need to explicitly convert colorscale to list of lists due to plotly bug/inconsistency:
|
276 |
+
# https://github.com/plotly/plotly.py/issues/4808
|
277 |
+
colorscale = [list(x) for x in fig.layout.template.layout.colorscale.diverging]
|
278 |
+
colors = px.colors.sample_colorscale(colorscale, len(fig.data), 0.2, 0.8)
|
279 |
+
for trace, color in zip(fig.data, colors):
|
280 |
+
trace.update(marker_color=color)
|
281 |
+
|
282 |
+
# Plotly draws traces in order they appear in fig.data, starting from x=0 and then stacking outwards.
|
283 |
+
# We need negative traces to be ordered so that "Disagree" comes before "Strongly disagree", so reverse the
|
284 |
+
# order of first half of traces.
|
285 |
+
mutable_traces = list(fig.data)
|
286 |
+
mutable_traces[: len(fig.data) // 2] = reversed(fig.data[: len(fig.data) // 2])
|
287 |
+
fig.data = mutable_traces
|
288 |
+
|
289 |
+
# Create new x or y axis with scale reversed (so going from 0 at the midpoint outwards) to do negative bars.
|
290 |
+
orientation = fig.data[0].orientation
|
291 |
+
x_or_y = "x" if orientation == "h" else "y"
|
292 |
+
|
293 |
+
for trace_idx in range(len(fig.data) // 2):
|
294 |
+
fig.update_traces({f"{x_or_y}axis": f"{x_or_y}2"}, selector=trace_idx)
|
295 |
+
|
296 |
+
fig.update_layout({f"{x_or_y}axis2": fig.layout[f"{x_or_y}axis"]})
|
297 |
+
fig.update_layout(
|
298 |
+
{f"{x_or_y}axis": {"autorange": "reversed", "domain": [0, 0.5]}, f"{x_or_y}axis2": {"domain": [0.5, 1]}}
|
299 |
+
)
|
300 |
+
|
301 |
+
if orientation == "h":
|
302 |
+
fig.add_vline(x=0, line_width=2, line_color="grey")
|
303 |
+
else:
|
304 |
+
fig.add_hline(y=0, line_width=2, line_color="grey")
|
305 |
+
|
306 |
+
return fig
|
custom_components.py
CHANGED
@@ -11,31 +11,38 @@ try:
|
|
11 |
except ImportError: # pragma: no cov
|
12 |
from pydantic import Field
|
13 |
|
|
|
|
|
14 |
|
15 |
class CodeClipboard(vm.VizroBaseModel):
|
16 |
"""Code snippet with a copy to clipboard button."""
|
17 |
|
18 |
type: Literal["code_clipboard"] = "code_clipboard"
|
19 |
code: str
|
|
|
20 |
language: str = ""
|
21 |
|
22 |
def build(self):
|
23 |
"""Returns the code clipboard component inside an accordion."""
|
24 |
markdown_code = "\n".join([f"```{self.language}", self.code, "```"])
|
25 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
26 |
[
|
27 |
-
|
28 |
-
|
29 |
-
|
30 |
-
dcc.Markdown(markdown_code, id=self.id),
|
31 |
-
dcc.Clipboard(target_id=self.id, className="code-clipboard"),
|
32 |
-
],
|
33 |
-
className="code-clipboard-container",
|
34 |
-
),
|
35 |
-
title="SHOW CODE",
|
36 |
-
)
|
37 |
],
|
38 |
-
|
39 |
)
|
40 |
|
41 |
|
@@ -68,4 +75,4 @@ class FlexContainer(vm.Container):
|
|
68 |
|
69 |
vm.Container.add_type("components", FlexContainer)
|
70 |
vm.Container.add_type("components", Markdown)
|
71 |
-
vm.
|
|
|
11 |
except ImportError: # pragma: no cov
|
12 |
from pydantic import Field
|
13 |
|
14 |
+
from urllib.parse import quote
|
15 |
+
|
16 |
|
17 |
class CodeClipboard(vm.VizroBaseModel):
|
18 |
"""Code snippet with a copy to clipboard button."""
|
19 |
|
20 |
type: Literal["code_clipboard"] = "code_clipboard"
|
21 |
code: str
|
22 |
+
mode: Literal["vizro", "plotly"]
|
23 |
language: str = ""
|
24 |
|
25 |
def build(self):
|
26 |
"""Returns the code clipboard component inside an accordion."""
|
27 |
markdown_code = "\n".join([f"```{self.language}", self.code, "```"])
|
28 |
+
|
29 |
+
pycafe_link = dbc.Button(
|
30 |
+
[
|
31 |
+
"Edit code live on PyCafe",
|
32 |
+
html.Span("open_in_new", className="material-symbols-outlined open-in-new"),
|
33 |
+
],
|
34 |
+
href=f"https://py.cafe/snippet/vizro/v1#code={quote(self.code)}",
|
35 |
+
target="_blank",
|
36 |
+
className="pycafe-link",
|
37 |
+
)
|
38 |
+
|
39 |
+
return html.Div(
|
40 |
[
|
41 |
+
pycafe_link if self.mode == "vizro" else None,
|
42 |
+
dcc.Clipboard(target_id=self.id, className="code-clipboard"),
|
43 |
+
dcc.Markdown(markdown_code, id=self.id),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
44 |
],
|
45 |
+
className="code-clipboard-container",
|
46 |
)
|
47 |
|
48 |
|
|
|
75 |
|
76 |
vm.Container.add_type("components", FlexContainer)
|
77 |
vm.Container.add_type("components", Markdown)
|
78 |
+
vm.Container.add_type("components", CodeClipboard)
|
pages/__init__.py
CHANGED
@@ -1,5 +1 @@
|
|
1 |
# TODO: eventually deduplicate page generation into a function rather than copying and pasting across files?
|
2 |
-
# TODO: think about the best way to do code examples, e.g.
|
3 |
-
# - do we want full dashboard example or plot-only example?
|
4 |
-
# - or both? Could be done using a toggle switch or multiple tabs.
|
5 |
-
# - a link to PyCafe showing the dashboard code?
|
|
|
1 |
# TODO: eventually deduplicate page generation into a function rather than copying and pasting across files?
|
|
|
|
|
|
|
|
pages/_factories.py
CHANGED
@@ -5,10 +5,9 @@ each chart type used in different groups.
|
|
5 |
"""
|
6 |
|
7 |
import vizro.models as vm
|
8 |
-
import vizro.plotly.express as px
|
9 |
-
from custom_charts import butterfly, column_and_line, waterfall
|
10 |
|
11 |
-
from pages._pages_utils import PAGE_GRID,
|
|
|
12 |
|
13 |
|
14 |
def butterfly_factory(group: str):
|
@@ -37,8 +36,19 @@ def butterfly_factory(group: str):
|
|
37 |
categories.
|
38 |
"""
|
39 |
),
|
40 |
-
vm.Graph(figure=butterfly
|
41 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
42 |
],
|
43 |
)
|
44 |
|
@@ -69,8 +79,19 @@ def connected_scatter_factory(group: str):
|
|
69 |
avoid misinterpretation.
|
70 |
"""
|
71 |
),
|
72 |
-
vm.Graph(figure=
|
73 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
74 |
],
|
75 |
)
|
76 |
|
@@ -99,15 +120,19 @@ def column_and_line_factory(group: str):
|
|
99 |
for other types of data comparisons.
|
100 |
"""
|
101 |
),
|
102 |
-
vm.Graph(
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
|
|
|
|
|
|
|
|
|
|
109 |
),
|
110 |
-
make_code_clipboard_from_py_file("column_and_line.py"),
|
111 |
],
|
112 |
)
|
113 |
|
@@ -139,14 +164,18 @@ def waterfall_factory(group: str):
|
|
139 |
colors for positive and negative values, and arrange categories logically to tell a coherent story.
|
140 |
"""
|
141 |
),
|
142 |
-
vm.Graph(
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
|
|
|
|
|
|
|
|
|
|
149 |
),
|
150 |
-
make_code_clipboard_from_py_file("waterfall.py"),
|
151 |
],
|
152 |
)
|
|
|
5 |
"""
|
6 |
|
7 |
import vizro.models as vm
|
|
|
|
|
8 |
|
9 |
+
from pages._pages_utils import PAGE_GRID, make_code_clipboard_from_py_file
|
10 |
+
from pages.examples import butterfly, column_and_line, connected_scatter, waterfall
|
11 |
|
12 |
|
13 |
def butterfly_factory(group: str):
|
|
|
36 |
categories.
|
37 |
"""
|
38 |
),
|
39 |
+
vm.Graph(figure=butterfly.fig),
|
40 |
+
vm.Tabs(
|
41 |
+
tabs=[
|
42 |
+
vm.Container(
|
43 |
+
title="Vizro dashboard",
|
44 |
+
components=[make_code_clipboard_from_py_file("butterfly.py", mode="vizro")],
|
45 |
+
),
|
46 |
+
vm.Container(
|
47 |
+
title="Plotly figure",
|
48 |
+
components=[make_code_clipboard_from_py_file("butterfly.py", mode="plotly")],
|
49 |
+
),
|
50 |
+
]
|
51 |
+
),
|
52 |
],
|
53 |
)
|
54 |
|
|
|
79 |
avoid misinterpretation.
|
80 |
"""
|
81 |
),
|
82 |
+
vm.Graph(figure=connected_scatter.fig),
|
83 |
+
vm.Tabs(
|
84 |
+
tabs=[
|
85 |
+
vm.Container(
|
86 |
+
title="Vizro dashboard",
|
87 |
+
components=[make_code_clipboard_from_py_file("connected_scatter.py", mode="vizro")],
|
88 |
+
),
|
89 |
+
vm.Container(
|
90 |
+
title="Plotly figure",
|
91 |
+
components=[make_code_clipboard_from_py_file("connected_scatter.py", mode="plotly")],
|
92 |
+
),
|
93 |
+
]
|
94 |
+
),
|
95 |
],
|
96 |
)
|
97 |
|
|
|
120 |
for other types of data comparisons.
|
121 |
"""
|
122 |
),
|
123 |
+
vm.Graph(figure=column_and_line.fig),
|
124 |
+
vm.Tabs(
|
125 |
+
tabs=[
|
126 |
+
vm.Container(
|
127 |
+
title="Vizro dashboard",
|
128 |
+
components=[make_code_clipboard_from_py_file("column_and_line.py", mode="vizro")],
|
129 |
+
),
|
130 |
+
vm.Container(
|
131 |
+
title="Plotly figure",
|
132 |
+
components=[make_code_clipboard_from_py_file("column_and_line.py", mode="plotly")],
|
133 |
+
),
|
134 |
+
]
|
135 |
),
|
|
|
136 |
],
|
137 |
)
|
138 |
|
|
|
164 |
colors for positive and negative values, and arrange categories logically to tell a coherent story.
|
165 |
"""
|
166 |
),
|
167 |
+
vm.Graph(figure=waterfall.fig),
|
168 |
+
vm.Tabs(
|
169 |
+
tabs=[
|
170 |
+
vm.Container(
|
171 |
+
title="Vizro dashboard",
|
172 |
+
components=[make_code_clipboard_from_py_file("waterfall.py", mode="vizro")],
|
173 |
+
),
|
174 |
+
vm.Container(
|
175 |
+
title="Plotly figure",
|
176 |
+
components=[make_code_clipboard_from_py_file("waterfall.py", mode="plotly")],
|
177 |
+
),
|
178 |
+
]
|
179 |
),
|
|
|
180 |
],
|
181 |
)
|
pages/_pages_utils.py
CHANGED
@@ -3,105 +3,57 @@
|
|
3 |
import logging
|
4 |
from pathlib import Path
|
5 |
|
|
|
6 |
import black
|
7 |
-
import
|
8 |
-
import vizro.plotly.express as px
|
9 |
from custom_components import CodeClipboard
|
10 |
|
11 |
# To disable logging info messages caused by black.format_str: https://github.com/psf/black/issues/2058
|
12 |
logging.getLogger("blib2to3").setLevel(logging.ERROR)
|
13 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
|
15 |
-
def make_code_clipboard_from_py_file(filepath: str):
|
16 |
# Black doesn't yet have a Python API, so format_str might not work at some point in the future.
|
17 |
# https://black.readthedocs.io/en/stable/faq.html#does-black-have-an-api
|
18 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
return CodeClipboard(
|
20 |
-
code=
|
|
|
21 |
language="python",
|
22 |
)
|
23 |
|
24 |
|
25 |
PAGE_GRID = [[0, 0, 0, 0, 0, 0, 0]] * 2 + [[1, 1, 1, 1, 2, 2, 2]] * 5
|
26 |
-
|
27 |
-
# DATA --------------------------------------------------------------
|
28 |
-
gapminder = px.data.gapminder()
|
29 |
-
iris = px.data.iris()
|
30 |
-
stocks = px.data.stocks()
|
31 |
-
tips = px.data.tips()
|
32 |
-
wind = px.data.wind()
|
33 |
-
|
34 |
-
ages = pd.DataFrame(
|
35 |
-
{
|
36 |
-
"Age": ["0-19", "20-29", "30-39", "40-49", "50-59", ">=60"],
|
37 |
-
"Male": [800, 2000, 4200, 5000, 2100, 800],
|
38 |
-
"Female": [1000, 3000, 3500, 3800, 3600, 700],
|
39 |
-
}
|
40 |
-
)
|
41 |
-
sankey_data = pd.DataFrame(
|
42 |
-
{
|
43 |
-
"Origin": [0, 1, 0, 2, 3, 3],
|
44 |
-
"Destination": [2, 3, 3, 4, 4, 5],
|
45 |
-
"Value": [8, 4, 2, 8, 4, 2],
|
46 |
-
}
|
47 |
-
)
|
48 |
-
|
49 |
-
funnel_data = pd.DataFrame(
|
50 |
-
{"Stage": ["Leads", "Sales calls", "Follow-up", "Conversion", "Sales"], "Value": [10, 7, 4, 2, 1]}
|
51 |
-
)
|
52 |
-
|
53 |
-
stepped_line_data = pd.DataFrame(
|
54 |
-
{
|
55 |
-
"year": [1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003],
|
56 |
-
"rate": [0.10, 0.12, 0.15, 0.13, 0.14, 0.13, 0.14, 0.16, 0.15],
|
57 |
-
}
|
58 |
-
)
|
59 |
-
|
60 |
-
|
61 |
-
carshare = px.data.carshare()
|
62 |
-
|
63 |
-
tasks = pd.DataFrame(
|
64 |
-
[
|
65 |
-
{"Task": "Job A", "Start": "2009-01-01", "Finish": "2009-02-28"},
|
66 |
-
{"Task": "Job B", "Start": "2009-03-05", "Finish": "2009-04-15"},
|
67 |
-
{"Task": "Job C", "Start": "2009-02-20", "Finish": "2009-05-30"},
|
68 |
-
]
|
69 |
-
)
|
70 |
-
|
71 |
-
waterfall_data = pd.DataFrame(
|
72 |
-
{
|
73 |
-
"x": ["Sales", "Consulting", "Net revenue", "Purchases", "Other expenses", "Profit before tax"],
|
74 |
-
"y": [60, 80, 0, -40, -20, 0],
|
75 |
-
"measure": ["relative", "relative", "total", "relative", "relative", "total"],
|
76 |
-
}
|
77 |
-
)
|
78 |
-
|
79 |
-
|
80 |
-
pastries = pd.DataFrame(
|
81 |
-
{
|
82 |
-
"pastry": [
|
83 |
-
"Scones",
|
84 |
-
"Bagels",
|
85 |
-
"Muffins",
|
86 |
-
"Cakes",
|
87 |
-
"Donuts",
|
88 |
-
"Cookies",
|
89 |
-
"Croissants",
|
90 |
-
"Eclairs",
|
91 |
-
"Brownies",
|
92 |
-
"Tarts",
|
93 |
-
"Macarons",
|
94 |
-
"Pies",
|
95 |
-
],
|
96 |
-
"Profit Ratio": [-0.10, -0.15, -0.05, 0.10, 0.05, 0.20, 0.15, -0.08, 0.08, -0.12, 0.02, -0.07],
|
97 |
-
}
|
98 |
-
)
|
99 |
-
|
100 |
-
|
101 |
-
salaries = pd.DataFrame(
|
102 |
-
{
|
103 |
-
"Job": ["Developer", "Analyst", "Manager", "Specialist"] * 2,
|
104 |
-
"Salary": [60000, 55000, 70000, 50000, 130000, 110000, 96400, 80000],
|
105 |
-
"Range": ["Min"] * 4 + ["Max"] * 4,
|
106 |
-
}
|
107 |
-
)
|
|
|
3 |
import logging
|
4 |
from pathlib import Path
|
5 |
|
6 |
+
import autoflake
|
7 |
import black
|
8 |
+
import isort
|
|
|
9 |
from custom_components import CodeClipboard
|
10 |
|
11 |
# To disable logging info messages caused by black.format_str: https://github.com/psf/black/issues/2058
|
12 |
logging.getLogger("blib2to3").setLevel(logging.ERROR)
|
13 |
|
14 |
+
VIZRO_CODE_TEMPLATE = """
|
15 |
+
import vizro.models as vm
|
16 |
+
from vizro import Vizro
|
17 |
+
{example_code}
|
18 |
+
page = vm.Page(title="My page", components=[vm.Graph(figure=fig)])
|
19 |
+
dashboard = vm.Dashboard(pages=[page])
|
20 |
+
Vizro().build(dashboard).run()
|
21 |
+
"""
|
22 |
+
|
23 |
+
|
24 |
+
def _format_and_lint(code_string: str, line_length: int) -> str:
|
25 |
+
"""Inspired by vizro.models._base._format_and_lint. The only difference is that this does isort too."""
|
26 |
+
# Tracking https://github.com/astral-sh/ruff/issues/659 for proper Python API
|
27 |
+
# Good example: https://github.com/astral-sh/ruff/issues/8401#issuecomment-1788806462
|
28 |
+
# While we wait for the API, we can use autoflake and black to process code strings
|
29 |
+
# Isort is needed since otherwise example code looks quite strange sometimes. Autoflake is needed since isort can't
|
30 |
+
# remove imports by itself: https://github.com/PyCQA/isort/issues/1105.
|
31 |
+
|
32 |
+
removed_imports = autoflake.fix_code(code_string, remove_all_unused_imports=True)
|
33 |
+
sorted_imports = isort.code(removed_imports)
|
34 |
+
# Black doesn't yet have a Python API, so format_str might not work at some point in the future.
|
35 |
+
# https://black.readthedocs.io/en/stable/faq.html#does-black-have-an-api
|
36 |
+
formatted = black.format_str(sorted_imports, mode=black.Mode(line_length=line_length))
|
37 |
+
return formatted
|
38 |
+
|
39 |
|
40 |
+
def make_code_clipboard_from_py_file(filepath: str, mode="vizro"):
|
41 |
# Black doesn't yet have a Python API, so format_str might not work at some point in the future.
|
42 |
# https://black.readthedocs.io/en/stable/faq.html#does-black-have-an-api
|
43 |
+
example_code = (Path(__file__).parents[1] / "pages/examples" / filepath).read_text()
|
44 |
+
|
45 |
+
if mode == "vizro":
|
46 |
+
example_code = VIZRO_CODE_TEMPLATE.format(example_code=example_code)
|
47 |
+
else:
|
48 |
+
replacements = {"import vizro.plotly.express as px": "import plotly.express as px", '@capture("graph")': ""}
|
49 |
+
for old_code, new_code in replacements.items():
|
50 |
+
example_code = example_code.replace(old_code, new_code)
|
51 |
+
|
52 |
return CodeClipboard(
|
53 |
+
code=_format_and_lint(example_code, line_length=80),
|
54 |
+
mode=mode,
|
55 |
language="python",
|
56 |
)
|
57 |
|
58 |
|
59 |
PAGE_GRID = [[0, 0, 0, 0, 0, 0, 0]] * 2 + [[1, 1, 1, 1, 2, 2, 2]] * 5
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pages/correlation.py
CHANGED
@@ -1,12 +1,12 @@
|
|
1 |
"""Correlation charts."""
|
2 |
|
3 |
import vizro.models as vm
|
4 |
-
import vizro.plotly.express as px
|
5 |
|
6 |
from pages._factories import column_and_line_factory, connected_scatter_factory
|
7 |
-
from pages._pages_utils import PAGE_GRID,
|
|
|
8 |
|
9 |
-
|
10 |
title="Scatter",
|
11 |
path="correlation/scatter",
|
12 |
layout=vm.Layout(grid=PAGE_GRID),
|
@@ -29,14 +29,24 @@ scatter = vm.Page(
|
|
29 |
that correlation is not causation. Make sure your audience does not draw the wrong conclusions.
|
30 |
"""
|
31 |
),
|
32 |
-
vm.Graph(figure=
|
33 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
34 |
],
|
35 |
)
|
36 |
|
37 |
-
|
38 |
|
39 |
-
|
40 |
title="Scatter matrix",
|
41 |
path="correlation/scatter-matrix",
|
42 |
layout=vm.Layout(grid=PAGE_GRID),
|
@@ -60,14 +70,23 @@ scatter_matrix = vm.Page(
|
|
60 |
ensure clarity and readability of the chart.
|
61 |
"""
|
62 |
),
|
63 |
-
vm.Graph(
|
64 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
65 |
),
|
66 |
-
make_code_clipboard_from_py_file("scatter_matrix.py"),
|
67 |
],
|
68 |
)
|
69 |
|
70 |
-
|
71 |
title="Bubble",
|
72 |
path="correlation/bubble",
|
73 |
layout=vm.Layout(grid=PAGE_GRID),
|
@@ -91,10 +110,21 @@ bubble = vm.Page(
|
|
91 |
providing deeper insights than a standard scatter plot.
|
92 |
"""
|
93 |
),
|
94 |
-
vm.Graph(figure=
|
95 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
96 |
],
|
97 |
)
|
98 |
|
99 |
-
|
100 |
-
|
|
|
|
1 |
"""Correlation charts."""
|
2 |
|
3 |
import vizro.models as vm
|
|
|
4 |
|
5 |
from pages._factories import column_and_line_factory, connected_scatter_factory
|
6 |
+
from pages._pages_utils import PAGE_GRID, make_code_clipboard_from_py_file
|
7 |
+
from pages.examples import bubble, scatter, scatter_matrix
|
8 |
|
9 |
+
scatter_page = vm.Page(
|
10 |
title="Scatter",
|
11 |
path="correlation/scatter",
|
12 |
layout=vm.Layout(grid=PAGE_GRID),
|
|
|
29 |
that correlation is not causation. Make sure your audience does not draw the wrong conclusions.
|
30 |
"""
|
31 |
),
|
32 |
+
vm.Graph(figure=scatter.fig),
|
33 |
+
vm.Tabs(
|
34 |
+
tabs=[
|
35 |
+
vm.Container(
|
36 |
+
title="Vizro dashboard", components=[make_code_clipboard_from_py_file("scatter.py", mode="vizro")]
|
37 |
+
),
|
38 |
+
vm.Container(
|
39 |
+
title="Plotly figure",
|
40 |
+
components=[make_code_clipboard_from_py_file("scatter.py", mode="plotly")],
|
41 |
+
),
|
42 |
+
]
|
43 |
+
),
|
44 |
],
|
45 |
)
|
46 |
|
47 |
+
connected_scatter_page = connected_scatter_factory("correlation")
|
48 |
|
49 |
+
scatter_matrix_page = vm.Page(
|
50 |
title="Scatter matrix",
|
51 |
path="correlation/scatter-matrix",
|
52 |
layout=vm.Layout(grid=PAGE_GRID),
|
|
|
70 |
ensure clarity and readability of the chart.
|
71 |
"""
|
72 |
),
|
73 |
+
vm.Graph(figure=scatter_matrix.fig),
|
74 |
+
vm.Tabs(
|
75 |
+
tabs=[
|
76 |
+
vm.Container(
|
77 |
+
title="Vizro dashboard",
|
78 |
+
components=[make_code_clipboard_from_py_file("scatter_matrix.py", mode="vizro")],
|
79 |
+
),
|
80 |
+
vm.Container(
|
81 |
+
title="Plotly figure",
|
82 |
+
components=[make_code_clipboard_from_py_file("scatter_matrix.py", mode="plotly")],
|
83 |
+
),
|
84 |
+
]
|
85 |
),
|
|
|
86 |
],
|
87 |
)
|
88 |
|
89 |
+
bubble_page = vm.Page(
|
90 |
title="Bubble",
|
91 |
path="correlation/bubble",
|
92 |
layout=vm.Layout(grid=PAGE_GRID),
|
|
|
110 |
providing deeper insights than a standard scatter plot.
|
111 |
"""
|
112 |
),
|
113 |
+
vm.Graph(figure=bubble.fig),
|
114 |
+
vm.Tabs(
|
115 |
+
tabs=[
|
116 |
+
vm.Container(
|
117 |
+
title="Vizro dashboard", components=[make_code_clipboard_from_py_file("bubble.py", mode="vizro")]
|
118 |
+
),
|
119 |
+
vm.Container(
|
120 |
+
title="Plotly figure",
|
121 |
+
components=[make_code_clipboard_from_py_file("bubble.py", mode="plotly")],
|
122 |
+
),
|
123 |
+
]
|
124 |
+
),
|
125 |
],
|
126 |
)
|
127 |
|
128 |
+
column_and_line_page = column_and_line_factory("correlation")
|
129 |
+
|
130 |
+
pages = [scatter_page, connected_scatter_page, scatter_matrix_page, bubble_page, column_and_line_page]
|
pages/deviation.py
CHANGED
@@ -1,16 +1,15 @@
|
|
1 |
"""Deviation charts."""
|
2 |
|
3 |
-
import plotly.io as pio
|
4 |
import vizro.models as vm
|
5 |
-
import vizro.plotly.express as px
|
6 |
|
7 |
from pages._factories import butterfly_factory
|
8 |
-
from pages._pages_utils import PAGE_GRID, make_code_clipboard_from_py_file
|
|
|
9 |
|
10 |
-
|
11 |
|
12 |
|
13 |
-
|
14 |
title="Diverging bar",
|
15 |
path="deviation/diverging-bar",
|
16 |
layout=vm.Layout(grid=PAGE_GRID),
|
@@ -36,19 +35,63 @@ diverging_bar = vm.Page(
|
|
36 |
of values. Ensure a consistent scale on both sides of the baseline to avoid misleading interpretations.
|
37 |
"""
|
38 |
),
|
39 |
-
vm.Graph(
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
-
|
|
|
|
|
49 |
),
|
50 |
-
make_code_clipboard_from_py_file("diverging_bar.py"),
|
51 |
],
|
52 |
)
|
53 |
|
54 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
"""Deviation charts."""
|
2 |
|
|
|
3 |
import vizro.models as vm
|
|
|
4 |
|
5 |
from pages._factories import butterfly_factory
|
6 |
+
from pages._pages_utils import PAGE_GRID, make_code_clipboard_from_py_file
|
7 |
+
from pages.examples import diverging_bar, diverging_stacked_bar
|
8 |
|
9 |
+
butterfly_page = butterfly_factory("deviation")
|
10 |
|
11 |
|
12 |
+
diverging_bar_page = vm.Page(
|
13 |
title="Diverging bar",
|
14 |
path="deviation/diverging-bar",
|
15 |
layout=vm.Layout(grid=PAGE_GRID),
|
|
|
35 |
of values. Ensure a consistent scale on both sides of the baseline to avoid misleading interpretations.
|
36 |
"""
|
37 |
),
|
38 |
+
vm.Graph(figure=diverging_bar.fig),
|
39 |
+
vm.Tabs(
|
40 |
+
tabs=[
|
41 |
+
vm.Container(
|
42 |
+
title="Vizro dashboard",
|
43 |
+
components=[make_code_clipboard_from_py_file("diverging_bar.py", mode="vizro")],
|
44 |
+
),
|
45 |
+
vm.Container(
|
46 |
+
title="Plotly figure",
|
47 |
+
components=[make_code_clipboard_from_py_file("diverging_bar.py", mode="plotly")],
|
48 |
+
),
|
49 |
+
]
|
50 |
),
|
|
|
51 |
],
|
52 |
)
|
53 |
|
54 |
+
diverging_stacked_bar_page = vm.Page(
|
55 |
+
title="Diverging stacked bar",
|
56 |
+
path="deviation/diverging-stacked-bar",
|
57 |
+
layout=vm.Layout(grid=PAGE_GRID),
|
58 |
+
components=[
|
59 |
+
vm.Card(
|
60 |
+
text="""
|
61 |
+
|
62 |
+
#### What is a diverging stacked bar?
|
63 |
+
|
64 |
+
A diverging stacked bar chart is like a stacked bar chart but aligns bars on a central baseline instead of
|
65 |
+
the left or right. It displays positive and negative values, with each bar divided into segments for
|
66 |
+
different categories. This type of chart is commonly used for percentage shares, especially in survey
|
67 |
+
results using Likert scales (e.g., Strongly Disagree, Disagree, Agree, Strongly Agree).
|
68 |
+
|
69 |
+
|
70 |
+
|
71 |
+
#### When should I use it?
|
72 |
+
|
73 |
+
A diverging stacked bar chart is useful for comparing positive and negative values and showing the
|
74 |
+
composition of each bar. However, use this chart with caution: since none of the segments share a
|
75 |
+
common baseline, direct comparisons can be more challenging. For clearer comparisons, consider using a
|
76 |
+
100% stacked bar chart with a baseline starting from the left or right. For more insights on the potential
|
77 |
+
pitfalls, we recommend reading the article from
|
78 |
+
[Datawrapper on diverging stacked bar charts](https://blog.datawrapper.de/divergingbars/).
|
79 |
+
"""
|
80 |
+
),
|
81 |
+
vm.Graph(figure=diverging_stacked_bar.fig),
|
82 |
+
vm.Tabs(
|
83 |
+
tabs=[
|
84 |
+
vm.Container(
|
85 |
+
title="Vizro dashboard",
|
86 |
+
components=[make_code_clipboard_from_py_file("diverging_stacked_bar.py", mode="vizro")],
|
87 |
+
),
|
88 |
+
vm.Container(
|
89 |
+
title="Plotly figure",
|
90 |
+
components=[make_code_clipboard_from_py_file("diverging_stacked_bar.py", mode="plotly")],
|
91 |
+
),
|
92 |
+
]
|
93 |
+
),
|
94 |
+
],
|
95 |
+
)
|
96 |
+
|
97 |
+
pages = [butterfly_page, diverging_bar_page, diverging_stacked_bar_page]
|
pages/distribution.py
CHANGED
@@ -1,13 +1,12 @@
|
|
1 |
"""Distribution charts."""
|
2 |
|
3 |
import vizro.models as vm
|
4 |
-
import vizro.plotly.express as px
|
5 |
-
from custom_charts import dumbbell
|
6 |
|
7 |
from pages._factories import butterfly_factory
|
8 |
-
from pages._pages_utils import PAGE_GRID, make_code_clipboard_from_py_file
|
|
|
9 |
|
10 |
-
|
11 |
title="Violin",
|
12 |
path="distribution/violin",
|
13 |
layout=vm.Layout(grid=PAGE_GRID),
|
@@ -28,20 +27,22 @@ violin = vm.Page(
|
|
28 |
inter-quartile range, the confidence intervals and the median.
|
29 |
"""
|
30 |
),
|
31 |
-
vm.Graph(
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
|
|
|
|
|
|
39 |
),
|
40 |
-
make_code_clipboard_from_py_file("violin.py"),
|
41 |
],
|
42 |
)
|
43 |
|
44 |
-
|
45 |
title="Boxplot",
|
46 |
path="distribution/boxplot",
|
47 |
layout=vm.Layout(grid=PAGE_GRID),
|
@@ -66,21 +67,24 @@ boxplot = vm.Page(
|
|
66 |
the whiskers.
|
67 |
"""
|
68 |
),
|
69 |
-
vm.Graph(
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
|
|
|
|
|
|
|
|
76 |
),
|
77 |
-
make_code_clipboard_from_py_file("boxplot.py"),
|
78 |
],
|
79 |
)
|
80 |
|
81 |
-
|
82 |
|
83 |
-
|
84 |
title="Histogram",
|
85 |
path="distribution/histogram",
|
86 |
layout=vm.Layout(grid=PAGE_GRID),
|
@@ -102,12 +106,22 @@ histogram = vm.Page(
|
|
102 |
immediately clear.
|
103 |
"""
|
104 |
),
|
105 |
-
vm.Graph(figure=
|
106 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
107 |
],
|
108 |
)
|
109 |
|
110 |
-
|
111 |
title="Dumbbell",
|
112 |
path="distribution/dumbbell",
|
113 |
layout=vm.Layout(grid=PAGE_GRID),
|
@@ -129,10 +143,20 @@ dumbbell = vm.Page(
|
|
129 |
of changes or to distinguish between categories.
|
130 |
"""
|
131 |
),
|
132 |
-
vm.Graph(figure=dumbbell
|
133 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
134 |
],
|
135 |
)
|
136 |
|
137 |
|
138 |
-
pages = [
|
|
|
1 |
"""Distribution charts."""
|
2 |
|
3 |
import vizro.models as vm
|
|
|
|
|
4 |
|
5 |
from pages._factories import butterfly_factory
|
6 |
+
from pages._pages_utils import PAGE_GRID, make_code_clipboard_from_py_file
|
7 |
+
from pages.examples import boxplot, dumbbell, histogram, violin
|
8 |
|
9 |
+
violin_page = vm.Page(
|
10 |
title="Violin",
|
11 |
path="distribution/violin",
|
12 |
layout=vm.Layout(grid=PAGE_GRID),
|
|
|
27 |
inter-quartile range, the confidence intervals and the median.
|
28 |
"""
|
29 |
),
|
30 |
+
vm.Graph(figure=violin.fig),
|
31 |
+
vm.Tabs(
|
32 |
+
tabs=[
|
33 |
+
vm.Container(
|
34 |
+
title="Vizro dashboard", components=[make_code_clipboard_from_py_file("violin.py", mode="vizro")]
|
35 |
+
),
|
36 |
+
vm.Container(
|
37 |
+
title="Plotly figure",
|
38 |
+
components=[make_code_clipboard_from_py_file("violin.py", mode="plotly")],
|
39 |
+
),
|
40 |
+
]
|
41 |
),
|
|
|
42 |
],
|
43 |
)
|
44 |
|
45 |
+
boxplot_page = vm.Page(
|
46 |
title="Boxplot",
|
47 |
path="distribution/boxplot",
|
48 |
layout=vm.Layout(grid=PAGE_GRID),
|
|
|
67 |
the whiskers.
|
68 |
"""
|
69 |
),
|
70 |
+
vm.Graph(figure=boxplot.fig),
|
71 |
+
vm.Tabs(
|
72 |
+
tabs=[
|
73 |
+
vm.Container(
|
74 |
+
title="Vizro dashboard", components=[make_code_clipboard_from_py_file("boxplot.py", mode="vizro")]
|
75 |
+
),
|
76 |
+
vm.Container(
|
77 |
+
title="Plotly figure",
|
78 |
+
components=[make_code_clipboard_from_py_file("boxplot.py", mode="plotly")],
|
79 |
+
),
|
80 |
+
]
|
81 |
),
|
|
|
82 |
],
|
83 |
)
|
84 |
|
85 |
+
butterfly_page = butterfly_factory("distribution")
|
86 |
|
87 |
+
histogram_page = vm.Page(
|
88 |
title="Histogram",
|
89 |
path="distribution/histogram",
|
90 |
layout=vm.Layout(grid=PAGE_GRID),
|
|
|
106 |
immediately clear.
|
107 |
"""
|
108 |
),
|
109 |
+
vm.Graph(figure=histogram.fig),
|
110 |
+
vm.Tabs(
|
111 |
+
tabs=[
|
112 |
+
vm.Container(
|
113 |
+
title="Vizro dashboard", components=[make_code_clipboard_from_py_file("histogram.py", mode="vizro")]
|
114 |
+
),
|
115 |
+
vm.Container(
|
116 |
+
title="Plotly figure",
|
117 |
+
components=[make_code_clipboard_from_py_file("histogram.py", mode="plotly")],
|
118 |
+
),
|
119 |
+
]
|
120 |
+
),
|
121 |
],
|
122 |
)
|
123 |
|
124 |
+
dumbbell_page = vm.Page(
|
125 |
title="Dumbbell",
|
126 |
path="distribution/dumbbell",
|
127 |
layout=vm.Layout(grid=PAGE_GRID),
|
|
|
143 |
of changes or to distinguish between categories.
|
144 |
"""
|
145 |
),
|
146 |
+
vm.Graph(figure=dumbbell.fig),
|
147 |
+
vm.Tabs(
|
148 |
+
tabs=[
|
149 |
+
vm.Container(
|
150 |
+
title="Vizro dashboard", components=[make_code_clipboard_from_py_file("dumbbell.py", mode="vizro")]
|
151 |
+
),
|
152 |
+
vm.Container(
|
153 |
+
title="Plotly figure",
|
154 |
+
components=[make_code_clipboard_from_py_file("dumbbell.py", mode="plotly")],
|
155 |
+
),
|
156 |
+
]
|
157 |
+
),
|
158 |
],
|
159 |
)
|
160 |
|
161 |
|
162 |
+
pages = [violin_page, boxplot_page, butterfly_page, dumbbell_page, histogram_page]
|
pages/examples/area.py
CHANGED
@@ -1,13 +1,5 @@
|
|
1 |
-
import vizro.models as vm
|
2 |
import vizro.plotly.express as px
|
3 |
-
from vizro import Vizro
|
4 |
|
5 |
stocks = px.data.stocks()
|
6 |
|
7 |
-
|
8 |
-
title="Area",
|
9 |
-
components=[vm.Graph(figure=px.area(stocks, x="date", y="GOOG"))],
|
10 |
-
)
|
11 |
-
|
12 |
-
dashboard = vm.Dashboard(pages=[page])
|
13 |
-
Vizro().build(dashboard).run()
|
|
|
|
|
1 |
import vizro.plotly.express as px
|
|
|
2 |
|
3 |
stocks = px.data.stocks()
|
4 |
|
5 |
+
fig = px.area(stocks, x="date", y="GOOG")
|
|
|
|
|
|
|
|
|
|
|
|
pages/examples/bar.py
CHANGED
@@ -1,24 +1,7 @@
|
|
1 |
-
import vizro.models as vm
|
2 |
import vizro.plotly.express as px
|
3 |
-
from vizro import Vizro
|
4 |
|
5 |
-
gapminder = px.data.gapminder()
|
6 |
-
|
7 |
-
page = vm.Page(
|
8 |
-
title="Bar",
|
9 |
-
components=[
|
10 |
-
vm.Graph(
|
11 |
-
figure=px.bar(
|
12 |
-
gapminder.query(
|
13 |
-
"year == 2007 and country.isin(['United States', 'Pakistan', 'India', 'China', 'Indonesia'])"
|
14 |
-
),
|
15 |
-
x="pop",
|
16 |
-
y="country",
|
17 |
-
orientation="h",
|
18 |
-
)
|
19 |
-
)
|
20 |
-
],
|
21 |
)
|
22 |
|
23 |
-
|
24 |
-
Vizro().build(dashboard).run()
|
|
|
|
|
1 |
import vizro.plotly.express as px
|
|
|
2 |
|
3 |
+
gapminder = px.data.gapminder().query(
|
4 |
+
"year == 2007 and country.isin(['United States', 'Pakistan', 'India', 'China', 'Indonesia'])"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
)
|
6 |
|
7 |
+
fig = px.bar(gapminder, x="pop", y="country", orientation="h")
|
|
pages/examples/boxplot.py
CHANGED
@@ -1,15 +1,5 @@
|
|
1 |
-
import vizro.models as vm
|
2 |
import vizro.plotly.express as px
|
3 |
-
from vizro import Vizro
|
4 |
|
5 |
tips = px.data.tips()
|
6 |
|
7 |
-
|
8 |
-
title="Boxplot",
|
9 |
-
components=[
|
10 |
-
vm.Graph(figure=px.boxplot(tips, y="total_bill", x="day", color="day")),
|
11 |
-
],
|
12 |
-
)
|
13 |
-
|
14 |
-
dashboard = vm.Dashboard(pages=[page])
|
15 |
-
Vizro().build(dashboard).run()
|
|
|
|
|
1 |
import vizro.plotly.express as px
|
|
|
2 |
|
3 |
tips = px.data.tips()
|
4 |
|
5 |
+
fig = px.box(tips, y="total_bill", x="day", color="day")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pages/examples/bubble.py
CHANGED
@@ -1,15 +1,5 @@
|
|
1 |
-
import vizro.models as vm
|
2 |
import vizro.plotly.express as px
|
3 |
-
from vizro import Vizro
|
4 |
|
5 |
-
gapminder = px.data.gapminder()
|
6 |
|
7 |
-
|
8 |
-
title="Bubble",
|
9 |
-
components=[
|
10 |
-
vm.Graph(figure=px.scatter(gapminder.query("year==2007"), x="gdpPercap", y="lifeExp", size="pop", size_max=60))
|
11 |
-
],
|
12 |
-
)
|
13 |
-
|
14 |
-
dashboard = vm.Dashboard(pages=[page])
|
15 |
-
Vizro().build(dashboard).run()
|
|
|
|
|
1 |
import vizro.plotly.express as px
|
|
|
2 |
|
3 |
+
gapminder = px.data.gapminder().query("year==2007")
|
4 |
|
5 |
+
fig = px.scatter(gapminder, x="gdpPercap", y="lifeExp", size="pop", size_max=60)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pages/examples/bubble_map.py
CHANGED
@@ -1,25 +1,7 @@
|
|
1 |
-
import vizro.models as vm
|
2 |
import vizro.plotly.express as px
|
3 |
-
from vizro import Vizro
|
4 |
|
5 |
carshare = px.data.carshare()
|
6 |
|
7 |
-
|
8 |
-
|
9 |
-
components=[
|
10 |
-
vm.Graph(
|
11 |
-
figure=px.scatter_map(
|
12 |
-
carshare,
|
13 |
-
lat="centroid_lat",
|
14 |
-
lon="centroid_lon",
|
15 |
-
size="car_hours",
|
16 |
-
size_max=15,
|
17 |
-
opacity=0.5,
|
18 |
-
zoom=10,
|
19 |
-
)
|
20 |
-
)
|
21 |
-
],
|
22 |
)
|
23 |
-
|
24 |
-
dashboard = vm.Dashboard(pages=[page])
|
25 |
-
Vizro().build(dashboard).run()
|
|
|
|
|
1 |
import vizro.plotly.express as px
|
|
|
2 |
|
3 |
carshare = px.data.carshare()
|
4 |
|
5 |
+
fig = px.scatter_map(
|
6 |
+
carshare, lat="centroid_lat", lon="centroid_lon", size="car_hours", size_max=15, opacity=0.5, zoom=10
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
)
|
|
|
|
|
|
pages/examples/butterfly.py
CHANGED
@@ -1,9 +1,30 @@
|
|
1 |
import pandas as pd
|
|
|
2 |
import plotly.graph_objects as go
|
3 |
-
import vizro.models as vm
|
4 |
-
from vizro import Vizro
|
5 |
from vizro.models.types import capture
|
6 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
ages = pd.DataFrame(
|
8 |
{
|
9 |
"Age": ["0-19", "20-29", "30-39", "40-49", "50-59", ">=60"],
|
@@ -12,36 +33,4 @@ ages = pd.DataFrame(
|
|
12 |
}
|
13 |
)
|
14 |
|
15 |
-
|
16 |
-
@capture("graph")
|
17 |
-
def butterfly(data_frame: pd.DataFrame, x1: str, x2: str, y: str):
|
18 |
-
fig = go.Figure()
|
19 |
-
fig.add_trace(
|
20 |
-
go.Bar(
|
21 |
-
x=-data_frame[x1],
|
22 |
-
y=data_frame[y],
|
23 |
-
orientation="h",
|
24 |
-
name=x1,
|
25 |
-
)
|
26 |
-
)
|
27 |
-
fig.add_trace(
|
28 |
-
go.Bar(
|
29 |
-
x=data_frame[x2],
|
30 |
-
y=data_frame[y],
|
31 |
-
orientation="h",
|
32 |
-
name=x2,
|
33 |
-
)
|
34 |
-
)
|
35 |
-
fig.update_layout(barmode="relative")
|
36 |
-
return fig
|
37 |
-
|
38 |
-
|
39 |
-
dashboard = vm.Dashboard(
|
40 |
-
pages=[
|
41 |
-
vm.Page(
|
42 |
-
title="Butterfly",
|
43 |
-
components=[vm.Graph(figure=butterfly(ages, x1="Male", x2="Female", y="Age"))],
|
44 |
-
)
|
45 |
-
]
|
46 |
-
)
|
47 |
-
Vizro().build(dashboard).run()
|
|
|
1 |
import pandas as pd
|
2 |
+
import plotly.express as px
|
3 |
import plotly.graph_objects as go
|
|
|
|
|
4 |
from vizro.models.types import capture
|
5 |
|
6 |
+
|
7 |
+
@capture("graph")
|
8 |
+
def butterfly(data_frame: pd.DataFrame, **kwargs) -> go.Figure:
|
9 |
+
fig = px.bar(data_frame, **kwargs)
|
10 |
+
|
11 |
+
orientation = fig.data[0].orientation
|
12 |
+
x_or_y = "x" if orientation == "h" else "y"
|
13 |
+
|
14 |
+
fig.update_traces({f"{x_or_y}axis": f"{x_or_y}2"}, selector=1)
|
15 |
+
fig.update_layout({f"{x_or_y}axis2": fig.layout[f"{x_or_y}axis"]})
|
16 |
+
fig.update_layout(
|
17 |
+
{f"{x_or_y}axis": {"autorange": "reversed", "domain": [0, 0.5]}, f"{x_or_y}axis2": {"domain": [0.5, 1]}}
|
18 |
+
)
|
19 |
+
|
20 |
+
if orientation == "h":
|
21 |
+
fig.add_vline(x=0, line_width=2, line_color="grey")
|
22 |
+
else:
|
23 |
+
fig.add_hline(y=0, line_width=2, line_color="grey")
|
24 |
+
|
25 |
+
return fig
|
26 |
+
|
27 |
+
|
28 |
ages = pd.DataFrame(
|
29 |
{
|
30 |
"Age": ["0-19", "20-29", "30-39", "40-49", "50-59", ">=60"],
|
|
|
33 |
}
|
34 |
)
|
35 |
|
36 |
+
fig = butterfly(ages, x=["Male", "Female"], y="Age", labels={"value": "Population", "variable": "Sex"})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pages/examples/choropleth.py
CHANGED
@@ -1,19 +1,5 @@
|
|
1 |
-
import vizro.models as vm
|
2 |
import vizro.plotly.express as px
|
3 |
-
from vizro import Vizro
|
4 |
|
5 |
-
gapminder = px.data.gapminder()
|
6 |
|
7 |
-
|
8 |
-
title="Choropleth",
|
9 |
-
components=[
|
10 |
-
vm.Graph(
|
11 |
-
figure=px.choropleth(
|
12 |
-
gapminder.query("year == 2007"), locations="iso_alpha", color="lifeExp", hover_name="country"
|
13 |
-
)
|
14 |
-
)
|
15 |
-
],
|
16 |
-
)
|
17 |
-
|
18 |
-
dashboard = vm.Dashboard(pages=[page])
|
19 |
-
Vizro().build(dashboard).run()
|
|
|
|
|
1 |
import vizro.plotly.express as px
|
|
|
2 |
|
3 |
+
gapminder = px.data.gapminder().query("year == 2007")
|
4 |
|
5 |
+
fig = px.choropleth(gapminder, locations="iso_alpha", color="lifeExp", hover_name="country")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pages/examples/column_and_line.py
CHANGED
@@ -1,53 +1,38 @@
|
|
|
|
|
|
1 |
import pandas as pd
|
2 |
import plotly.graph_objects as go
|
3 |
-
import vizro.models as vm
|
4 |
import vizro.plotly.express as px
|
5 |
from plotly.subplots import make_subplots
|
6 |
-
from vizro import Vizro
|
7 |
from vizro.models.types import capture
|
8 |
|
9 |
-
gapminder = px.data.gapminder()
|
10 |
-
|
11 |
|
12 |
@capture("graph")
|
13 |
-
def column_and_line(
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
20 |
)
|
21 |
|
22 |
-
|
23 |
-
|
24 |
-
secondary_y=True,
|
25 |
-
)
|
26 |
|
27 |
-
fig.update_layout(
|
28 |
-
xaxis={"type": "category", "title": x},
|
29 |
-
yaxis={"tickmode": "sync", "title": y_column},
|
30 |
-
yaxis2={"tickmode": "sync", "overlaying": "y", "title": y_line},
|
31 |
-
)
|
32 |
|
33 |
return fig
|
34 |
|
35 |
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
title="Column and line",
|
40 |
-
components=[
|
41 |
-
vm.Graph(
|
42 |
-
figure=column_and_line(
|
43 |
-
gapminder.query("country == 'Vietnam'"),
|
44 |
-
y_column="gdpPercap",
|
45 |
-
y_line="lifeExp",
|
46 |
-
x="year",
|
47 |
-
)
|
48 |
-
)
|
49 |
-
],
|
50 |
-
)
|
51 |
-
]
|
52 |
-
)
|
53 |
-
Vizro().build(dashboard).run()
|
|
|
1 |
+
from typing import Union
|
2 |
+
|
3 |
import pandas as pd
|
4 |
import plotly.graph_objects as go
|
|
|
5 |
import vizro.plotly.express as px
|
6 |
from plotly.subplots import make_subplots
|
|
|
7 |
from vizro.models.types import capture
|
8 |
|
|
|
|
|
9 |
|
10 |
@capture("graph")
|
11 |
+
def column_and_line(
|
12 |
+
data_frame: pd.DataFrame,
|
13 |
+
x: Union[str, pd.Series, list[str], list[pd.Series]],
|
14 |
+
y_column: Union[str, pd.Series, list[str], list[pd.Series]],
|
15 |
+
y_line: Union[str, pd.Series, list[str], list[pd.Series]],
|
16 |
+
) -> go.Figure:
|
17 |
+
bar = px.bar(data_frame, x=x, y=y_column)
|
18 |
+
fig = make_subplots(figure=bar, specs=[[{"secondary_y": True}]])
|
19 |
+
|
20 |
+
line = px.line(
|
21 |
+
data_frame,
|
22 |
+
x=x,
|
23 |
+
y=y_line,
|
24 |
+
markers=True,
|
25 |
+
color_discrete_sequence=fig.layout.template.layout.colorway[len(bar.data) :],
|
26 |
)
|
27 |
|
28 |
+
for trace in line.data:
|
29 |
+
fig.add_trace(trace, secondary_y=True)
|
|
|
|
|
30 |
|
31 |
+
fig.update_layout(yaxis2={"tickmode": "sync", "overlaying": "y", "title": line.layout.yaxis.title})
|
|
|
|
|
|
|
|
|
32 |
|
33 |
return fig
|
34 |
|
35 |
|
36 |
+
gapminder = px.data.gapminder().query("country == 'Vietnam'")
|
37 |
+
|
38 |
+
fig = column_and_line(gapminder, y_column="gdpPercap", y_line="lifeExp", x="year")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pages/examples/connected_scatter.py
CHANGED
@@ -1,15 +1,5 @@
|
|
1 |
-
import vizro.models as vm
|
2 |
import vizro.plotly.express as px
|
3 |
-
from vizro import Vizro
|
4 |
|
5 |
-
gapminder = px.data.gapminder()
|
6 |
|
7 |
-
|
8 |
-
title="Connected scatter",
|
9 |
-
components=[
|
10 |
-
vm.Graph(figure=px.line(gapminder.query("country == 'Australia'"), x="year", y="lifeExp", markers=True))
|
11 |
-
],
|
12 |
-
)
|
13 |
-
|
14 |
-
dashboard = vm.Dashboard(pages=[page])
|
15 |
-
Vizro().build(dashboard).run()
|
|
|
|
|
1 |
import vizro.plotly.express as px
|
|
|
2 |
|
3 |
+
gapminder = px.data.gapminder().query("country == 'Australia'")
|
4 |
|
5 |
+
fig = px.line(gapminder, x="year", y="lifeExp", markers=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pages/examples/diverging_bar.py
CHANGED
@@ -1,8 +1,5 @@
|
|
1 |
import pandas as pd
|
2 |
-
import plotly.io as pio
|
3 |
-
import vizro.models as vm
|
4 |
import vizro.plotly.express as px
|
5 |
-
from vizro import Vizro
|
6 |
|
7 |
pastries = pd.DataFrame(
|
8 |
{
|
@@ -15,31 +12,9 @@ pastries = pd.DataFrame(
|
|
15 |
"Cookies",
|
16 |
"Croissants",
|
17 |
"Eclairs",
|
18 |
-
"Brownies",
|
19 |
-
"Tarts",
|
20 |
-
"Macarons",
|
21 |
-
"Pies",
|
22 |
],
|
23 |
-
"Profit Ratio": [-0.10, -0.
|
24 |
}
|
25 |
-
)
|
26 |
|
27 |
-
|
28 |
-
title="Diverging bar",
|
29 |
-
components=[
|
30 |
-
vm.Graph(
|
31 |
-
figure=px.bar(
|
32 |
-
pastries.sort_values("Profit Ratio"),
|
33 |
-
orientation="h",
|
34 |
-
x="Profit Ratio",
|
35 |
-
y="pastry",
|
36 |
-
color="Profit Ratio",
|
37 |
-
color_continuous_scale=pio.templates["vizro_dark"].layout.colorscale.diverging,
|
38 |
-
color_continuous_midpoint=0,
|
39 |
-
),
|
40 |
-
),
|
41 |
-
],
|
42 |
-
)
|
43 |
-
|
44 |
-
dashboard = vm.Dashboard(pages=[page])
|
45 |
-
Vizro().build(dashboard).run()
|
|
|
1 |
import pandas as pd
|
|
|
|
|
2 |
import vizro.plotly.express as px
|
|
|
3 |
|
4 |
pastries = pd.DataFrame(
|
5 |
{
|
|
|
12 |
"Cookies",
|
13 |
"Croissants",
|
14 |
"Eclairs",
|
|
|
|
|
|
|
|
|
15 |
],
|
16 |
+
"Profit Ratio": [-0.10, -0.05, 0.10, 0.05, 0.15, -0.08, 0.08, -0.12],
|
17 |
}
|
18 |
+
).sort_values("Profit Ratio")
|
19 |
|
20 |
+
fig = px.bar(pastries, x="Profit Ratio", y="pastry")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pages/examples/diverging_stacked_bar.py
ADDED
@@ -0,0 +1,68 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import pandas as pd
|
2 |
+
import plotly.express as px
|
3 |
+
import plotly.graph_objects as go
|
4 |
+
from vizro.models.types import capture
|
5 |
+
|
6 |
+
|
7 |
+
@capture("graph")
|
8 |
+
def diverging_stacked_bar(data_frame: pd.DataFrame, **kwargs) -> go.Figure:
|
9 |
+
fig = px.bar(data_frame, **kwargs)
|
10 |
+
|
11 |
+
for i, trace in enumerate(fig.data):
|
12 |
+
trace.update(legendrank=i)
|
13 |
+
|
14 |
+
if "color_discrete_sequence" not in kwargs and "color_discrete_map" not in kwargs:
|
15 |
+
colorscale = [list(x) for x in fig.layout.template.layout.colorscale.diverging]
|
16 |
+
colors = px.colors.sample_colorscale(colorscale, len(fig.data), 0.2, 0.8)
|
17 |
+
for trace, color in zip(fig.data, colors):
|
18 |
+
trace.update(marker_color=color)
|
19 |
+
|
20 |
+
mutable_traces = list(fig.data)
|
21 |
+
mutable_traces[: len(fig.data) // 2] = reversed(fig.data[: len(fig.data) // 2])
|
22 |
+
fig.data = mutable_traces
|
23 |
+
|
24 |
+
orientation = fig.data[0].orientation
|
25 |
+
x_or_y = "x" if orientation == "h" else "y"
|
26 |
+
|
27 |
+
for trace_idx in range(len(fig.data) // 2):
|
28 |
+
fig.update_traces({f"{x_or_y}axis": f"{x_or_y}2"}, selector=trace_idx)
|
29 |
+
|
30 |
+
fig.update_layout({f"{x_or_y}axis2": fig.layout[f"{x_or_y}axis"]})
|
31 |
+
fig.update_layout(
|
32 |
+
{f"{x_or_y}axis": {"autorange": "reversed", "domain": [0, 0.5]}, f"{x_or_y}axis2": {"domain": [0.5, 1]}}
|
33 |
+
)
|
34 |
+
|
35 |
+
if orientation == "h":
|
36 |
+
fig.add_vline(x=0, line_width=2, line_color="grey")
|
37 |
+
else:
|
38 |
+
fig.add_hline(y=0, line_width=2, line_color="grey")
|
39 |
+
|
40 |
+
return fig
|
41 |
+
|
42 |
+
|
43 |
+
pastries = pd.DataFrame(
|
44 |
+
{
|
45 |
+
"pastry": [
|
46 |
+
"Scones",
|
47 |
+
"Bagels",
|
48 |
+
"Muffins",
|
49 |
+
"Cakes",
|
50 |
+
"Donuts",
|
51 |
+
"Cookies",
|
52 |
+
"Croissants",
|
53 |
+
"Eclairs",
|
54 |
+
],
|
55 |
+
"Strongly Disagree": [20, 30, 10, 5, 15, 5, 10, 25],
|
56 |
+
"Disagree": [30, 25, 20, 10, 20, 10, 15, 30],
|
57 |
+
"Agree": [30, 25, 40, 40, 45, 40, 40, 25],
|
58 |
+
"Strongly Agree": [20, 20, 30, 45, 20, 45, 35, 20],
|
59 |
+
}
|
60 |
+
)
|
61 |
+
|
62 |
+
fig = diverging_stacked_bar(
|
63 |
+
data_frame=pastries,
|
64 |
+
x=["Strongly Disagree", "Disagree", "Agree", "Strongly Agree"],
|
65 |
+
y="pastry",
|
66 |
+
labels={"value": "Response count", "variable": "Opinion"},
|
67 |
+
title="I would recommend this pastry to my friends",
|
68 |
+
)
|
pages/examples/donut.py
CHANGED
@@ -1,13 +1,5 @@
|
|
1 |
-
import vizro.models as vm
|
2 |
import vizro.plotly.express as px
|
3 |
-
from vizro import Vizro
|
4 |
|
5 |
tips = px.data.tips()
|
6 |
|
7 |
-
|
8 |
-
title="Donut",
|
9 |
-
components=[vm.Graph(figure=px.pie(tips, values="tip", names="day", hole=0.4))],
|
10 |
-
)
|
11 |
-
|
12 |
-
dashboard = vm.Dashboard(pages=[page])
|
13 |
-
Vizro().build(dashboard).run()
|
|
|
|
|
1 |
import vizro.plotly.express as px
|
|
|
2 |
|
3 |
tips = px.data.tips()
|
4 |
|
5 |
+
fig = px.pie(tips, values="tip", names="day", hole=0.4)
|
|
|
|
|
|
|
|
|
|
|
|
pages/examples/dot_map.py
CHANGED
@@ -1,23 +1,5 @@
|
|
1 |
-
import vizro.models as vm
|
2 |
import vizro.plotly.express as px
|
3 |
-
from vizro import Vizro
|
4 |
|
5 |
carshare = px.data.carshare()
|
6 |
|
7 |
-
|
8 |
-
title="Dot map",
|
9 |
-
components=[
|
10 |
-
vm.Graph(
|
11 |
-
figure=px.scatter_map(
|
12 |
-
carshare,
|
13 |
-
lat="centroid_lat",
|
14 |
-
lon="centroid_lon",
|
15 |
-
opacity=0.5,
|
16 |
-
zoom=10,
|
17 |
-
)
|
18 |
-
)
|
19 |
-
],
|
20 |
-
)
|
21 |
-
|
22 |
-
dashboard = vm.Dashboard(pages=[page])
|
23 |
-
Vizro().build(dashboard).run()
|
|
|
|
|
1 |
import vizro.plotly.express as px
|
|
|
2 |
|
3 |
carshare = px.data.carshare()
|
4 |
|
5 |
+
fig = px.scatter_map(carshare, lat="centroid_lat", lon="centroid_lon", opacity=0.5, zoom=10)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pages/examples/dumbbell.py
CHANGED
@@ -1,46 +1,41 @@
|
|
1 |
import pandas as pd
|
2 |
-
import
|
3 |
import vizro.plotly.express as px
|
4 |
-
from plotly import graph_objects as go
|
5 |
-
from vizro import Vizro
|
6 |
from vizro.models.types import capture
|
7 |
|
8 |
-
salaries = pd.DataFrame(
|
9 |
-
{
|
10 |
-
"Job": ["Developer", "Analyst", "Manager", "Specialist"] * 2,
|
11 |
-
"Salary": [60000, 55000, 70000, 50000, 130000, 110000, 96400, 80000],
|
12 |
-
"Range": ["Min"] * 4 + ["Max"] * 4,
|
13 |
-
}
|
14 |
-
)
|
15 |
-
|
16 |
|
17 |
@capture("graph")
|
18 |
-
def dumbbell(data_frame: pd.DataFrame,
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
fig.add_shape(
|
|
|
25 |
type="line",
|
26 |
layer="below",
|
27 |
-
y0=y_value,
|
28 |
-
y1=y_value,
|
29 |
-
x0=group[x].min(),
|
30 |
-
x1=group[x].max(),
|
31 |
line_color="grey",
|
32 |
line_width=3,
|
33 |
)
|
34 |
|
35 |
-
# Increase size of dots
|
36 |
fig.update_traces(marker_size=12)
|
37 |
return fig
|
38 |
|
39 |
|
40 |
-
|
41 |
-
|
42 |
-
|
|
|
|
|
|
|
43 |
)
|
44 |
|
45 |
-
|
46 |
-
Vizro().build(dashboard).run()
|
|
|
1 |
import pandas as pd
|
2 |
+
import plotly.graph_objects as go
|
3 |
import vizro.plotly.express as px
|
|
|
|
|
4 |
from vizro.models.types import capture
|
5 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6 |
|
7 |
@capture("graph")
|
8 |
+
def dumbbell(data_frame: pd.DataFrame, **kwargs) -> go.Figure:
|
9 |
+
fig = px.scatter(data_frame, **kwargs)
|
10 |
+
|
11 |
+
orientation = fig.data[0].orientation
|
12 |
+
x_or_y = "x" if orientation == "h" else "y"
|
13 |
+
y_or_x = "y" if orientation == "h" else "x"
|
14 |
+
|
15 |
+
for x_or_y_0, x_or_y_1, y_or_x_0, y_or_x_1 in zip(
|
16 |
+
fig.data[0][x_or_y],
|
17 |
+
fig.data[1][x_or_y],
|
18 |
+
fig.data[0][y_or_x],
|
19 |
+
fig.data[1][y_or_x],
|
20 |
+
):
|
21 |
fig.add_shape(
|
22 |
+
**{f"{x_or_y}0": x_or_y_0, f"{x_or_y}1": x_or_y_1, f"{y_or_x}0": y_or_x_0, f"{y_or_x}1": y_or_x_1},
|
23 |
type="line",
|
24 |
layer="below",
|
|
|
|
|
|
|
|
|
25 |
line_color="grey",
|
26 |
line_width=3,
|
27 |
)
|
28 |
|
|
|
29 |
fig.update_traces(marker_size=12)
|
30 |
return fig
|
31 |
|
32 |
|
33 |
+
salaries = pd.DataFrame(
|
34 |
+
{
|
35 |
+
"Job": ["Developer", "Analyst", "Manager", "Specialist"],
|
36 |
+
"Min": [60000, 55000, 70000, 50000],
|
37 |
+
"Max": [130000, 110000, 96400, 80000],
|
38 |
+
}
|
39 |
)
|
40 |
|
41 |
+
fig = dumbbell(salaries, y="Job", x=["Min", "Max"], labels={"variable": "", "value": "Salary in $"})
|
|
pages/examples/funnel.py
CHANGED
@@ -1,16 +1,8 @@
|
|
1 |
import pandas as pd
|
2 |
-
import vizro.models as vm
|
3 |
import vizro.plotly.express as px
|
4 |
-
from vizro import Vizro
|
5 |
|
6 |
funnel_data = pd.DataFrame(
|
7 |
{"Stage": ["Leads", "Sales calls", "Follow-up", "Conversion", "Sales"], "Value": [10, 7, 4, 2, 1]}
|
8 |
)
|
9 |
|
10 |
-
|
11 |
-
title="Funnel",
|
12 |
-
components=[vm.Graph(figure=px.funnel_area(funnel_data, names="Stage", values="Value"))],
|
13 |
-
)
|
14 |
-
|
15 |
-
dashboard = vm.Dashboard(pages=[page])
|
16 |
-
Vizro().build(dashboard).run()
|
|
|
1 |
import pandas as pd
|
|
|
2 |
import vizro.plotly.express as px
|
|
|
3 |
|
4 |
funnel_data = pd.DataFrame(
|
5 |
{"Stage": ["Leads", "Sales calls", "Follow-up", "Conversion", "Sales"], "Value": [10, 7, 4, 2, 1]}
|
6 |
)
|
7 |
|
8 |
+
fig = px.funnel_area(funnel_data, names="Stage", values="Value")
|
|
|
|
|
|
|
|
|
|
|
|
pages/examples/gantt.py
CHANGED
@@ -1,7 +1,5 @@
|
|
1 |
import pandas as pd
|
2 |
-
import vizro.models as vm
|
3 |
import vizro.plotly.express as px
|
4 |
-
from vizro import Vizro
|
5 |
|
6 |
tasks = pd.DataFrame(
|
7 |
[
|
@@ -9,15 +7,6 @@ tasks = pd.DataFrame(
|
|
9 |
{"Task": "Job B", "Start": "2009-03-05", "Finish": "2009-04-15"},
|
10 |
{"Task": "Job C", "Start": "2009-02-20", "Finish": "2009-05-30"},
|
11 |
]
|
12 |
-
)
|
13 |
|
14 |
-
|
15 |
-
page = vm.Page(
|
16 |
-
title="Gantt",
|
17 |
-
components=[
|
18 |
-
vm.Graph(px.timeline(tasks.sort_values("Start", ascending=False), x_start="Start", x_end="Finish", y="Task"))
|
19 |
-
],
|
20 |
-
)
|
21 |
-
|
22 |
-
dashboard = vm.Dashboard(pages=[page])
|
23 |
-
Vizro().build(dashboard).run()
|
|
|
1 |
import pandas as pd
|
|
|
2 |
import vizro.plotly.express as px
|
|
|
3 |
|
4 |
tasks = pd.DataFrame(
|
5 |
[
|
|
|
7 |
{"Task": "Job B", "Start": "2009-03-05", "Finish": "2009-04-15"},
|
8 |
{"Task": "Job C", "Start": "2009-02-20", "Finish": "2009-05-30"},
|
9 |
]
|
10 |
+
).sort_values("Start", ascending=False)
|
11 |
|
12 |
+
fig = px.timeline(tasks, x_start="Start", x_end="Finish", y="Task")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pages/examples/heatmap.py
CHANGED
@@ -1,15 +1,5 @@
|
|
1 |
-
import vizro.models as vm
|
2 |
import vizro.plotly.express as px
|
3 |
-
from vizro import Vizro
|
4 |
|
5 |
tips = px.data.tips()
|
6 |
|
7 |
-
|
8 |
-
title="Heatmap",
|
9 |
-
components=[
|
10 |
-
vm.Graph(figure=px.density_heatmap(tips, x="day", y="size", z="tip", histfunc="avg", text_auto="$.2f")),
|
11 |
-
],
|
12 |
-
)
|
13 |
-
|
14 |
-
dashboard = vm.Dashboard(pages=[page])
|
15 |
-
Vizro().build(dashboard).run()
|
|
|
|
|
1 |
import vizro.plotly.express as px
|
|
|
2 |
|
3 |
tips = px.data.tips()
|
4 |
|
5 |
+
fig = px.density_heatmap(tips, x="day", y="size", z="tip", histfunc="avg", text_auto="$.2f")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pages/examples/histogram.py
CHANGED
@@ -1,13 +1,5 @@
|
|
1 |
-
import vizro.models as vm
|
2 |
import vizro.plotly.express as px
|
3 |
-
from vizro import Vizro
|
4 |
|
5 |
tips = px.data.tips()
|
6 |
|
7 |
-
|
8 |
-
title="Histogram",
|
9 |
-
components=[vm.Graph(px.histogram(tips, x="total_bill"))],
|
10 |
-
)
|
11 |
-
|
12 |
-
dashboard = vm.Dashboard(pages=[page])
|
13 |
-
Vizro().build(dashboard).run()
|
|
|
|
|
1 |
import vizro.plotly.express as px
|
|
|
2 |
|
3 |
tips = px.data.tips()
|
4 |
|
5 |
+
fig = px.histogram(tips, x="total_bill")
|
|
|
|
|
|
|
|
|
|
|
|
pages/examples/line.py
CHANGED
@@ -1,13 +1,5 @@
|
|
1 |
-
import vizro.models as vm
|
2 |
import vizro.plotly.express as px
|
3 |
-
from vizro import Vizro
|
4 |
|
5 |
stocks = px.data.stocks()
|
6 |
|
7 |
-
|
8 |
-
title="Line",
|
9 |
-
components=[vm.Graph(figure=px.line(stocks, x="date", y="GOOG"))],
|
10 |
-
)
|
11 |
-
|
12 |
-
dashboard = vm.Dashboard(pages=[page])
|
13 |
-
Vizro().build(dashboard).run()
|
|
|
|
|
1 |
import vizro.plotly.express as px
|
|
|
2 |
|
3 |
stocks = px.data.stocks()
|
4 |
|
5 |
+
fig = px.line(stocks, x="date", y="GOOG")
|
|
|
|
|
|
|
|
|
|
|
|
pages/examples/magnitude_column.py
CHANGED
@@ -1,23 +1,7 @@
|
|
1 |
-
import vizro.models as vm
|
2 |
import vizro.plotly.express as px
|
3 |
-
from vizro import Vizro
|
4 |
|
5 |
-
gapminder = px.data.gapminder()
|
6 |
-
|
7 |
-
page = vm.Page(
|
8 |
-
title="Column",
|
9 |
-
components=[
|
10 |
-
vm.Graph(
|
11 |
-
figure=px.bar(
|
12 |
-
gapminder.query(
|
13 |
-
"year == 2007 and country.isin(['United States', 'Pakistan', 'India', 'China', 'Indonesia'])"
|
14 |
-
),
|
15 |
-
y="pop",
|
16 |
-
x="country",
|
17 |
-
)
|
18 |
-
)
|
19 |
-
],
|
20 |
)
|
21 |
|
22 |
-
|
23 |
-
Vizro().build(dashboard).run()
|
|
|
|
|
1 |
import vizro.plotly.express as px
|
|
|
2 |
|
3 |
+
gapminder = px.data.gapminder().query(
|
4 |
+
"year == 2007 and country.isin(['United States', 'Pakistan', 'India', 'China', 'Indonesia'])"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
)
|
6 |
|
7 |
+
fig = px.bar(gapminder, y="pop", x="country")
|
|
pages/examples/ordered_bar.py
CHANGED
@@ -1,25 +1,9 @@
|
|
1 |
-
import vizro.models as vm
|
2 |
import vizro.plotly.express as px
|
3 |
-
from vizro import Vizro
|
4 |
|
5 |
-
gapminder =
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
title="Ordered bar",
|
10 |
-
components=[
|
11 |
-
vm.Graph(
|
12 |
-
figure=px.bar(
|
13 |
-
gapminder.query(
|
14 |
-
"year == 2007 and country.isin(['United States', 'Pakistan', 'India', 'China', 'Indonesia'])"
|
15 |
-
).sort_values("pop"),
|
16 |
-
x="pop",
|
17 |
-
y="country",
|
18 |
-
orientation="h",
|
19 |
-
)
|
20 |
-
)
|
21 |
-
],
|
22 |
)
|
23 |
|
24 |
-
|
25 |
-
Vizro().build(dashboard).run()
|
|
|
|
|
1 |
import vizro.plotly.express as px
|
|
|
2 |
|
3 |
+
gapminder = (
|
4 |
+
px.data.gapminder()
|
5 |
+
.query("year == 2007 and country.isin(['United States', 'Pakistan', 'India', 'China', 'Indonesia'])")
|
6 |
+
.sort_values("pop")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
)
|
8 |
|
9 |
+
fig = px.bar(gapminder, x="pop", y="country", orientation="h")
|
|
pages/examples/ordered_column.py
CHANGED
@@ -1,24 +1,9 @@
|
|
1 |
-
import vizro.models as vm
|
2 |
import vizro.plotly.express as px
|
3 |
-
from vizro import Vizro
|
4 |
|
5 |
-
gapminder =
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
title="Ordered column",
|
10 |
-
components=[
|
11 |
-
vm.Graph(
|
12 |
-
figure=px.bar(
|
13 |
-
gapminder.query(
|
14 |
-
"year == 2007 and country.isin(['United States', 'Pakistan', 'India', 'China', 'Indonesia'])"
|
15 |
-
).sort_values("pop"),
|
16 |
-
y="pop",
|
17 |
-
x="country",
|
18 |
-
)
|
19 |
-
)
|
20 |
-
],
|
21 |
)
|
22 |
|
23 |
-
|
24 |
-
Vizro().build(dashboard).run()
|
|
|
|
|
1 |
import vizro.plotly.express as px
|
|
|
2 |
|
3 |
+
gapminder = (
|
4 |
+
px.data.gapminder()
|
5 |
+
.query("year == 2007 and country.isin(['United States', 'Pakistan', 'India', 'China', 'Indonesia'])")
|
6 |
+
.sort_values("pop")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
)
|
8 |
|
9 |
+
fig = px.bar(gapminder, y="pop", x="country")
|
|
pages/examples/paired_bar.py
CHANGED
@@ -1,26 +1,13 @@
|
|
1 |
-
import vizro.models as vm
|
2 |
import vizro.plotly.express as px
|
3 |
-
from vizro import Vizro
|
4 |
|
5 |
tips = px.data.tips()
|
6 |
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
x="total_bill",
|
16 |
-
color="sex",
|
17 |
-
barmode="group",
|
18 |
-
orientation="h",
|
19 |
-
category_orders={"day": ["Thur", "Fri", "Sat", "Sun"]},
|
20 |
-
),
|
21 |
-
)
|
22 |
-
],
|
23 |
)
|
24 |
-
|
25 |
-
dashboard = vm.Dashboard(pages=[page])
|
26 |
-
Vizro().build(dashboard).run()
|
|
|
|
|
1 |
import vizro.plotly.express as px
|
|
|
2 |
|
3 |
tips = px.data.tips()
|
4 |
|
5 |
+
fig = px.histogram(
|
6 |
+
tips,
|
7 |
+
y="day",
|
8 |
+
x="total_bill",
|
9 |
+
color="sex",
|
10 |
+
barmode="group",
|
11 |
+
orientation="h",
|
12 |
+
category_orders={"day": ["Thur", "Fri", "Sat", "Sun"]},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
)
|
|
|
|
|
|
pages/examples/paired_column.py
CHANGED
@@ -1,25 +1,7 @@
|
|
1 |
-
import vizro.models as vm
|
2 |
import vizro.plotly.express as px
|
3 |
-
from vizro import Vizro
|
4 |
|
5 |
tips = px.data.tips()
|
6 |
|
7 |
-
|
8 |
-
|
9 |
-
title="Paired column",
|
10 |
-
components=[
|
11 |
-
vm.Graph(
|
12 |
-
figure=px.histogram(
|
13 |
-
tips,
|
14 |
-
x="day",
|
15 |
-
y="total_bill",
|
16 |
-
color="sex",
|
17 |
-
barmode="group",
|
18 |
-
category_orders={"day": ["Thur", "Fri", "Sat", "Sun"]},
|
19 |
-
),
|
20 |
-
)
|
21 |
-
],
|
22 |
)
|
23 |
-
|
24 |
-
dashboard = vm.Dashboard(pages=[page])
|
25 |
-
Vizro().build(dashboard).run()
|
|
|
|
|
1 |
import vizro.plotly.express as px
|
|
|
2 |
|
3 |
tips = px.data.tips()
|
4 |
|
5 |
+
fig = px.histogram(
|
6 |
+
tips, x="day", y="total_bill", color="sex", barmode="group", category_orders={"day": ["Thur", "Fri", "Sat", "Sun"]}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
)
|
|
|
|
|
|
pages/examples/parallel_coordinates.py
CHANGED
@@ -1,19 +1,7 @@
|
|
1 |
-
import vizro.models as vm
|
2 |
import vizro.plotly.express as px
|
3 |
-
from vizro import Vizro
|
4 |
|
5 |
iris = px.data.iris()
|
6 |
|
7 |
-
|
8 |
-
|
9 |
-
components=[
|
10 |
-
vm.Graph(
|
11 |
-
figure=px.parallel_coordinates(
|
12 |
-
iris, color="species_id", dimensions=["sepal_width", "sepal_length", "petal_width", "petal_length"]
|
13 |
-
)
|
14 |
-
)
|
15 |
-
],
|
16 |
)
|
17 |
-
|
18 |
-
dashboard = vm.Dashboard(pages=[page])
|
19 |
-
Vizro().build(dashboard).run()
|
|
|
|
|
1 |
import vizro.plotly.express as px
|
|
|
2 |
|
3 |
iris = px.data.iris()
|
4 |
|
5 |
+
fig = px.parallel_coordinates(
|
6 |
+
iris, color="species_id", dimensions=["sepal_width", "sepal_length", "petal_width", "petal_length"]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
)
|
|
|
|
|
|
pages/examples/pie.py
CHANGED
@@ -1,13 +1,5 @@
|
|
1 |
-
import vizro.models as vm
|
2 |
import vizro.plotly.express as px
|
3 |
-
from vizro import Vizro
|
4 |
|
5 |
tips = px.data.tips()
|
6 |
|
7 |
-
|
8 |
-
title="Pie",
|
9 |
-
components=[vm.Graph(figure=px.pie(tips, values="tip", names="day"))],
|
10 |
-
)
|
11 |
-
|
12 |
-
dashboard = vm.Dashboard(pages=[page])
|
13 |
-
Vizro().build(dashboard).run()
|
|
|
|
|
1 |
import vizro.plotly.express as px
|
|
|
2 |
|
3 |
tips = px.data.tips()
|
4 |
|
5 |
+
fig = px.pie(tips, values="tip", names="day")
|
|
|
|
|
|
|
|
|
|
|
|
pages/examples/radar.py
CHANGED
@@ -1,25 +1,15 @@
|
|
1 |
-
import
|
2 |
import vizro.plotly.express as px
|
3 |
-
from vizro import Vizro
|
4 |
from vizro.models.types import capture
|
5 |
|
6 |
-
wind = px.data.wind()
|
7 |
-
|
8 |
|
9 |
@capture("graph")
|
10 |
-
def radar(data_frame, **kwargs):
|
11 |
-
"""Creates a radar chart using Plotly's line_polar."""
|
12 |
fig = px.line_polar(data_frame, **kwargs)
|
13 |
fig.update_traces(fill="toself")
|
14 |
return fig
|
15 |
|
16 |
|
17 |
-
|
18 |
-
title="Radar",
|
19 |
-
components=[
|
20 |
-
vm.Graph(figure=radar(wind.query("strength == '1-2'"), r="frequency", theta="direction", line_close=True))
|
21 |
-
],
|
22 |
-
)
|
23 |
|
24 |
-
|
25 |
-
Vizro().build(dashboard).run()
|
|
|
1 |
+
import pandas as pd
|
2 |
import vizro.plotly.express as px
|
|
|
3 |
from vizro.models.types import capture
|
4 |
|
|
|
|
|
5 |
|
6 |
@capture("graph")
|
7 |
+
def radar(data_frame: pd.DataFrame, **kwargs):
|
|
|
8 |
fig = px.line_polar(data_frame, **kwargs)
|
9 |
fig.update_traces(fill="toself")
|
10 |
return fig
|
11 |
|
12 |
|
13 |
+
wind = px.data.wind().query("strength == '1-2'")
|
|
|
|
|
|
|
|
|
|
|
14 |
|
15 |
+
fig = radar(wind, r="frequency", theta="direction", line_close=True)
|
|
pages/examples/sankey.py
CHANGED
@@ -1,19 +1,7 @@
|
|
1 |
-
from typing import List
|
2 |
-
|
3 |
import pandas as pd
|
4 |
import plotly.graph_objects as go
|
5 |
-
import vizro.models as vm
|
6 |
-
from vizro import Vizro
|
7 |
from vizro.models.types import capture
|
8 |
|
9 |
-
sankey_data = pd.DataFrame(
|
10 |
-
{
|
11 |
-
"Origin": [0, 1, 0, 2, 3, 3], # indices inside labels
|
12 |
-
"Destination": [2, 3, 3, 4, 4, 5], # indices inside labels
|
13 |
-
"Value": [8, 4, 2, 8, 4, 2],
|
14 |
-
}
|
15 |
-
)
|
16 |
-
|
17 |
|
18 |
@capture("graph")
|
19 |
def sankey(
|
@@ -21,44 +9,35 @@ def sankey(
|
|
21 |
source: str,
|
22 |
target: str,
|
23 |
value: str,
|
24 |
-
labels:
|
25 |
):
|
26 |
-
|
27 |
-
data=
|
28 |
-
|
29 |
-
|
30 |
-
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
]
|
43 |
)
|
44 |
-
fig.update_layout(barmode="relative")
|
45 |
-
return fig
|
46 |
|
47 |
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
labels=["A1", "A2", "B1", "B2", "C1", "C2"],
|
55 |
-
source="Origin",
|
56 |
-
target="Destination",
|
57 |
-
value="Value",
|
58 |
-
),
|
59 |
-
),
|
60 |
-
],
|
61 |
)
|
62 |
|
63 |
-
|
64 |
-
|
|
|
|
|
|
|
|
1 |
import pandas as pd
|
2 |
import plotly.graph_objects as go
|
|
|
|
|
3 |
from vizro.models.types import capture
|
4 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
|
6 |
@capture("graph")
|
7 |
def sankey(
|
|
|
9 |
source: str,
|
10 |
target: str,
|
11 |
value: str,
|
12 |
+
labels: list[str],
|
13 |
):
|
14 |
+
return go.Figure(
|
15 |
+
data=go.Sankey(
|
16 |
+
node={
|
17 |
+
"pad": 16,
|
18 |
+
"thickness": 16,
|
19 |
+
"label": labels,
|
20 |
+
},
|
21 |
+
link={
|
22 |
+
"source": data_frame[source],
|
23 |
+
"target": data_frame[target],
|
24 |
+
"value": data_frame[value],
|
25 |
+
"label": labels,
|
26 |
+
"color": "rgba(205, 209, 228, 0.4)",
|
27 |
+
},
|
28 |
+
),
|
29 |
+
layout={"barmode": "relative"},
|
|
|
30 |
)
|
|
|
|
|
31 |
|
32 |
|
33 |
+
sankey_data = pd.DataFrame(
|
34 |
+
{
|
35 |
+
"Origin": [0, 1, 0, 2, 3, 3], # indices inside labels
|
36 |
+
"Destination": [2, 3, 3, 4, 4, 5], # indices inside labels
|
37 |
+
"Value": [8, 4, 2, 8, 4, 2],
|
38 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
39 |
)
|
40 |
|
41 |
+
fig = sankey(
|
42 |
+
sankey_data, labels=["A1", "A2", "B1", "B2", "C1", "C2"], source="Origin", target="Destination", value="Value"
|
43 |
+
)
|
pages/examples/scatter.py
CHANGED
@@ -1,13 +1,5 @@
|
|
1 |
-
import vizro.models as vm
|
2 |
import vizro.plotly.express as px
|
3 |
-
from vizro import Vizro
|
4 |
|
5 |
iris = px.data.iris()
|
6 |
|
7 |
-
|
8 |
-
title="Scatter",
|
9 |
-
components=[vm.Graph(figure=px.scatter(iris, x="sepal_width", y="sepal_length", color="species"))],
|
10 |
-
)
|
11 |
-
|
12 |
-
dashboard = vm.Dashboard(pages=[page])
|
13 |
-
Vizro().build(dashboard).run()
|
|
|
|
|
1 |
import vizro.plotly.express as px
|
|
|
2 |
|
3 |
iris = px.data.iris()
|
4 |
|
5 |
+
fig = px.scatter(iris, x="sepal_width", y="sepal_length", color="species")
|
|
|
|
|
|
|
|
|
|
|
|
pages/examples/scatter_matrix.py
CHANGED
@@ -1,17 +1,5 @@
|
|
1 |
-
import vizro.models as vm
|
2 |
import vizro.plotly.express as px
|
3 |
-
from vizro import Vizro
|
4 |
|
5 |
iris = px.data.iris()
|
6 |
|
7 |
-
|
8 |
-
title="Scatter matrix",
|
9 |
-
components=[
|
10 |
-
vm.Graph(
|
11 |
-
figure=px.scatter_matrix(iris, dimensions=["sepal_length", "sepal_width", "petal_length", "petal_width"])
|
12 |
-
)
|
13 |
-
],
|
14 |
-
)
|
15 |
-
|
16 |
-
dashboard = vm.Dashboard(pages=[page])
|
17 |
-
Vizro().build(dashboard).run()
|
|
|
|
|
1 |
import vizro.plotly.express as px
|
|
|
2 |
|
3 |
iris = px.data.iris()
|
4 |
|
5 |
+
fig = px.scatter_matrix(iris, dimensions=["sepal_length", "sepal_width", "petal_length", "petal_width"])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pages/examples/stacked_bar.py
CHANGED
@@ -1,14 +1,5 @@
|
|
1 |
-
import vizro.models as vm
|
2 |
import vizro.plotly.express as px
|
3 |
-
from vizro import Vizro
|
4 |
|
5 |
tips = px.data.tips()
|
6 |
|
7 |
-
|
8 |
-
page = vm.Page(
|
9 |
-
title="Stacked bar",
|
10 |
-
components=[vm.Graph(figure=px.histogram(tips, y="sex", x="total_bill", color="day", orientation="h"))],
|
11 |
-
)
|
12 |
-
|
13 |
-
dashboard = vm.Dashboard(pages=[page])
|
14 |
-
Vizro().build(dashboard).run()
|
|
|
|
|
1 |
import vizro.plotly.express as px
|
|
|
2 |
|
3 |
tips = px.data.tips()
|
4 |
|
5 |
+
fig = px.histogram(tips, y="sex", x="total_bill", color="day", orientation="h")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pages/examples/stacked_column.py
CHANGED
@@ -1,14 +1,5 @@
|
|
1 |
-
import vizro.models as vm
|
2 |
import vizro.plotly.express as px
|
3 |
-
from vizro import Vizro
|
4 |
|
5 |
tips = px.data.tips()
|
6 |
|
7 |
-
|
8 |
-
page = vm.Page(
|
9 |
-
title="Stacked column",
|
10 |
-
components=[vm.Graph(figure=px.histogram(tips, x="sex", y="total_bill", color="day"))],
|
11 |
-
)
|
12 |
-
|
13 |
-
dashboard = vm.Dashboard(pages=[page])
|
14 |
-
Vizro().build(dashboard).run()
|
|
|
|
|
1 |
import vizro.plotly.express as px
|
|
|
2 |
|
3 |
tips = px.data.tips()
|
4 |
|
5 |
+
fig = px.histogram(tips, x="sex", y="total_bill", color="day")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pages/examples/stepped_line.py
CHANGED
@@ -1,7 +1,5 @@
|
|
1 |
import pandas as pd
|
2 |
-
import vizro.models as vm
|
3 |
import vizro.plotly.express as px
|
4 |
-
from vizro import Vizro
|
5 |
|
6 |
stepped_line_data = pd.DataFrame(
|
7 |
{
|
@@ -10,18 +8,4 @@ stepped_line_data = pd.DataFrame(
|
|
10 |
}
|
11 |
)
|
12 |
|
13 |
-
|
14 |
-
title="Stepped line",
|
15 |
-
components=[
|
16 |
-
vm.Graph(
|
17 |
-
figure=px.line(
|
18 |
-
data_frame=stepped_line_data,
|
19 |
-
x="year",
|
20 |
-
y="rate",
|
21 |
-
line_shape="vh",
|
22 |
-
),
|
23 |
-
)
|
24 |
-
],
|
25 |
-
)
|
26 |
-
dashboard = vm.Dashboard(pages=[page])
|
27 |
-
Vizro().build(dashboard).run()
|
|
|
1 |
import pandas as pd
|
|
|
2 |
import vizro.plotly.express as px
|
|
|
3 |
|
4 |
stepped_line_data = pd.DataFrame(
|
5 |
{
|
|
|
8 |
}
|
9 |
)
|
10 |
|
11 |
+
fig = px.line(data_frame=stepped_line_data, x="year", y="rate", line_shape="vh")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pages/examples/time_column.py
CHANGED
@@ -1,36 +1,16 @@
|
|
1 |
import pandas as pd
|
2 |
-
import
|
3 |
import vizro.plotly.express as px
|
4 |
-
from vizro import Vizro
|
5 |
from vizro.models.types import capture
|
6 |
|
7 |
-
gapminder = px.data.gapminder()
|
8 |
-
|
9 |
|
10 |
@capture("graph")
|
11 |
-
def categorical_column(data_frame: pd.DataFrame,
|
12 |
-
fig = px.bar(
|
13 |
-
data_frame,
|
14 |
-
x=x,
|
15 |
-
y=y,
|
16 |
-
)
|
17 |
-
# So ticks are aligned with bars when xaxes values are numbers (e.g. years)
|
18 |
fig.update_xaxes(type="category")
|
19 |
return fig
|
20 |
|
21 |
|
22 |
-
|
23 |
-
title="Column",
|
24 |
-
components=[
|
25 |
-
vm.Graph(
|
26 |
-
figure=categorical_column(
|
27 |
-
gapminder.query("country == 'Nigeria' and year > 1970"),
|
28 |
-
y="lifeExp",
|
29 |
-
x="year",
|
30 |
-
)
|
31 |
-
)
|
32 |
-
],
|
33 |
-
)
|
34 |
|
35 |
-
|
36 |
-
Vizro().build(dashboard).run()
|
|
|
1 |
import pandas as pd
|
2 |
+
import plotly.graph_objects as go
|
3 |
import vizro.plotly.express as px
|
|
|
4 |
from vizro.models.types import capture
|
5 |
|
|
|
|
|
6 |
|
7 |
@capture("graph")
|
8 |
+
def categorical_column(data_frame: pd.DataFrame, **kwargs) -> go.Figure:
|
9 |
+
fig = px.bar(data_frame, **kwargs)
|
|
|
|
|
|
|
|
|
|
|
10 |
fig.update_xaxes(type="category")
|
11 |
return fig
|
12 |
|
13 |
|
14 |
+
gapminder = px.data.gapminder().query("country == 'Nigeria' and year > 1970")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
|
16 |
+
fig = categorical_column(gapminder, x="year", y="lifeExp")
|
|
pages/examples/treemap.py
CHANGED
@@ -1,22 +1,5 @@
|
|
1 |
-
import vizro.models as vm
|
2 |
import vizro.plotly.express as px
|
3 |
-
from vizro import Vizro
|
4 |
|
5 |
-
gapminder = px.data.gapminder()
|
6 |
|
7 |
-
|
8 |
-
title="Treemap",
|
9 |
-
components=[
|
10 |
-
vm.Graph(
|
11 |
-
figure=px.treemap(
|
12 |
-
gapminder.query("year == 2007"),
|
13 |
-
path=[px.Constant("world"), "continent", "country"],
|
14 |
-
values="pop",
|
15 |
-
color="lifeExp",
|
16 |
-
)
|
17 |
-
),
|
18 |
-
],
|
19 |
-
)
|
20 |
-
|
21 |
-
dashboard = vm.Dashboard(pages=[page])
|
22 |
-
Vizro().build(dashboard).run()
|
|
|
|
|
1 |
import vizro.plotly.express as px
|
|
|
2 |
|
3 |
+
gapminder = px.data.gapminder().query("year == 2007")
|
4 |
|
5 |
+
fig = px.treemap(gapminder, path=[px.Constant("world"), "continent", "country"], values="pop", color="lifeExp")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pages/examples/violin.py
CHANGED
@@ -1,15 +1,5 @@
|
|
1 |
-
import vizro.models as vm
|
2 |
import vizro.plotly.express as px
|
3 |
-
from vizro import Vizro
|
4 |
|
5 |
tips = px.data.tips()
|
6 |
|
7 |
-
|
8 |
-
title="Violin",
|
9 |
-
components=[
|
10 |
-
vm.Graph(figure=px.violin(tips, y="total_bill", x="day", color="day", box=True)),
|
11 |
-
],
|
12 |
-
)
|
13 |
-
|
14 |
-
dashboard = vm.Dashboard(pages=[page])
|
15 |
-
Vizro().build(dashboard).run()
|
|
|
|
|
1 |
import vizro.plotly.express as px
|
|
|
2 |
|
3 |
tips = px.data.tips()
|
4 |
|
5 |
+
fig = px.violin(tips, y="total_bill", x="day", color="day", box=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
pages/examples/waterfall.py
CHANGED
@@ -1,51 +1,27 @@
|
|
1 |
-
from typing import List
|
2 |
-
|
3 |
import pandas as pd
|
4 |
import plotly.graph_objects as go
|
5 |
-
import vizro.models as vm
|
6 |
-
from vizro import Vizro
|
7 |
from vizro.models.types import capture
|
8 |
|
9 |
-
waterfall_data = pd.DataFrame(
|
10 |
-
{
|
11 |
-
"x": ["Sales", "Consulting", "Net revenue", "Purchases", "Other expenses", "Profit before tax"],
|
12 |
-
"y": [60, 80, 0, -40, -20, 0],
|
13 |
-
"measure": ["relative", "relative", "total", "relative", "relative", "total"],
|
14 |
-
}
|
15 |
-
)
|
16 |
-
|
17 |
|
18 |
@capture("graph")
|
19 |
def waterfall(
|
20 |
data_frame: pd.DataFrame,
|
21 |
x: str,
|
22 |
y: str,
|
23 |
-
measure:
|
24 |
):
|
25 |
-
|
26 |
-
go.Waterfall(
|
27 |
-
|
28 |
-
y=data_frame[y],
|
29 |
-
measure=data_frame[measure],
|
30 |
-
)
|
31 |
)
|
32 |
-
fig.update_layout(showlegend=False)
|
33 |
-
return fig
|
34 |
|
35 |
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
x="x",
|
43 |
-
y="y",
|
44 |
-
measure="measure",
|
45 |
-
)
|
46 |
-
)
|
47 |
-
],
|
48 |
)
|
49 |
|
50 |
-
|
51 |
-
Vizro().build(dashboard).run()
|
|
|
|
|
|
|
1 |
import pandas as pd
|
2 |
import plotly.graph_objects as go
|
|
|
|
|
3 |
from vizro.models.types import capture
|
4 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
|
6 |
@capture("graph")
|
7 |
def waterfall(
|
8 |
data_frame: pd.DataFrame,
|
9 |
x: str,
|
10 |
y: str,
|
11 |
+
measure: list[str],
|
12 |
):
|
13 |
+
return go.Figure(
|
14 |
+
data=go.Waterfall(x=data_frame[x], y=data_frame[y], measure=data_frame[measure]),
|
15 |
+
layout={"showlegend": False},
|
|
|
|
|
|
|
16 |
)
|
|
|
|
|
17 |
|
18 |
|
19 |
+
waterfall_data = pd.DataFrame(
|
20 |
+
{
|
21 |
+
"x": ["Sales", "Consulting", "Net revenue", "Purchases", "Other expenses", "Profit before tax"],
|
22 |
+
"y": [60, 80, 0, -40, -20, 0],
|
23 |
+
"measure": ["relative", "relative", "total", "relative", "relative", "total"],
|
24 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
)
|
26 |
|
27 |
+
fig = waterfall(waterfall_data, x="x", y="y", measure="measure")
|
|
pages/flow.py
CHANGED
@@ -1,12 +1,12 @@
|
|
1 |
"""Flow charts."""
|
2 |
|
3 |
import vizro.models as vm
|
4 |
-
from custom_charts import sankey
|
5 |
|
6 |
from pages._factories import waterfall_factory
|
7 |
-
from pages._pages_utils import PAGE_GRID, make_code_clipboard_from_py_file
|
|
|
8 |
|
9 |
-
|
10 |
title="Sankey",
|
11 |
path="flow/sankey",
|
12 |
layout=vm.Layout(grid=PAGE_GRID),
|
@@ -32,19 +32,21 @@ sankey = vm.Page(
|
|
32 |
possible.
|
33 |
"""
|
34 |
),
|
35 |
-
vm.Graph(
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
|
|
|
|
|
|
43 |
),
|
44 |
-
make_code_clipboard_from_py_file("sankey.py"),
|
45 |
],
|
46 |
)
|
47 |
|
48 |
-
|
49 |
|
50 |
-
pages = [
|
|
|
1 |
"""Flow charts."""
|
2 |
|
3 |
import vizro.models as vm
|
|
|
4 |
|
5 |
from pages._factories import waterfall_factory
|
6 |
+
from pages._pages_utils import PAGE_GRID, make_code_clipboard_from_py_file
|
7 |
+
from pages.examples import sankey
|
8 |
|
9 |
+
sankey_page = vm.Page(
|
10 |
title="Sankey",
|
11 |
path="flow/sankey",
|
12 |
layout=vm.Layout(grid=PAGE_GRID),
|
|
|
32 |
possible.
|
33 |
"""
|
34 |
),
|
35 |
+
vm.Graph(figure=sankey.fig),
|
36 |
+
vm.Tabs(
|
37 |
+
tabs=[
|
38 |
+
vm.Container(
|
39 |
+
title="Vizro dashboard", components=[make_code_clipboard_from_py_file("sankey.py", mode="vizro")]
|
40 |
+
),
|
41 |
+
vm.Container(
|
42 |
+
title="Plotly figure",
|
43 |
+
components=[make_code_clipboard_from_py_file("sankey.py", mode="plotly")],
|
44 |
+
),
|
45 |
+
]
|
46 |
),
|
|
|
47 |
],
|
48 |
)
|
49 |
|
50 |
+
waterfall_page = waterfall_factory("flow")
|
51 |
|
52 |
+
pages = [sankey_page, waterfall_page]
|