Python 交互式数据可视化框架:Dash(中)

导读提要:Python 交互式数据可视化框架:Dash(上)

设置Dash应用程序的样式

Dash为您提供了很大的灵活性,可以自定义应用程序的外观。您可以使用自己的 CSS 或 JavaScript 文件,设置图标(在Web浏览器上显示的小图标)以及嵌入图像等高级选项。

在本节中,您将学习如何将自定义样式应用于组件,然后为上一节中构建的仪表板设置样式。

如何对组件应用设置自定义样式

您可以通过两种方式为组件设置样式:

1、使用单个组件的样式参数

2、提供一个外部CSS文件

使用style参数自定义仪表板非常简单。此参数采用带有键值对的Python字典,键值对由CSS属性的名称和要设置的值组成。

如果您想在app.py中更改H1元素的大小和颜色,则可以如下设置元素的style参数:

html.H1(
    children =“ Avocado Analytics”,
    style = {“ fontSize”:“ 48px”,“ color”:“ red”},
),

在这里,您可以使用属性和要为其设置的值来为字典设置样式。在这种情况下,指定的样式应具有一个红色标题,其字体大小为48像素。

使用style参数的不利之处在于,随着代码库的增长,它无法很好地扩展。如果您的信息中心中有多个您希望外观相同的组件,那么您将不得不重复写很多代码。相反,您可以使用自定义CSS文件。

如果要包括自己的本地CSS或JavaScript文件,则需要在项目的根目录中创建一个名为asset/的文件夹,然后将要添加的文件保存在其中。默认情况下,Dash自动提供asset/中包含的任何文件。如后文中所示,这也可以用于添加收藏夹图标或嵌入图像。

然后,您可以使用组件的classNameid参数来使用CSS调整其样式。这些参数在转换为HTML标签后便与classid属性相对应。

如果要调整app.pyH1元素的字体大小和文本颜色,则可以使用className参数,如下所示:

html.H1(
    children="Avocado Analytics",
    className="header-title",
),

设置className参数将定义H1元素的class属性。然后,您可以在assets文件夹中使用一个CSS文件来指定外观:

.header-title {
  font-size: 48px;
  color: red;
}

您可以使用类选择器来格式化CSS文件中的标题。该选择器将调整标题格式。您还可以通过设置className =“ header-title”将它与需要共享格式的其他元素一起使用。

接下来,您将为仪表盘设置样式。

如何改善仪表板的外观

前面介绍了Dash中样式的基础知识。现在,您将学习如何自定义仪表板的外观。您将进行以下改进:

  • 在页面上添加一个图标和标题

  • 更改仪表板的字体系列

  • 使用外部CSS文件设置Dash组件的样式

首先,您将学习如何在应用程序中使用外部资源。这样一来,您就可以添加图标,自定义字体系列和CSS样式表。然后,您将学习如何使用className参数将自定义样式应用于Dash组件。

向您的应用程序添加外部资源

在项目的根目录中创建一个名为asset /的文件夹。从Twemoji开源项目中下载一个图标,并将其另存为Asset /中的favicon.ico。最后,在assets /中创建一个名为style.css的CSS文件,并创建代码如下。

body {
    font-family: "Lato", sans-serif;
    margin: 0;
    background-color: #F7F7F7;
}

.header {
    background-color: #222222;
    height: 256px;
    display: flex;
    flex-direction: column;
    justify-content: center;
}

.header-emoji {
    font-size: 48px;
    margin: 0 auto;
    text-align: center;
}

.header-title {
    color: #FFFFFF;
    font-size: 48px;
    font-weight: bold;
    text-align: center;
    margin: 0 auto;
}

.header-description {
    color: #CFCFCF;
    margin: 4px auto;
    text-align: center;
    max-width: 384px;
}

.wrapper {
    margin-right: auto;
    margin-left: auto;
    max-width: 1024px;
    padding-right: 10px;
    padding-left: 10px;
    margin-top: 32px;
}

.card {
    margin-bottom: 24px;
    box-shadow: 0 4px 6px 0 rgba(0, 0, 0, 0.18);
}

assets/文件包含您将应用于APP程序布局中的组件样式。现在,您的项目结构应如下所示:

avocado_analytics/
│
├── assets/
│   ├── favicon.ico
│   └── style.css
│
├── venv/
│
├── app.py
└── avocado.csv

启动服务器后,Dash将自动提供位于Assets /中的文件。您在asset/中包含两个文件:favicon.icostyle.css。要设置默认图标,您无需采取任何其他步骤。要使用您在style.css中定义的样式,您需要在Dash组件中使用className参数。

app.py需要一些更改。其中包括一个外部样式表,在仪表板上添加标题,并使用style.css文件对组件进行样式设置。查看下面的更改。然后,在本节的最后部分,您将找到更新版本的app.py的完整代码。

您可以通过以下方式添加外部样式表并在仪表板上添加标题:

external_stylesheets = [
    {
        "href": "https://fonts.googleapis.com/css2?"
                "family=Lato:wght@400;700&display=swap",
        "rel": "stylesheet",
    },
]
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
app.title = "Avocado Analytics: Understand Your Avocados!"

在第11到18行上,指定要在应用程序中加载的外部CSS文件,即字体系列。外部文件被添加到应用程序的head标签中,并在应用程序主体加载之前加载。您可以使用external_stylesheets参数来添加外部CSS文件或为外部JavaScript文件(例如Google Analytics(分析))添加external_scripts

在第19行,设置应用程序的标题。这是共享网站时显示在网络浏览器标题栏中,Google的搜索结果中以及社交媒体卡中的文本。

自定义组件样式

要在style.css中使用样式,您需要在Dash组件中使用className参数。下面的代码向构成仪表板标题的每个组件中添加一个带有相应类选择器的className

