-
Notifications
You must be signed in to change notification settings - Fork 22
/
mtcars_server.py
107 lines (86 loc) · 3.07 KB
/
mtcars_server.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
"""
Purpose: Provide reactive output for the MT Cars dataset.
- Use inputs from the UI Sidebar to filter the dataset.
- Update reactive outputs in the UI Main Panel.
Matching the IDs in the UI Sidebar and function/output names in the UI Main Panel
to this server code is critical. They are case sensitive and must match exactly.
"""
import pathlib
from shiny import render, reactive
import matplotlib.pyplot as plt
import pandas as pd
from plotnine import aes, geom_point, ggplot, ggtitle
from shinywidgets import render_widget
import plotly.express as px
from util_logger import setup_logger
logger, logname = setup_logger(__name__)
def get_mtcars_server_functions(input, output, session):
"""Define functions to create UI outputs."""
p = pathlib.Path(__file__).parent.joinpath("data").joinpath("mtcars.csv")
# logger.info(f"Reading data from {p}")
original_df = pd.read_csv(p)
total_count = len(original_df)
reactive_df = reactive.Value()
@reactive.Effect
@reactive.event(input.MTCARS_MPG_RANGE)
def _():
df = original_df.copy()
input_range = input.MTCARS_MPG_RANGE()
input_min = input_range[0]
input_max = input_range[1]
"""
Filter the dataframe to just those greater than or equal to the min
and less than or equal to the max
Note: The ampersand (&) is the Python operator for AND
The column name is in quotes and is "mpg".
You must be familiar with the dataset to know the column names.
"""
filtered_df = df[(df["mpg"] >= input_min) & (df["mpg"] <= input_max)]
# Set the reactive value
reactive_df.set(filtered_df)
@output
@render.text
def mtcars_record_count_string():
filtered_df = reactive_df.get()
filtered_count = len(filtered_df)
message = f"Showing {filtered_count} of {total_count} records"
# logger.debug(f"filter message: {message}")
return message
@output
@render.table
def mtcars_filtered_table():
filtered_df = reactive_df.get()
return filtered_df
@output
@render_widget
def mtcars_output_widget1():
df = reactive_df.get()
plotly_express_plot = px.scatter(df, x="mpg", y="hp", color="cyl", size="wt")
plotly_express_plot.update_layout(title="MT Cars with Plotly Express")
return plotly_express_plot
@output
@render.plot
def mtcars_plot1():
df = reactive_df.get()
matplotlib_fig, ax = plt.subplots()
plt.title("MT Cars with matplotlib")
ax.scatter(df["wt"], df["mpg"])
return matplotlib_fig
@output
@render.plot
def mtcars_plot2():
df = reactive_df.get()
plotnine_plot = (
ggplot(df, aes("wt", "mpg"))
+ geom_point()
+ ggtitle("MT Cars with plotnine")
)
return plotnine_plot
# return a list of function names for use in reactive outputs
return [
mtcars_record_count_string,
mtcars_filtered_table,
mtcars_output_widget1,
mtcars_plot1,
mtcars_plot2,
]