Reactive Web Dashboards with Shiny Transcripts
Chapter: Basic user interfaces
Lecture: Basic UI
Login or
purchase this course
to watch this video and the rest of the course contents.
0:00
Okay, so we made a lot of progress with our basic Shiny app, and we've got a slider which
0:07
filters the data frame, and that updates a plot and a data frame output. So you can see the plotted
0:13
data and the raw data. But when you look at this application, it's got some layout problems.
0:19
So first of all, this input here affects both outputs, but it's kind of a little bit hard to
0:26
see it, especially when you're scrolling down here to the bottom of the data frame.
0:30
Secondly, it would be nice if there were some sort of visual differentiation between the two
0:35
components. And lastly, we might want to explore just putting them side by side so that you could
0:39
see the plot and the data frame at the same time. So whenever you have layout problems like this,
0:44
like you have all the components you want, but you just need to organize them in a different way,
0:48
the first your first step should be to go to the Shiny layout gallery, which gives you a nice
0:54
visual representation of some of the layouts that we have for our applications. So there's nav bars
0:59
down here, we have tabs and cards. And the one I'm going to look at first of all is sidebar.
1:05
This is probably the most common thing that you're going to do with an application is just stick some
1:10
inputs in the sidebar. You see here, sidebar is a nice little collapsible container, which you can
1:16
add inputs and outputs to. And when we look at the code example here, it's pretty simple,
1:21
you use a context manager. And we can just go ahead and copy this and bring it over to our
1:27
application. So with Shiny Express, to add a sidebar, you add a context manager with UI sidebar,
1:36
and you can add a background color if you like. And that will create a little sidebar in your
1:42
application. If you've never used a context manager before, they're just a kind of different way of
1:48
calling a function. Instead of calling UI.sidebar with all of its arguments inside the braces,
1:54
you can call it with UI sidebar and then have this colon and then add the arguments to that
2:01
function underneath without commas. So it's a little bit more convenient, especially in the
2:05
Shiny Express style of writing applications. So let's put our input over there and see what that
2:12
looks like. It's a little better because we're able to see the input as we scroll. So it sort
2:22
of stays at the top when we scroll down in the main panel. But it still works just like it did
2:27
before. And you can collapse or not collapse that sidebar. Okay, so that's great. So the next thing
2:34
we want to do is add some visual differentiation between the cards. And again, we're going to go
2:39
to the layout gallery and see if there's anything here that can help us. So down at the bottom,
2:46
I see there's some content and cards that maybe looks like what we're looking for.
2:51
And this actually has both of the things we're looking for. We have content in a little
2:54
differentiated card, and also they're laid out side by side. So let's see how that happened.
2:59
So see, we have two context managers here. So there's UI card and then layout columns. And so I'll start here with the UI card.
3:07
Again, we can add any type of content we like here. So add with UI card around that one
3:19
and around this one. And that'll give us this nice little rounded box, which oddly makes your
3:28
application a lot easier to read and more attractive. Cards also let you add a title
3:34
pretty easily. So we can add some text here at the top in the first argument to give us a little bit of information about what's going on in that card.
3:45
And they're also great for grouping together inputs and outputs. So for example, like let's
3:50
say we wanted to add input that changed just this plot, but not the data frame.
3:55
It might not make sense to put that in the sidebar because then it's not really clear
3:59
what that is modifying. But when we add it directly under the plot or somewhere in the card,
4:05
it makes it a lot more clear. So here I'll add a show species checkbox. And this will add that show species down here. This doesn't do anything yet.
4:17
But we can then handle it just like we did before here. So for example, if input show species,
4:27
and then if not, we can add else return the scatterplot without the species.
4:36
And now when we have this thing, you see there's like a checkbox and it's clear that that's going
4:43
to apply just to this plot because it's in the, it's a little easier if we see it on a big screen.
4:49
It's clear that this only applies to the plot and not to the main body mass slider.
4:54
The last thing we probably want to do is try showing these side by side. So this plot
5:00
maybe doesn't actually need this much horizontal space. And it would be nice to be able to see the
5:03
plot and the data next to each other. And there's a very convenient function for this called layout
5:09
columns. And what layout columns does is it just takes the, so the children, the things that go in
5:15
that container and puts them side by side with equal space. You can modify how that spacing works,
5:21
but as a default, most of the time you kind of just want to have it be, you kind of want to mostly
5:26
just have it be side by side. Let's see what went wrong here. And now you see that since we have
5:32
this layout columns, we're able to put these two side by side. One nice thing about layout columns
5:37
is that it's dynamic to the screen size. So if it shrinks, you see the two cards shrink with it.
5:43
And also if it gets very small, for example, if you're viewing it on a phone, the whole thing
5:48
collapses to show things above them. And this is again, things you can configure, but the defaults
5:53
are mostly what you want. So as it gets to a larger screen, it does this, but if it's a smaller screen,
5:58
it's going to stack them up. All right, so that application is looking a lot more presentable.
6:04
Before we move on, there's one little technical thing that's worth just noting here. So one of
6:10
the things that is important for Shiny applications is that you take all of your code that is
6:15
expensive, like data reading, and you put it in a sub-module. And the reason for that is that
6:19
whenever any user is opening up your application, this whole script is going to run. And one way you
6:26
can prevent that data from being re-read on every single connection is to put it in another file.
6:34
So here I took the data import code that we had before, and I have it in this other file where
6:39
I'm defining this df variable, but otherwise it's just the same reading in the CSV. And when you do
6:46
that, what'll happen is that Python will cache that value whenever it's run. So then in the same
6:51
session, every time a user connects, they're going to retrieve the cached value rather than doing the
6:54
CSV read again and again. So we're going to be using that for most of the other exercises in
7:00
here, but I just wanted to mention that that's why that's happening there. All right, so we have
7:06
the basics of how to actually construct a Shiny application, and next we're going to move into
7:11
some more details about how this actually works and why Shiny is designed the way it is.