app.layout = html.Div(
    children=[
        html.Div(
            children=[
                html.P(children="????", className="header-emoji"),
                html.H1(
                    children="Avocado Analytics", className="header-title"
                ),
                html.P(
                    children="Analyze the behavior of avocado prices"
                    " and the number of avocados sold in the US"
                    " between 2015 and 2018",
                    className="header-description",
                ),
            ],
            className="header",
        ),

在第21到37行,您可以看到对仪表板的初始版本进行了两项更改:

1、带有鳄梨表情符号的新段落元素将用作徽标。 

2、每个组件中都有一个className参数。这些类名称应与style.css中的类选择器匹配,该选择器将定义每个组件的外观。

例如,以“分析鳄梨价格的行为”开头的分配给段落组件的header-description类在style.css中具有相应的选择器:

.header-description {
    color: #CFCFCF;
    margin: 4px auto;
    text-align: center;
    max-width: 384px;
}

style.css的第29至34行定义了header-description类选择器的格式。这些将更改任何带有className =“ header-description”的组件的颜色、边距、对齐方式和最大宽度。所有组件在CSS文件中都有相应的类选择器。

另一个重要的变化是在图中。这是价格图表的新代码:

html.Div(
    children=[
        html.Div(
            children=dcc.Graph(
                id="price-chart",
                config={"displayModeBar": False},#43行
                figure={
                    "data": [
                        {
                            "x": data["Date"],
                            "y": data["AveragePrice"],
                            "type": "lines",
                            "hovertemplate": "$%{y:.2f}"#50行
                                                "<extra></extra>",#51行
                        },
                    ],
                    "layout": { #54行
                        "title": {
                            "text": "Average Price of Avocados",
                            "x": 0.05,
                            "xanchor": "left",
                        },
                        "xaxis": {"fixedrange": True},
                        "yaxis": {
                            "tickprefix": "$",
                            "fixedrange": True,
                        },
                        "colorway": ["#17B897"],
                    }, #66行
                },
            ),
            className="card",  #69行
        ),

在此代码中,您将为图表的configFigure参数定义一个className和一些自定义项。更改如下:

  • 第43行:您删除了默认情况下Plotly显示的浮动条。

  • 第50和51行:设置悬停模板,以便当用户将鼠标悬停在数据- 点上时,它以美元显示价格。而不是2.5,而是显示为$ 2.5

  • 第54到66行:您可以在图表的布局部分中调整轴,图形的颜色和标题格式。

  • 第69行:使用“ card”类将图形包装在html.Div中。这将使图形具有白色背景,并在其下方添加一个小阴影。销售量和数量图表也有类似的调整。

您可以在下面的可折叠部分中,以完整代码查看更新后的app.py

import dash
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd

data = pd.read_csv("avocado.csv")
data = data.query("type == 'conventional' and region == 'Albany'")
data["Date"] = pd.to_datetime(data["Date"], format="%Y-%m-%d")
data.sort_values("Date", inplace=True)

external_stylesheets = [
    {
        "href": "https://fonts.googleapis.com/css2?"
        "family=Lato:wght@400;700&display=swap",
        "rel": "stylesheet",
    },
]
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
app.title = "Avocado Analytics: Understand Your Avocados!"

app.layout = html.Div(
    children=[
        html.Div(
            children=[
                html.P(children="????", className="header-emoji"),
                html.H1(
                    children="Avocado Analytics", className="header-title"
                ),
                html.P(
                    children="Analyze the behavior of avocado prices"
                    " and the number of avocados sold in the US"
                    " between 2015 and 2018",
                    className="header-description",
                ),
            ],
            className="header",
        ),
        html.Div(
            children=[
                html.Div(
                    children=dcc.Graph(
                        id="price-chart",
                        config={"displayModeBar": False},
                        figure={
                            "data": [
                                {
                                    "x": data["Date"],
                                    "y": data["AveragePrice"],
                                    "type": "lines",
                                    "hovertemplate": "$%{y:.2f}"
                                                     "<extra></extra>",
                                },
                            ],
                            "layout": {
                                "title": {
                                    "text": "Average Price of Avocados",
                                    "x": 0.05,
                                    "xanchor": "left",
                                },
                                "xaxis": {"fixedrange": True},
                                "yaxis": {
                                    "tickprefix": "$",
                                    "fixedrange": True,
                                },
                                "colorway": ["#17B897"],
                            },
                        },
                    ),
                    className="card",
                ),
                html.Div(
                    children=dcc.Graph(
                        id="volume-chart",
                        config={"displayModeBar": False},
                        figure={
                            "data": [
                                {
                                    "x": data["Date"],
                                    "y": data["Total Volume"],
                                    "type": "lines",
                                },
                            ],
                            "layout": {
                                "title": {
                                    "text": "Avocados Sold",
                                    "x": 0.05,
                                    "xanchor": "left",
                                },
                                "xaxis": {"fixedrange": True},
                                "yaxis": {"fixedrange": True},
                                "colorway": ["#E12D39"],
                            },
                        },
                    ),
                    className="card",
                ),
            ],
            className="wrapper",
        ),
    ]
)

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

这是app.py的更新版本。它对代码进行了必要的更改,以添加收藏夹图标和页面标题,更新字体系列并使用外部CSS文件。完成这些更改后,仪表板应如下所示:

在下一部分中,您将学习如何向仪表板添加交互式组件。

Python 交互式数据可视化框架:Dash(上)

更多阅读

2020 年最佳流行 Python 库 Top 10

2020 Python中文社区热门文章 Top 10

5分钟快速掌握 Python 定时任务框架

特别推荐


点击下方阅读原文加入社区会员

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值