├── code
├── data
│ └── raw
│ │ └── AmazonBooks.xlsx
├── images
│ └── readme.md
├── st_simple_1.py
├── dash_simple_app_1.py
├── dash_simple_app_2.py
├── dash_html_gen.py
├── st_simple_2.py
├── st_simple_sidebar.py
├── dash_full_app.py
├── ch6-exercise-2.ipynb
├── ch6-exercise-1.ipynb
├── ch3-exercise-2.ipynb
└── ch3-exercise-3.ipynb
├── readme_resources
└── python-data-visualization.jpg
├── requirements.piptools
├── LICENSE
├── .gitignore
├── README.md
└── requirements.txt
/code/data/raw/AmazonBooks.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/talkpython/python-data-visualization/HEAD/code/data/raw/AmazonBooks.xlsx
--------------------------------------------------------------------------------
/readme_resources/python-data-visualization.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/talkpython/python-data-visualization/HEAD/readme_resources/python-data-visualization.jpg
--------------------------------------------------------------------------------
/code/images/readme.md:
--------------------------------------------------------------------------------
1 | ## Placeholder
2 |
3 | This file is here just so git will create the images folder. The notebooks may save output here and the folder must exist first.
4 |
--------------------------------------------------------------------------------
/code/st_simple_1.py:
--------------------------------------------------------------------------------
1 | from pathlib import Path
2 | import pandas as pd
3 | import streamlit as st
4 | import plotly.express as px
5 |
6 | src_file = Path.cwd() / "data" / "raw" / "EPA_fuel_economy_summary.csv"
7 | df = pd.read_csv(src_file)
8 |
9 | fig = px.histogram(
10 | df,
11 | x="fuelCost08",
12 | color="class_summary",
13 | labels={"fuelCost08": "Annual Fuel Cost"},
14 | nbins=40,
15 | title="Fuel Cost Distribution",
16 | )
17 |
18 | st.title("Simple Example")
19 | st.write(fig)
20 |
21 |
--------------------------------------------------------------------------------
/code/dash_simple_app_1.py:
--------------------------------------------------------------------------------
1 | from pathlib import Path
2 | import pandas as pd
3 | from dash import Dash, html, dcc
4 | import plotly.express as px
5 |
6 | app = Dash(__name__)
7 |
8 | src_file = Path.cwd() / "data" / "raw" / "EPA_fuel_economy_summary.csv"
9 | df = pd.read_csv(src_file)
10 |
11 | fig = px.histogram(
12 | df,
13 | x="fuelCost08",
14 | color="class_summary",
15 | labels={"fuelCost08": "Annual Fuel Cost"},
16 | nbins=40,
17 | title="Fuel Cost Distribution",
18 | )
19 |
20 | app.layout = html.Div(children=[
21 | html.H1("Simple Histogram"),
22 | html.Div("Annual Fuel Cost Plot."),
23 | dcc.Graph(id="example-histogram", figure=fig),
24 | ])
25 |
26 | if __name__ == "__main__":
27 | app.run_server(debug=True)
28 |
29 |
30 |
--------------------------------------------------------------------------------
/requirements.piptools:
--------------------------------------------------------------------------------
1 | # This file contains the top-level dependencies, without pinned versions, for this course.
2 | # It is used to create the working requirements.txt file with transitive dependencies and fixed versions.
3 | # You don't need to use this file or modify it, just install the dependencies for requirements.txt
4 | # But you can learn more here: https://pip-tools.readthedocs.io/en/latest/
5 | #
6 |
7 | # Chapter 3 dependencies
8 | jupyter
9 | jupyterlab
10 | pandas
11 | numpy
12 | matplotlib
13 | statsmodels
14 |
15 | # Chapter 4 dependencies
16 | # no additional libs
17 |
18 | # Chapter 5 dependencies
19 | seaborn
20 |
21 | # Chapter 6 dependencies
22 | altair
23 | altair_data_server
24 | altair_saver
25 | openpyxl
26 | vegafusion
27 | vegafusion-python-embed
28 | vl-convert-python
29 |
30 |
31 | # Chapter 7 dependencies
32 | plotly
33 | kaleido
34 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Talk Python
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/code/dash_simple_app_2.py:
--------------------------------------------------------------------------------
1 | from pathlib import Path
2 | import pandas as pd
3 |
4 | from dash import Dash, html, dcc, Input, Output
5 | import plotly.express as px
6 |
7 | app = Dash(__name__)
8 |
9 | src_file = Path.cwd() / "data" / "raw" / "EPA_fuel_economy_summary.csv"
10 | df = pd.read_csv(src_file)
11 | fuel_types = df["fuel_type_summary"].unique()
12 |
13 | app.layout = html.Div(
14 | children=[
15 | html.H1("Simple Histogram"),
16 | html.Div("Annual Fuel Cost Plot."),
17 | dcc.Graph(id="histogram"),
18 | dcc.Dropdown(
19 | id="fuel_id",
20 | options=[{"label": i, "value": i} for i in fuel_types],
21 | value=[i for i in fuel_types],
22 | multi=True,
23 | ),
24 | ]
25 | )
26 |
27 | @app.callback(Output("histogram", "figure"), Input("fuel_id", "value"))
28 | def update_output(fuel_list):
29 | filtered_df = df[df["fuel_type_summary"].isin(fuel_list)]
30 | fig = px.histogram(
31 | filtered_df,
32 | x="fuelCost08",
33 | color="class_summary",
34 | labels={"fuelCost08": "Annual Fuel Cost"},
35 | nbins=40,
36 | title="Fuel Cost Distribution",
37 | )
38 | return fig
39 |
40 | if __name__ == "__main__":
41 | app.run_server(debug=True)
42 |
43 |
44 |
--------------------------------------------------------------------------------
/code/dash_html_gen.py:
--------------------------------------------------------------------------------
1 | from dash import Dash, html, dcc
2 | import plotly.express as px
3 |
4 | external_stylesheets = ["https://codepen.io/chriddyp/pen/bWLwgP.css"]
5 | app = Dash(__name__, external_stylesheets=external_stylesheets)
6 |
7 | app.layout = html.Div(
8 | [
9 | html.H1("Simple HTML Only Site"),
10 | html.H2("TalkPython Training"),
11 | html.Div(
12 | [
13 | html.P("Annual Fuel Cost Plot",
14 | className="my-p-class",
15 | id="my-p-id")
16 | ],
17 | style={
18 | "color": "green",
19 | "fontSize": 18
20 | },
21 | ),
22 | dcc.Markdown("""
23 | #### Dash Supports Markdown
24 |
25 | You can write simple text and format it with markup like
26 | **bold text** and *italics*, [links](http://commonmark.org/help).
27 | You can also use:
28 | * lists
29 | * inline `code` snippets
30 | * and more
31 | """),
32 | ],
33 | style={
34 | "margin-left": "25px",
35 | "width": "55%",
36 | "backgroundColor": "lightgray"
37 | },
38 | )
39 |
40 |
41 | if __name__ == "__main__":
42 | app.run_server(debug=True)
43 |
44 |
45 |
--------------------------------------------------------------------------------
/code/st_simple_2.py:
--------------------------------------------------------------------------------
1 | from pathlib import Path
2 | import pandas as pd
3 | import streamlit as st
4 | import plotly.express as px
5 | import altair as alt
6 |
7 | @st.cache()
8 | def load_data():
9 | src_file = Path.cwd() / "data" / "raw" / "EPA_fuel_economy_summary.csv"
10 | raw_df = pd.read_csv(src_file)
11 | return raw_df
12 |
13 | # Load data and determine valid values
14 | df = load_data()
15 | min_year = int(df["year"].min())
16 | max_year = int(df["year"].max())
17 | valid_makes = sorted(df["make"].unique())
18 |
19 | # Setup the UI
20 | st.title("Simple Example")
21 | make = st.multiselect("Select a make:", valid_makes)
22 | year_range = st.slider(
23 | label="Year range",
24 | min_value=min_year,
25 | max_value=max_year,
26 | value=(min_year, max_year),
27 | )
28 |
29 | # Filter data based on inputs
30 | year_filter = df["year"].between(year_range[0], year_range[1])
31 | make_filter = df["make"].isin(make)
32 |
33 | plot_df = df[make_filter & year_filter]
34 |
35 | avg_fuel_economy = plot_df["fuelCost08"].mean().round(0)
36 | st.metric("Average", avg_fuel_economy)
37 |
38 | # Plot the data
39 | fig = px.histogram(
40 | plot_df,
41 | x="fuelCost08",
42 | color="class_summary",
43 | labels={"fuelCost08": "Annual Fuel Cost"},
44 | nbins=40,
45 | title="Fuel Cost Distribution",
46 | )
47 |
48 | altair_chart = (
49 | alt.Chart(plot_df).mark_tick().encode(y="fuel_type_summary", x="barrels08")
50 | )
51 |
52 | # Display the output results
53 | st.write(fig)
54 | st.write(altair_chart)
55 |
56 | st.write("Sample data", plot_df.head(10))
--------------------------------------------------------------------------------
/code/st_simple_sidebar.py:
--------------------------------------------------------------------------------
1 | from pathlib import Path
2 | import pandas as pd
3 | import streamlit as st
4 | import plotly.express as px
5 | import altair as alt
6 |
7 |
8 | @st.cache()
9 | def load_data():
10 | src_file = Path.cwd() / "data" / "raw" / "EPA_fuel_economy_summary.csv"
11 | raw_df = pd.read_csv(src_file)
12 | return raw_df
13 |
14 |
15 | # Load data and determine valid values
16 | df = load_data()
17 | min_year = int(df["year"].min())
18 | max_year = int(df["year"].max())
19 |
20 | # Add ALL as an option to make it easier to select all
21 | valid_makes = ["ALL"] + sorted(df["make"].unique())
22 |
23 | # Get the top 5 as the default
24 | default_makes = df["make"].value_counts().nlargest(5).index.tolist()
25 |
26 | # Setup the UI
27 | st.title("Simple Sidebar Example")
28 | make = st.sidebar.multiselect("Select a make:", valid_makes, default=default_makes)
29 | year_range = st.sidebar.slider(
30 | label="Year range",
31 | min_value=min_year,
32 | max_value=max_year,
33 | value=(min_year, max_year),
34 | )
35 |
36 | # Filter data based on inputs
37 | year_filter = df["year"].between(year_range[0], year_range[1])
38 | if "ALL" in make:
39 | # Dummy filter to include all makes
40 | make_filter = True
41 | else:
42 | make_filter = df["make"].isin(make)
43 |
44 | plot_df = df[make_filter & year_filter]
45 |
46 | avg_fuel_economy = plot_df["fuelCost08"].mean().round(0)
47 | st.sidebar.metric("Average", avg_fuel_economy)
48 |
49 | # Plot the data
50 | fig = px.histogram(
51 | plot_df,
52 | x="fuelCost08",
53 | color="class_summary",
54 | labels={"fuelCost08": "Annual Fuel Cost"},
55 | nbins=40,
56 | title="Fuel Cost Distribution",
57 | )
58 |
59 | altair_chart = (
60 | alt.Chart(plot_df)
61 | .mark_tick()
62 | .encode(y="fuel_type_summary", x="barrels08")
63 | .properties(width=600)
64 | )
65 |
66 | # Display the output results
67 | st.write(fig)
68 | st.write(altair_chart)
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Byte-compiled / optimized / DLL files
2 | __pycache__/
3 | *.py[cod]
4 | *$py.class
5 |
6 | # C extensions
7 | *.so
8 |
9 | # Distribution / packaging
10 | .Python
11 | build/
12 | develop-eggs/
13 | dist/
14 | downloads/
15 | eggs/
16 | .eggs/
17 | lib/
18 | lib64/
19 | parts/
20 | sdist/
21 | var/
22 | wheels/
23 | pip-wheel-metadata/
24 | share/python-wheels/
25 | *.egg-info/
26 | .installed.cfg
27 | *.egg
28 | MANIFEST
29 |
30 | # PyInstaller
31 | # Usually these files are written by a python script from a template
32 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
33 | *.manifest
34 | *.spec
35 |
36 | # Installer logs
37 | pip-log.txt
38 | pip-delete-this-directory.txt
39 |
40 | # Unit test / coverage reports
41 | htmlcov/
42 | .tox/
43 | .nox/
44 | .coverage
45 | .coverage.*
46 | .cache
47 | nosetests.xml
48 | coverage.xml
49 | *.cover
50 | *.py,cover
51 | .hypothesis/
52 | .pytest_cache/
53 |
54 | # Translations
55 | *.mo
56 | *.pot
57 |
58 | # Django stuff:
59 | *.log
60 | local_settings.py
61 | db.sqlite3
62 | db.sqlite3-journal
63 |
64 | # Flask stuff:
65 | instance/
66 | .webassets-cache
67 |
68 | # Scrapy stuff:
69 | .scrapy
70 |
71 | # Sphinx documentation
72 | docs/_build/
73 |
74 | # PyBuilder
75 | target/
76 |
77 | # Jupyter Notebook
78 | .ipynb_checkpoints
79 |
80 | # IPython
81 | profile_default/
82 | ipython_config.py
83 |
84 | # pyenv
85 | .python-version
86 |
87 | # pipenv
88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
91 | # install all needed dependencies.
92 | #Pipfile.lock
93 |
94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow
95 | __pypackages__/
96 |
97 | # Celery stuff
98 | celerybeat-schedule
99 | celerybeat.pid
100 |
101 | # SageMath parsed files
102 | *.sage.py
103 |
104 | # Environments
105 | .env
106 | .venv
107 | env/
108 | venv/
109 | ENV/
110 | env.bak/
111 | venv.bak/
112 |
113 | # Spyder project settings
114 | .spyderproject
115 | .spyproject
116 |
117 | # Rope project settings
118 | .ropeproject
119 |
120 | # mkdocs documentation
121 | /site
122 |
123 | # mypy
124 | .mypy_cache/
125 | .dmypy.json
126 | dmypy.json
127 |
128 | # Pyre type checker
129 | .pyre/
130 |
131 | # PyCharm projects
132 | .idea/
133 |
134 | # Ignore some of the output generated from the notebooks.
135 | code/images/*.png
136 | code/images/*.jpg
137 | code/images/*.svg
138 | code/images/*.pdf
139 | seaborn_heatmap.svg
140 | histogram.svg
141 | customization_example.svg
142 | plotlyhistogram.svg
143 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Python Data Visualization course
2 | Code and examples from our [**Python Data Visualization course**](https://training.talkpython.fm/courses/python-data-visualization).
3 |
4 | [](https://training.talkpython.fm/courses/python-data-visualization)
5 |
6 | Have you ever been confused by all the different python plotting libraries? Have you tried to make a "simple" plot and gotten stuck and been unable to move forward? Do you want to make sophisticated, interactive data visualizations in python? If you answer yes, to any of these questions, then this course is for you.
7 |
8 | ## What's this course about and how is it different?
9 |
10 | The python data visualization landscape has many different libraries. They are all powerful and useful but it can be confusing to determine what works best for you. This course is unique because you will learn about many of the most popular python visualization libraries. You will start by learning how to use each library to build simple visualizations. You will also explore more complex usage and identify the scenarios where each library shines.
11 |
12 | By the end of this course, you will have a basic working knowledge of how to visualize data in python using multiple libraries. You will also learn which library is best for you and your coding style. Along the way, you'll learn general visualization concepts to make your plots more effective.
13 |
14 | In addition to the overview material, we will cover some of the more complex, interactive visualization dashboard technologies.
15 |
16 | ## What topics are covered
17 |
18 | In this course, you will:
19 |
20 | - Review the python visualization landscape
21 | - Explore core visualization concepts
22 | - Use matplotlib to build and customize visualizations
23 | - Build and customize simple plots with pandas
24 | - Learn about seaborn and use it for statistical visualizations
25 | - Create visualizations using Altair
26 | - Generate interactive plots using the Plotly library
27 | - Design interactive dashboards using Streamlit
28 | - Construct highly custom and flexible dashboards using Plotly's Dash framework
29 |
30 | View the full [**course outline**](https://training.talkpython.fm/courses/python-data-visualization#course_outline).
31 |
32 | ## Who is this course for?
33 |
34 | Developers and Data Analysts that have some experience with python but have not developed a competency in a python visualization library. This course is also helpful for those that feel restricted by their current plotting tools and wish to explore other options.
35 |
36 | **Note**: All software used during this course, including editors, Python language, etc., are 100% free and open source. You won't have to buy anything to take the course.
37 |
38 | ## Take the course
39 |
40 | Data sciense is one of the hottest topic of the year and data visualization is a core skillset needed to properly communicate your results and discoveries. **Take this course** to get good at a wide variety of modern Python-based visualization libraries.
41 |
--------------------------------------------------------------------------------
/code/dash_full_app.py:
--------------------------------------------------------------------------------
1 | from pathlib import Path
2 | import pandas as pd
3 |
4 | from dash import Dash, html, dcc, Input, Output, dash_table
5 | import plotly.express as px
6 |
7 | external_stylesheets = ["https://codepen.io/chriddyp/pen/bWLwgP.css"]
8 | app = Dash(__name__, external_stylesheets=external_stylesheets)
9 |
10 | styles = {"pre": {"border": "thin lightgrey solid", "overflowX": "scroll"}}
11 |
12 | src_file = Path.cwd() / "data" / "raw" / "EPA_fuel_economy_summary.csv"
13 | df = pd.read_csv(src_file)
14 |
15 | # Define the input parameters
16 | min_year = df["year"].min()
17 | max_year = df["year"].max()
18 | all_years = df["year"].unique()
19 | transmission_types = df["transmission"].unique()
20 |
21 | data_table_cols = [
22 | "make",
23 | "model",
24 | "year",
25 | "transmission",
26 | "drive",
27 | "class_summary",
28 | "cylinders",
29 | "displ",
30 | "fuelCost08",
31 | ]
32 |
33 | # Need to keep track of button clicks to see if there is a change
34 | total_clicks = 0
35 |
36 | app.layout = html.Div(
37 | [
38 | html.H1("Fuel Cost Analysis"),
39 | html.Div([
40 | html.P("Talk Python Training Example"),
41 | dcc.Graph(id="histogram-with-slider",
42 | config={"displayModeBar": False}),
43 | dcc.Graph(id="scatter-plot"),
44 | html.Label("Year Range"),
45 | dcc.RangeSlider(
46 | id="year-slider",
47 | min=min_year,
48 | max=max_year,
49 | value=(min_year, max_year),
50 | marks={str(year): str(year)
51 | for year in all_years},
52 | ),
53 | html.Label("Transmission type"),
54 | dcc.Checklist(
55 | id="transmission-list",
56 | options=[{
57 | "label": i,
58 | "value": i
59 | } for i in transmission_types],
60 | value=transmission_types,
61 | labelStyle={"display": "inline-block"},
62 | ),
63 | html.Hr(),
64 | html.Button("Reset selections", id="reset", n_clicks=0),
65 | html.H3(id="selected_count"),
66 | dash_table.DataTable(
67 | id="data-table",
68 | data=[],
69 | page_size=10,
70 | columns=[{
71 | "name": i,
72 | "id": i
73 | } for i in data_table_cols],
74 | ),
75 | ]),
76 | ],
77 | style={"margin-bottom": "150px"},
78 | )
79 |
80 |
81 | @app.callback(
82 | Output("histogram-with-slider", "figure"),
83 | Output("scatter-plot", "figure"),
84 | Output("data-table", "data"),
85 | Output("selected_count", "children"),
86 | Input("year-slider", "value"),
87 | Input("transmission-list", "value"),
88 | Input("scatter-plot", "selectedData"),
89 | Input("reset", "n_clicks"),
90 | )
91 | def update_figure(year_range, transmission_list, selectedData, n_clicks):
92 | # Global variables may cause unexepcted behavior in multi-user setup
93 | global total_clicks
94 | filtered_df = df[df["year"].between(year_range[0], year_range[1])
95 | & df["transmission"].isin(transmission_list)]
96 |
97 | fig_hist = px.histogram(
98 | filtered_df,
99 | x="fuelCost08",
100 | color="class_summary",
101 | labels={"fuelCost08": "Annual Fuel Cost"},
102 | nbins=40,
103 | )
104 |
105 | fig_scatter = px.scatter(
106 | filtered_df,
107 | x="displ",
108 | y="fuelCost08",
109 | hover_data=[filtered_df.index, "make", "model", "year"],
110 | )
111 |
112 | fig_scatter.update_layout(clickmode="event", uirevision=True)
113 | fig_scatter.update_traces(selected_marker_color="red")
114 |
115 | if n_clicks > total_clicks:
116 | # From here - https://community.plotly.com/t/applying-only-newest-selectedpoints-in-multiple-graphs-or-clearing-selection/31881
117 | fig_scatter.update_traces(selected_marker_color=None)
118 | total_clicks = n_clicks
119 | selectedData = None
120 |
121 | if selectedData:
122 | points = selectedData["points"]
123 | index_list = [
124 | points[x]["customdata"][0] for x in range(0, len(points))
125 | ]
126 | filtered_df = df[df.index.isin(index_list)]
127 | num_points_label = f"Showing {len(points)} selected points:"
128 | else:
129 | num_points_label = "No points selected - showing top 10 only"
130 | filtered_df = filtered_df.head(10)
131 |
132 | return fig_hist, fig_scatter, filtered_df.to_dict(
133 | "records"), num_points_label
134 |
135 |
136 | if __name__ == "__main__":
137 | app.run_server(debug=True)
138 |
--------------------------------------------------------------------------------
/code/ch6-exercise-2.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "3cebc250",
6 | "metadata": {},
7 | "source": [
8 | "## Chapter 6 Altair Data Visualization\n",
9 | "Exercise 2"
10 | ]
11 | },
12 | {
13 | "cell_type": "code",
14 | "execution_count": null,
15 | "id": "909ae279",
16 | "metadata": {},
17 | "outputs": [],
18 | "source": [
19 | "from pathlib import Path\n",
20 | "import pandas as pd\n",
21 | "import numpy as np\n",
22 | "import altair as alt"
23 | ]
24 | },
25 | {
26 | "cell_type": "code",
27 | "execution_count": null,
28 | "id": "70efbb1c",
29 | "metadata": {},
30 | "outputs": [],
31 | "source": [
32 | "# data_server seems to have been removed but there doesn't\n",
33 | "# seem to be an announcement (or we missed it). \n",
34 | "# Moving to vegafusion will make it all sign again.\n",
35 | "\n",
36 | "# alt.data_transformers.enable('data_server')\n",
37 | "\n",
38 | "alt.data_transformers.enable('vegafusion')"
39 | ]
40 | },
41 | {
42 | "cell_type": "code",
43 | "execution_count": null,
44 | "id": "3c6745dd",
45 | "metadata": {},
46 | "outputs": [],
47 | "source": [
48 | "src_file = Path.cwd() / 'data' / 'raw' / 'EPA_fuel_economy_summary.csv'\n",
49 | "df = pd.read_csv(src_file)\n",
50 | "df.head()"
51 | ]
52 | },
53 | {
54 | "cell_type": "code",
55 | "execution_count": null,
56 | "id": "55cae40c",
57 | "metadata": {},
58 | "outputs": [],
59 | "source": [
60 | "alt.Chart(df).mark_circle(size=50).encode(\n",
61 | " x='displ',\n",
62 | " y='fuelCost08',\n",
63 | " tooltip=['make', 'model', 'year'],\n",
64 | ").interactive()"
65 | ]
66 | },
67 | {
68 | "cell_type": "code",
69 | "execution_count": null,
70 | "id": "38f2ceca",
71 | "metadata": {},
72 | "outputs": [],
73 | "source": [
74 | "chart1 = alt.Chart(df).mark_tick().encode(\n",
75 | " y='fuel_type_summary',\n",
76 | " x='barrels08'\n",
77 | ")\n",
78 | "chart2 = alt.Chart(df).mark_bar().encode(\n",
79 | " alt.X('barrels08:Q', bin=True),\n",
80 | " alt.Y('count()')\n",
81 | ")\n",
82 | "chart1 | chart2"
83 | ]
84 | },
85 | {
86 | "cell_type": "code",
87 | "execution_count": null,
88 | "id": "538830f6",
89 | "metadata": {},
90 | "outputs": [],
91 | "source": [
92 | "chart2 & chart1"
93 | ]
94 | },
95 | {
96 | "cell_type": "code",
97 | "execution_count": null,
98 | "id": "3bdfad56",
99 | "metadata": {},
100 | "outputs": [],
101 | "source": [
102 | "alt.hconcat(chart1, chart2)"
103 | ]
104 | },
105 | {
106 | "cell_type": "code",
107 | "execution_count": null,
108 | "id": "46778465",
109 | "metadata": {},
110 | "outputs": [],
111 | "source": [
112 | "alt.vconcat(chart1, chart2)"
113 | ]
114 | },
115 | {
116 | "cell_type": "code",
117 | "execution_count": null,
118 | "id": "98137673",
119 | "metadata": {},
120 | "outputs": [],
121 | "source": [
122 | "alt.Chart(df).mark_circle(size=50).encode(\n",
123 | " x='displ',\n",
124 | " y='fuelCost08',\n",
125 | " color='class_summary:N',\n",
126 | " tooltip=['make', 'model', 'year'],\n",
127 | ").facet(row='class_summary:N')"
128 | ]
129 | },
130 | {
131 | "cell_type": "code",
132 | "execution_count": null,
133 | "id": "d6c7f7dc",
134 | "metadata": {},
135 | "outputs": [],
136 | "source": [
137 | "alt.Chart(df).mark_circle(size=50).encode(\n",
138 | " x='displ',\n",
139 | " y='fuelCost08',\n",
140 | " color='class_summary:N',\n",
141 | " tooltip=['make', 'model', 'year'],\n",
142 | ").facet('class_summary:N', columns=2)"
143 | ]
144 | },
145 | {
146 | "cell_type": "code",
147 | "execution_count": null,
148 | "id": "071e7c16",
149 | "metadata": {},
150 | "outputs": [],
151 | "source": [
152 | "base_chart = alt.Chart(df).mark_circle(size=50).encode(\n",
153 | " x='displ',\n",
154 | " y='fuelCost08',\n",
155 | " color='class_summary:N',\n",
156 | " tooltip=['make', 'model', 'year'],\n",
157 | ")\n",
158 | "\n",
159 | "base_chart.facet('class_summary:N', columns=2)"
160 | ]
161 | },
162 | {
163 | "cell_type": "code",
164 | "execution_count": null,
165 | "id": "9b35b7e1",
166 | "metadata": {},
167 | "outputs": [],
168 | "source": [
169 | "bars = alt.Chart(df).mark_bar().encode(\n",
170 | " x='mean(fuelCost08):Q',\n",
171 | " y='year:O'\n",
172 | ")\n",
173 | "bars"
174 | ]
175 | },
176 | {
177 | "cell_type": "code",
178 | "execution_count": null,
179 | "id": "1ac960a3",
180 | "metadata": {},
181 | "outputs": [],
182 | "source": [
183 | "rule = alt.Chart(df).mark_rule(color='red').encode(\n",
184 | " x='mean(fuelCost08):Q'\n",
185 | ")\n",
186 | "bars + rule"
187 | ]
188 | },
189 | {
190 | "cell_type": "code",
191 | "execution_count": null,
192 | "id": "ab415527",
193 | "metadata": {},
194 | "outputs": [],
195 | "source": [
196 | "text = bars.mark_text(\n",
197 | " align='left', dx=3).encode(text=alt.Text('mean(fuelCost08):Q', format=',.0f'))\n",
198 | "(bars + rule + text)"
199 | ]
200 | },
201 | {
202 | "cell_type": "code",
203 | "execution_count": null,
204 | "id": "92297ff2",
205 | "metadata": {},
206 | "outputs": [],
207 | "source": [
208 | "(bars + rule + text).properties(width=700)"
209 | ]
210 | }
211 | ],
212 | "metadata": {
213 | "kernelspec": {
214 | "display_name": "Python 3 (ipykernel)",
215 | "language": "python",
216 | "name": "python3"
217 | },
218 | "language_info": {
219 | "codemirror_mode": {
220 | "name": "ipython",
221 | "version": 3
222 | },
223 | "file_extension": ".py",
224 | "mimetype": "text/x-python",
225 | "name": "python",
226 | "nbconvert_exporter": "python",
227 | "pygments_lexer": "ipython3",
228 | "version": "3.12.0"
229 | }
230 | },
231 | "nbformat": 4,
232 | "nbformat_minor": 5
233 | }
234 |
--------------------------------------------------------------------------------
/code/ch6-exercise-1.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "24828c85",
6 | "metadata": {},
7 | "source": [
8 | "## Chapter 6 Altair Data Visualization\n",
9 | "Exercise 1"
10 | ]
11 | },
12 | {
13 | "cell_type": "code",
14 | "execution_count": null,
15 | "id": "c44a7038",
16 | "metadata": {},
17 | "outputs": [],
18 | "source": [
19 | "from pathlib import Path\n",
20 | "import pandas as pd\n",
21 | "import numpy as np\n",
22 | "import altair as alt"
23 | ]
24 | },
25 | {
26 | "cell_type": "code",
27 | "execution_count": null,
28 | "id": "afa93459",
29 | "metadata": {},
30 | "outputs": [],
31 | "source": [
32 | "src_file = Path.cwd() / 'data' / 'raw' / 'EPA_fuel_economy_summary.csv'"
33 | ]
34 | },
35 | {
36 | "cell_type": "code",
37 | "execution_count": null,
38 | "id": "2190f191",
39 | "metadata": {},
40 | "outputs": [],
41 | "source": [
42 | "df = pd.read_csv(src_file)\n",
43 | "df.head()"
44 | ]
45 | },
46 | {
47 | "cell_type": "code",
48 | "execution_count": null,
49 | "id": "cbff6887",
50 | "metadata": {},
51 | "outputs": [],
52 | "source": [
53 | "alt.data_transformers.names()"
54 | ]
55 | },
56 | {
57 | "cell_type": "code",
58 | "execution_count": null,
59 | "id": "39e254bc",
60 | "metadata": {},
61 | "outputs": [],
62 | "source": [
63 | "# data_server seems to have been removed but there doesn't\n",
64 | "# seem to be an announcement (or we missed it). \n",
65 | "# Moving to vegafusion will make it all sign again.\n",
66 | "\n",
67 | "# alt.data_transformers.enable('data_server')\n",
68 | "\n",
69 | "alt.data_transformers.enable('vegafusion')"
70 | ]
71 | },
72 | {
73 | "cell_type": "code",
74 | "execution_count": null,
75 | "id": "9de36e98",
76 | "metadata": {},
77 | "outputs": [],
78 | "source": [
79 | "alt.Chart(df).mark_circle().encode(\n",
80 | " x='displ',\n",
81 | " y='fuelCost08',\n",
82 | ")"
83 | ]
84 | },
85 | {
86 | "cell_type": "code",
87 | "execution_count": null,
88 | "id": "59e5f555",
89 | "metadata": {},
90 | "outputs": [],
91 | "source": [
92 | "alt.Chart(df).mark_point().encode(\n",
93 | " x='displ',\n",
94 | " y='fuelCost08',\n",
95 | ")"
96 | ]
97 | },
98 | {
99 | "cell_type": "code",
100 | "execution_count": null,
101 | "id": "2209f687",
102 | "metadata": {},
103 | "outputs": [],
104 | "source": [
105 | "alt.Chart(df).mark_point().encode(\n",
106 | " x='displ',\n",
107 | " y='fuelCost08',\n",
108 | " color='drive',\n",
109 | " shape='drive',\n",
110 | ")"
111 | ]
112 | },
113 | {
114 | "cell_type": "code",
115 | "execution_count": null,
116 | "id": "a0410ea4",
117 | "metadata": {},
118 | "outputs": [],
119 | "source": [
120 | "alt.Chart(df).mark_bar().encode(\n",
121 | " x='fuelCost08',\n",
122 | " y='count()',\n",
123 | ")"
124 | ]
125 | },
126 | {
127 | "cell_type": "code",
128 | "execution_count": null,
129 | "id": "fe20ec30",
130 | "metadata": {},
131 | "outputs": [],
132 | "source": [
133 | "alt.Chart(df).mark_tick().encode(\n",
134 | " y='fuel_type_summary',\n",
135 | " x='barrels08'\n",
136 | ")"
137 | ]
138 | },
139 | {
140 | "cell_type": "code",
141 | "execution_count": null,
142 | "id": "67e239c2",
143 | "metadata": {},
144 | "outputs": [],
145 | "source": [
146 | "alt.Chart(df).mark_boxplot().encode(\n",
147 | " x='year',\n",
148 | " y='fuelCost08'\n",
149 | ")"
150 | ]
151 | },
152 | {
153 | "cell_type": "code",
154 | "execution_count": null,
155 | "id": "84d63b73",
156 | "metadata": {},
157 | "outputs": [],
158 | "source": [
159 | "alt.Chart(df).mark_boxplot().encode(\n",
160 | " x='year:O',\n",
161 | " y='fuelCost08:Q'\n",
162 | ")"
163 | ]
164 | },
165 | {
166 | "cell_type": "code",
167 | "execution_count": null,
168 | "id": "57c40450",
169 | "metadata": {},
170 | "outputs": [],
171 | "source": [
172 | "alt.Chart(df).mark_bar().encode(\n",
173 | " x='mean(fuelCost08)',\n",
174 | " y='year'\n",
175 | ")"
176 | ]
177 | },
178 | {
179 | "cell_type": "code",
180 | "execution_count": null,
181 | "id": "e345aa0f",
182 | "metadata": {},
183 | "outputs": [],
184 | "source": [
185 | "alt.Chart(df).mark_bar().encode(\n",
186 | " x='mean(fuelCost08)',\n",
187 | " y='year:O'\n",
188 | ")"
189 | ]
190 | },
191 | {
192 | "cell_type": "code",
193 | "execution_count": null,
194 | "id": "2b1de1b7",
195 | "metadata": {},
196 | "outputs": [],
197 | "source": [
198 | "alt.Chart(df).mark_bar().encode(\n",
199 | " x='fuelCost08',\n",
200 | " y='count()',\n",
201 | ")"
202 | ]
203 | },
204 | {
205 | "cell_type": "code",
206 | "execution_count": null,
207 | "id": "a656ef1b",
208 | "metadata": {},
209 | "outputs": [],
210 | "source": [
211 | "alt.Chart(df).mark_bar().encode(\n",
212 | " alt.X('fuelCost08', type='quantitative', bin=True),\n",
213 | " alt.Y(aggregate='count', type='quantitative'),\n",
214 | ")"
215 | ]
216 | },
217 | {
218 | "cell_type": "code",
219 | "execution_count": null,
220 | "id": "38989baa",
221 | "metadata": {},
222 | "outputs": [],
223 | "source": [
224 | "alt.Chart(df).mark_bar().encode(\n",
225 | " alt.X('fuelCost08:Q', bin=alt.Bin(extent=[0,5000], step=250)),\n",
226 | " alt.Y('count()'),\n",
227 | ")"
228 | ]
229 | },
230 | {
231 | "cell_type": "code",
232 | "execution_count": null,
233 | "id": "b149d438",
234 | "metadata": {},
235 | "outputs": [],
236 | "source": [
237 | "alt.Chart(df).mark_point().encode(\n",
238 | " alt.X('displ', type='quantitative'),\n",
239 | " alt.Y('fuelCost08'),\n",
240 | " alt.Color('cylinders', type='ordinal')\n",
241 | ")"
242 | ]
243 | },
244 | {
245 | "cell_type": "code",
246 | "execution_count": null,
247 | "id": "63a8b75d",
248 | "metadata": {},
249 | "outputs": [],
250 | "source": [
251 | "alt.Chart(df).mark_point().encode(\n",
252 | " alt.X('displ', type='quantitative'),\n",
253 | " alt.Y('fuelCost08'),\n",
254 | " alt.Color('cylinders', type='quantitative')\n",
255 | ")"
256 | ]
257 | },
258 | {
259 | "cell_type": "code",
260 | "execution_count": null,
261 | "id": "d21d2d2d",
262 | "metadata": {},
263 | "outputs": [],
264 | "source": [
265 | "alt.Chart(df).mark_point().encode(\n",
266 | " alt.X('displ', type='quantitative'),\n",
267 | " alt.Y('fuelCost08'),\n",
268 | " alt.Color('cylinders', type='nominal')\n",
269 | ")"
270 | ]
271 | }
272 | ],
273 | "metadata": {
274 | "kernelspec": {
275 | "display_name": "dataviz",
276 | "language": "python",
277 | "name": "dataviz"
278 | },
279 | "language_info": {
280 | "codemirror_mode": {
281 | "name": "ipython",
282 | "version": 3
283 | },
284 | "file_extension": ".py",
285 | "mimetype": "text/x-python",
286 | "name": "python",
287 | "nbconvert_exporter": "python",
288 | "pygments_lexer": "ipython3",
289 | "version": "3.12.0"
290 | }
291 | },
292 | "nbformat": 4,
293 | "nbformat_minor": 5
294 | }
295 |
--------------------------------------------------------------------------------
/code/ch3-exercise-2.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "90ec1037",
6 | "metadata": {},
7 | "source": [
8 | "### Chapter 3 Matplotlib Data Visualization\n",
9 | "\n",
10 | "Exercise 2"
11 | ]
12 | },
13 | {
14 | "cell_type": "code",
15 | "execution_count": null,
16 | "id": "cd0de61c",
17 | "metadata": {},
18 | "outputs": [],
19 | "source": [
20 | "from pathlib import Path\n",
21 | "import pandas as pd\n",
22 | "import numpy as np\n",
23 | "import matplotlib.pyplot as plt\n",
24 | "from matplotlib import ticker"
25 | ]
26 | },
27 | {
28 | "cell_type": "code",
29 | "execution_count": null,
30 | "id": "735b302c",
31 | "metadata": {},
32 | "outputs": [],
33 | "source": [
34 | "src_file = Path.cwd() / 'data' / 'raw' / 'EPA_fuel_economy.csv'\n",
35 | "image_dir = Path.cwd() / 'images'"
36 | ]
37 | },
38 | {
39 | "cell_type": "code",
40 | "execution_count": null,
41 | "id": "de1064cd",
42 | "metadata": {},
43 | "outputs": [],
44 | "source": [
45 | "df = pd.read_csv(src_file)"
46 | ]
47 | },
48 | {
49 | "cell_type": "code",
50 | "execution_count": null,
51 | "id": "5830f9e5",
52 | "metadata": {},
53 | "outputs": [],
54 | "source": [
55 | "df.head()"
56 | ]
57 | },
58 | {
59 | "cell_type": "markdown",
60 | "id": "4535ce51",
61 | "metadata": {},
62 | "source": [
63 | "## Additional Plot Types\n",
64 | "Going beyong the histogram and boxplot"
65 | ]
66 | },
67 | {
68 | "cell_type": "code",
69 | "execution_count": null,
70 | "id": "9f3e1b91",
71 | "metadata": {},
72 | "outputs": [],
73 | "source": [
74 | "avg_by_year = df.groupby(['year'], as_index=False).agg({'comb08': 'mean'}).round(2)\n",
75 | "avg_by_year"
76 | ]
77 | },
78 | {
79 | "cell_type": "code",
80 | "execution_count": null,
81 | "id": "c81563ac",
82 | "metadata": {},
83 | "outputs": [],
84 | "source": [
85 | "fig, ax1 = plt.subplots()\n",
86 | "ax1.plot(avg_by_year['year'], avg_by_year['comb08']);"
87 | ]
88 | },
89 | {
90 | "cell_type": "code",
91 | "execution_count": null,
92 | "id": "059234a4",
93 | "metadata": {},
94 | "outputs": [],
95 | "source": [
96 | "fig, ax1 = plt.subplots()\n",
97 | "ax1.plot(avg_by_year['year'], avg_by_year['comb08'])\n",
98 | "ax1.set_xticks(np.arange(2000, 2022, 2));"
99 | ]
100 | },
101 | {
102 | "cell_type": "code",
103 | "execution_count": null,
104 | "id": "f2f60ebb",
105 | "metadata": {},
106 | "outputs": [],
107 | "source": [
108 | "fig, ax1 = plt.subplots()\n",
109 | "ax1.plot(avg_by_year['year'], avg_by_year['comb08'])\n",
110 | "ax1.xaxis.set_major_formatter(ticker.StrMethodFormatter(\"{x:0.0f}\"));"
111 | ]
112 | },
113 | {
114 | "cell_type": "code",
115 | "execution_count": null,
116 | "id": "fb6b7a19",
117 | "metadata": {},
118 | "outputs": [],
119 | "source": [
120 | "fig, ax1 = plt.subplots()\n",
121 | "ax1.bar(avg_by_year['year'], avg_by_year['comb08']);"
122 | ]
123 | },
124 | {
125 | "cell_type": "code",
126 | "execution_count": null,
127 | "id": "682ac912",
128 | "metadata": {},
129 | "outputs": [],
130 | "source": [
131 | "fig, ax1 = plt.subplots()\n",
132 | "ax1.bar(avg_by_year['year'], avg_by_year['comb08'])\n",
133 | "ax1.set_xticks(np.arange(2000, 2022, 2));"
134 | ]
135 | },
136 | {
137 | "cell_type": "code",
138 | "execution_count": null,
139 | "id": "7194f9c0",
140 | "metadata": {},
141 | "outputs": [],
142 | "source": [
143 | "fig, ax1 = plt.subplots()\n",
144 | "ax1.barh(avg_by_year['year'], avg_by_year['comb08']);"
145 | ]
146 | },
147 | {
148 | "cell_type": "code",
149 | "execution_count": null,
150 | "id": "a49a7fba",
151 | "metadata": {},
152 | "outputs": [],
153 | "source": [
154 | "fig, ax1 = plt.subplots()\n",
155 | "ax1.scatter(x=df['fuelCost08'], y=df['displ'], alpha=0.5, c=df['cylinders'])\n",
156 | "ax1.set(xlabel='Fuel Cost ($)', ylabel='Displacement')"
157 | ]
158 | },
159 | {
160 | "cell_type": "code",
161 | "execution_count": null,
162 | "id": "0b814095",
163 | "metadata": {},
164 | "outputs": [],
165 | "source": [
166 | "fig, ax1 = plt.subplots(figsize=(9,7))\n",
167 | "ax1.scatter(x=df['fuelCost08'], y=df['displ'], alpha=0.5, c=df['cylinders'])\n",
168 | "ax1.set_xlabel('Fuel Cost', size=14)\n",
169 | "ax1.set_ylabel('Displacement', size=14)\n",
170 | "ax1.xaxis.set_major_formatter('${x:,.0f}')\n",
171 | "ax1.tick_params(axis='x', labelrotation=45, labelsize=14)\n",
172 | "ax1.tick_params(axis='y', labelsize=14)\n",
173 | "ax1.axvline(3500, color='black', linestyle=':')\n",
174 | "ax1.annotate('Target of $3500', xy=(3500,2), size=16)\n",
175 | "ax1.grid(True)"
176 | ]
177 | },
178 | {
179 | "cell_type": "markdown",
180 | "id": "cfc2e4ca",
181 | "metadata": {},
182 | "source": [
183 | "## Using Styles"
184 | ]
185 | },
186 | {
187 | "cell_type": "code",
188 | "execution_count": null,
189 | "id": "9375d640",
190 | "metadata": {},
191 | "outputs": [],
192 | "source": [
193 | "plt.style.available"
194 | ]
195 | },
196 | {
197 | "cell_type": "code",
198 | "execution_count": null,
199 | "id": "90b02bbc",
200 | "metadata": {},
201 | "outputs": [],
202 | "source": [
203 | "plt.style.use('ggplot')"
204 | ]
205 | },
206 | {
207 | "cell_type": "code",
208 | "execution_count": null,
209 | "id": "4b158548",
210 | "metadata": {},
211 | "outputs": [],
212 | "source": [
213 | "fig, ax1 = plt.subplots()\n",
214 | "ax1.scatter(x=df['fuelCost08'], y=df['displ'], alpha=0.5, c=df['cylinders'])\n",
215 | "ax1.set(xlabel='Fuel Cost ($)', ylabel='Displacement')"
216 | ]
217 | },
218 | {
219 | "cell_type": "code",
220 | "execution_count": null,
221 | "id": "34968e08",
222 | "metadata": {},
223 | "outputs": [],
224 | "source": [
225 | "from matplotlib import style\n",
226 | "\n",
227 | "print(plt.style.available)"
228 | ]
229 | },
230 | {
231 | "cell_type": "code",
232 | "execution_count": null,
233 | "id": "92f287e1",
234 | "metadata": {},
235 | "outputs": [],
236 | "source": [
237 | "# Note, styles seaborn, seaborn-dark have been renamed to seaborn-v0_8, seaborn-v0_8-dark.\n",
238 | "# Hence the code change below.\n",
239 | "\n",
240 | "for style in ['Solarize_Light2', 'bmh', 'ggplot', 'fivethirtyeight', 'seaborn-v0_8', 'seaborn-v0_8-dark']:\n",
241 | " with plt.style.context(style):\n",
242 | " fig, ax1 = plt.subplots()\n",
243 | " ax1.scatter(x=df['fuelCost08'], y=df['displ'], alpha=0.5, c=df['cylinders'])\n",
244 | " ax1.set(title = f'style - {style}', xlabel='Fuel Cost ($)', ylabel='Displacement')"
245 | ]
246 | }
247 | ],
248 | "metadata": {
249 | "kernelspec": {
250 | "display_name": "Python 3 (ipykernel)",
251 | "language": "python",
252 | "name": "python3"
253 | },
254 | "language_info": {
255 | "codemirror_mode": {
256 | "name": "ipython",
257 | "version": 3
258 | },
259 | "file_extension": ".py",
260 | "mimetype": "text/x-python",
261 | "name": "python",
262 | "nbconvert_exporter": "python",
263 | "pygments_lexer": "ipython3",
264 | "version": "3.11.6"
265 | }
266 | },
267 | "nbformat": 4,
268 | "nbformat_minor": 5
269 | }
270 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | #
2 | # This file is autogenerated by pip-compile with Python 3.12
3 | # by the following command:
4 | #
5 | # pip-compile requirements.piptools
6 | #
7 | altair==5.2.0
8 | # via
9 | # -r requirements.piptools
10 | # altair-data-server
11 | # altair-saver
12 | # altair-viewer
13 | # vegafusion
14 | altair-data-server==0.4.1
15 | # via
16 | # -r requirements.piptools
17 | # altair-saver
18 | # altair-viewer
19 | altair-saver==0.5.0
20 | # via -r requirements.piptools
21 | altair-viewer==0.4.0
22 | # via altair-saver
23 | anyio==4.1.0
24 | # via jupyter-server
25 | appnope==0.1.3
26 | # via ipykernel
27 | argon2-cffi==23.1.0
28 | # via jupyter-server
29 | argon2-cffi-bindings==21.2.0
30 | # via argon2-cffi
31 | arrow==1.3.0
32 | # via isoduration
33 | asttokens==2.4.1
34 | # via stack-data
35 | async-lru==2.0.4
36 | # via jupyterlab
37 | attrs==23.1.0
38 | # via
39 | # jsonschema
40 | # outcome
41 | # referencing
42 | # trio
43 | babel==2.13.1
44 | # via jupyterlab-server
45 | beautifulsoup4==4.12.2
46 | # via nbconvert
47 | bleach==6.1.0
48 | # via nbconvert
49 | certifi==2023.11.17
50 | # via
51 | # requests
52 | # selenium
53 | cffi==1.16.0
54 | # via argon2-cffi-bindings
55 | charset-normalizer==3.3.2
56 | # via requests
57 | comm==0.2.0
58 | # via
59 | # ipykernel
60 | # ipywidgets
61 | contourpy==1.2.0
62 | # via matplotlib
63 | cycler==0.12.1
64 | # via matplotlib
65 | debugpy==1.8.0
66 | # via ipykernel
67 | decorator==5.1.1
68 | # via ipython
69 | defusedxml==0.7.1
70 | # via nbconvert
71 | et-xmlfile==1.1.0
72 | # via openpyxl
73 | executing==2.0.1
74 | # via stack-data
75 | fastjsonschema==2.19.0
76 | # via nbformat
77 | fonttools==4.46.0
78 | # via matplotlib
79 | fqdn==1.5.1
80 | # via jsonschema
81 | h11==0.14.0
82 | # via wsproto
83 | idna==3.6
84 | # via
85 | # anyio
86 | # jsonschema
87 | # requests
88 | # trio
89 | ipykernel==6.27.1
90 | # via
91 | # jupyter
92 | # jupyter-console
93 | # jupyterlab
94 | # qtconsole
95 | ipython==8.18.1
96 | # via
97 | # ipykernel
98 | # ipywidgets
99 | # jupyter-console
100 | ipywidgets==8.1.1
101 | # via jupyter
102 | isoduration==20.11.0
103 | # via jsonschema
104 | jedi==0.19.1
105 | # via ipython
106 | jinja2==3.1.2
107 | # via
108 | # altair
109 | # jupyter-server
110 | # jupyterlab
111 | # jupyterlab-server
112 | # nbconvert
113 | json5==0.9.14
114 | # via jupyterlab-server
115 | jsonpointer==2.4
116 | # via jsonschema
117 | jsonschema[format-nongpl]==4.20.0
118 | # via
119 | # altair
120 | # jupyter-events
121 | # jupyterlab-server
122 | # nbformat
123 | jsonschema-specifications==2023.11.2
124 | # via jsonschema
125 | jupyter==1.0.0
126 | # via -r requirements.piptools
127 | jupyter-client==8.6.0
128 | # via
129 | # ipykernel
130 | # jupyter-console
131 | # jupyter-server
132 | # nbclient
133 | # qtconsole
134 | jupyter-console==6.6.3
135 | # via jupyter
136 | jupyter-core==5.5.0
137 | # via
138 | # ipykernel
139 | # jupyter-client
140 | # jupyter-console
141 | # jupyter-server
142 | # jupyterlab
143 | # nbclient
144 | # nbconvert
145 | # nbformat
146 | # qtconsole
147 | jupyter-events==0.9.0
148 | # via jupyter-server
149 | jupyter-lsp==2.2.1
150 | # via jupyterlab
151 | jupyter-server==2.11.1
152 | # via
153 | # jupyter-lsp
154 | # jupyterlab
155 | # jupyterlab-server
156 | # notebook
157 | # notebook-shim
158 | jupyter-server-terminals==0.4.4
159 | # via jupyter-server
160 | jupyterlab==4.0.9
161 | # via
162 | # -r requirements.piptools
163 | # notebook
164 | jupyterlab-pygments==0.3.0
165 | # via nbconvert
166 | jupyterlab-server==2.25.2
167 | # via
168 | # jupyterlab
169 | # notebook
170 | jupyterlab-widgets==3.0.9
171 | # via ipywidgets
172 | kaleido==0.2.1
173 | # via -r requirements.piptools
174 | kiwisolver==1.4.5
175 | # via matplotlib
176 | markupsafe==2.1.3
177 | # via
178 | # jinja2
179 | # nbconvert
180 | matplotlib==3.8.2
181 | # via
182 | # -r requirements.piptools
183 | # seaborn
184 | matplotlib-inline==0.1.6
185 | # via
186 | # ipykernel
187 | # ipython
188 | mistune==3.0.2
189 | # via nbconvert
190 | nbclient==0.9.0
191 | # via nbconvert
192 | nbconvert==7.11.0
193 | # via
194 | # jupyter
195 | # jupyter-server
196 | nbformat==5.9.2
197 | # via
198 | # jupyter-server
199 | # nbclient
200 | # nbconvert
201 | nest-asyncio==1.5.8
202 | # via ipykernel
203 | notebook==7.0.6
204 | # via jupyter
205 | notebook-shim==0.2.3
206 | # via
207 | # jupyterlab
208 | # notebook
209 | numpy==1.26.2
210 | # via
211 | # -r requirements.piptools
212 | # altair
213 | # contourpy
214 | # matplotlib
215 | # pandas
216 | # patsy
217 | # pyarrow
218 | # scipy
219 | # seaborn
220 | # statsmodels
221 | openpyxl==3.1.2
222 | # via -r requirements.piptools
223 | outcome==1.3.0.post0
224 | # via trio
225 | overrides==7.4.0
226 | # via jupyter-server
227 | packaging==23.2
228 | # via
229 | # altair
230 | # ipykernel
231 | # jupyter-server
232 | # jupyterlab
233 | # jupyterlab-server
234 | # matplotlib
235 | # nbconvert
236 | # plotly
237 | # qtconsole
238 | # qtpy
239 | # statsmodels
240 | pandas==2.1.3
241 | # via
242 | # -r requirements.piptools
243 | # altair
244 | # seaborn
245 | # statsmodels
246 | # vegafusion
247 | pandocfilters==1.5.0
248 | # via nbconvert
249 | parso==0.8.3
250 | # via jedi
251 | patsy==0.5.4
252 | # via statsmodels
253 | pexpect==4.9.0
254 | # via ipython
255 | pillow==10.1.0
256 | # via matplotlib
257 | platformdirs==4.0.0
258 | # via jupyter-core
259 | plotly==5.18.0
260 | # via -r requirements.piptools
261 | portpicker==1.6.0
262 | # via altair-data-server
263 | prometheus-client==0.19.0
264 | # via jupyter-server
265 | prompt-toolkit==3.0.41
266 | # via
267 | # ipython
268 | # jupyter-console
269 | protobuf==4.25.1
270 | # via vegafusion
271 | psutil==5.9.6
272 | # via
273 | # ipykernel
274 | # portpicker
275 | # vegafusion
276 | ptyprocess==0.7.0
277 | # via
278 | # pexpect
279 | # terminado
280 | pure-eval==0.2.2
281 | # via stack-data
282 | pyarrow==14.0.1
283 | # via vegafusion
284 | pycparser==2.21
285 | # via cffi
286 | pygments==2.17.2
287 | # via
288 | # ipython
289 | # jupyter-console
290 | # nbconvert
291 | # qtconsole
292 | pyparsing==3.1.1
293 | # via matplotlib
294 | pysocks==1.7.1
295 | # via urllib3
296 | python-dateutil==2.8.2
297 | # via
298 | # arrow
299 | # jupyter-client
300 | # matplotlib
301 | # pandas
302 | python-json-logger==2.0.7
303 | # via jupyter-events
304 | pytz==2023.3.post1
305 | # via pandas
306 | pyyaml==6.0.1
307 | # via jupyter-events
308 | pyzmq==25.1.1
309 | # via
310 | # ipykernel
311 | # jupyter-client
312 | # jupyter-console
313 | # jupyter-server
314 | # qtconsole
315 | qtconsole==5.5.1
316 | # via jupyter
317 | qtpy==2.4.1
318 | # via qtconsole
319 | referencing==0.31.1
320 | # via
321 | # jsonschema
322 | # jsonschema-specifications
323 | # jupyter-events
324 | requests==2.31.0
325 | # via jupyterlab-server
326 | rfc3339-validator==0.1.4
327 | # via
328 | # jsonschema
329 | # jupyter-events
330 | rfc3986-validator==0.1.1
331 | # via
332 | # jsonschema
333 | # jupyter-events
334 | rpds-py==0.13.2
335 | # via
336 | # jsonschema
337 | # referencing
338 | scipy==1.11.4
339 | # via statsmodels
340 | seaborn==0.13.0
341 | # via -r requirements.piptools
342 | selenium==4.15.2
343 | # via altair-saver
344 | send2trash==1.8.2
345 | # via jupyter-server
346 | six==1.16.0
347 | # via
348 | # asttokens
349 | # bleach
350 | # patsy
351 | # python-dateutil
352 | # rfc3339-validator
353 | sniffio==1.3.0
354 | # via
355 | # anyio
356 | # trio
357 | sortedcontainers==2.4.0
358 | # via trio
359 | soupsieve==2.5
360 | # via beautifulsoup4
361 | stack-data==0.6.3
362 | # via ipython
363 | statsmodels==0.14.0
364 | # via -r requirements.piptools
365 | tenacity==8.2.3
366 | # via plotly
367 | terminado==0.18.0
368 | # via
369 | # jupyter-server
370 | # jupyter-server-terminals
371 | tinycss2==1.2.1
372 | # via nbconvert
373 | toolz==0.12.0
374 | # via altair
375 | tornado==6.4
376 | # via
377 | # altair-data-server
378 | # ipykernel
379 | # jupyter-client
380 | # jupyter-server
381 | # jupyterlab
382 | # notebook
383 | # terminado
384 | traitlets==5.14.0
385 | # via
386 | # comm
387 | # ipykernel
388 | # ipython
389 | # ipywidgets
390 | # jupyter-client
391 | # jupyter-console
392 | # jupyter-core
393 | # jupyter-events
394 | # jupyter-server
395 | # jupyterlab
396 | # matplotlib-inline
397 | # nbclient
398 | # nbconvert
399 | # nbformat
400 | # qtconsole
401 | trio==0.23.1
402 | # via
403 | # selenium
404 | # trio-websocket
405 | trio-websocket==0.11.1
406 | # via selenium
407 | types-python-dateutil==2.8.19.14
408 | # via arrow
409 | tzdata==2023.3
410 | # via pandas
411 | uri-template==1.3.0
412 | # via jsonschema
413 | urllib3[socks]==2.1.0
414 | # via
415 | # requests
416 | # selenium
417 | # urllib3
418 | vegafusion==1.4.5
419 | # via -r requirements.piptools
420 | vegafusion-python-embed==1.4.5
421 | # via -r requirements.piptools
422 | vl-convert-python==1.2.0
423 | # via -r requirements.piptools
424 | wcwidth==0.2.12
425 | # via prompt-toolkit
426 | webcolors==1.13
427 | # via jsonschema
428 | webencodings==0.5.1
429 | # via
430 | # bleach
431 | # tinycss2
432 | websocket-client==1.6.4
433 | # via jupyter-server
434 | widgetsnbextension==4.0.9
435 | # via ipywidgets
436 | wsproto==1.2.0
437 | # via trio-websocket
438 |
439 | # The following packages are considered to be unsafe in a requirements file:
440 | # setuptools
441 |
--------------------------------------------------------------------------------
/code/ch3-exercise-3.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "id": "2659304d",
6 | "metadata": {},
7 | "source": [
8 | "### Chapter 3 Matplotlib Data Visualization\n",
9 | "\n",
10 | "Exercise 3"
11 | ]
12 | },
13 | {
14 | "cell_type": "code",
15 | "execution_count": 1,
16 | "id": "8be87053",
17 | "metadata": {},
18 | "outputs": [],
19 | "source": [
20 | "from pathlib import Path\n",
21 | "import pandas as pd\n",
22 | "import numpy as np\n",
23 | "import matplotlib.pyplot as plt\n",
24 | "import matplotlib as mpl\n",
25 | "from matplotlib import ticker\n",
26 | "import statsmodels.formula.api as smf"
27 | ]
28 | },
29 | {
30 | "cell_type": "code",
31 | "execution_count": 2,
32 | "id": "7672c4e6",
33 | "metadata": {},
34 | "outputs": [],
35 | "source": [
36 | "src_file = Path.cwd() / 'data' / 'raw' / 'EPA_fuel_economy.csv'\n",
37 | "image_dir = Path.cwd() / 'images'"
38 | ]
39 | },
40 | {
41 | "cell_type": "code",
42 | "execution_count": 3,
43 | "id": "bd06540b",
44 | "metadata": {},
45 | "outputs": [],
46 | "source": [
47 | "df = pd.read_csv(src_file)"
48 | ]
49 | },
50 | {
51 | "cell_type": "code",
52 | "execution_count": 4,
53 | "id": "fe1c5dec",
54 | "metadata": {},
55 | "outputs": [
56 | {
57 | "data": {
58 | "text/html": [
59 | "
\n",
60 | "\n",
73 | "
\n",
74 | " \n",
75 | " \n",
76 | " | \n",
77 | " make | \n",
78 | " model | \n",
79 | " year | \n",
80 | " cylinders | \n",
81 | " trany | \n",
82 | " displ | \n",
83 | " VClass | \n",
84 | " co2 | \n",
85 | " barrels08 | \n",
86 | " fuelCost08 | \n",
87 | " fuelType | \n",
88 | " highway08 | \n",
89 | " city08 | \n",
90 | " comb08 | \n",
91 | "
\n",
92 | " \n",
93 | " \n",
94 | " \n",
95 | " | 0 | \n",
96 | " Acura | \n",
97 | " NSX | \n",
98 | " 2000 | \n",
99 | " 6.0 | \n",
100 | " Automatic 4-spd | \n",
101 | " 3.0 | \n",
102 | " Two Seaters | \n",
103 | " -1 | \n",
104 | " 18.311667 | \n",
105 | " 2600 | \n",
106 | " Premium | \n",
107 | " 22 | \n",
108 | " 15 | \n",
109 | " 18 | \n",
110 | "
\n",
111 | " \n",
112 | " | 1 | \n",
113 | " Acura | \n",
114 | " NSX | \n",
115 | " 2000 | \n",
116 | " 6.0 | \n",
117 | " Manual 6-spd | \n",
118 | " 3.2 | \n",
119 | " Two Seaters | \n",
120 | " -1 | \n",
121 | " 18.311667 | \n",
122 | " 2600 | \n",
123 | " Premium | \n",
124 | " 22 | \n",
125 | " 15 | \n",
126 | " 18 | \n",
127 | "
\n",
128 | " \n",
129 | " | 2 | \n",
130 | " BMW | \n",
131 | " M Coupe | \n",
132 | " 2000 | \n",
133 | " 6.0 | \n",
134 | " Manual 5-spd | \n",
135 | " 3.2 | \n",
136 | " Two Seaters | \n",
137 | " -1 | \n",
138 | " 17.347895 | \n",
139 | " 2500 | \n",
140 | " Premium | \n",
141 | " 23 | \n",
142 | " 17 | \n",
143 | " 19 | \n",
144 | "
\n",
145 | " \n",
146 | " | 3 | \n",
147 | " BMW | \n",
148 | " Z3 Coupe | \n",
149 | " 2000 | \n",
150 | " 6.0 | \n",
151 | " Automatic 4-spd | \n",
152 | " 2.8 | \n",
153 | " Two Seaters | \n",
154 | " -1 | \n",
155 | " 17.347895 | \n",
156 | " 2500 | \n",
157 | " Premium | \n",
158 | " 24 | \n",
159 | " 17 | \n",
160 | " 19 | \n",
161 | "
\n",
162 | " \n",
163 | " | 4 | \n",
164 | " BMW | \n",
165 | " Z3 Coupe | \n",
166 | " 2000 | \n",
167 | " 6.0 | \n",
168 | " Manual 5-spd | \n",
169 | " 2.8 | \n",
170 | " Two Seaters | \n",
171 | " -1 | \n",
172 | " 17.347895 | \n",
173 | " 2500 | \n",
174 | " Premium | \n",
175 | " 24 | \n",
176 | " 17 | \n",
177 | " 19 | \n",
178 | "
\n",
179 | " \n",
180 | "
\n",
181 | "
"
182 | ],
183 | "text/plain": [
184 | " make model year cylinders trany displ VClass co2 \\\n",
185 | "0 Acura NSX 2000 6.0 Automatic 4-spd 3.0 Two Seaters -1 \n",
186 | "1 Acura NSX 2000 6.0 Manual 6-spd 3.2 Two Seaters -1 \n",
187 | "2 BMW M Coupe 2000 6.0 Manual 5-spd 3.2 Two Seaters -1 \n",
188 | "3 BMW Z3 Coupe 2000 6.0 Automatic 4-spd 2.8 Two Seaters -1 \n",
189 | "4 BMW Z3 Coupe 2000 6.0 Manual 5-spd 2.8 Two Seaters -1 \n",
190 | "\n",
191 | " barrels08 fuelCost08 fuelType highway08 city08 comb08 \n",
192 | "0 18.311667 2600 Premium 22 15 18 \n",
193 | "1 18.311667 2600 Premium 22 15 18 \n",
194 | "2 17.347895 2500 Premium 23 17 19 \n",
195 | "3 17.347895 2500 Premium 24 17 19 \n",
196 | "4 17.347895 2500 Premium 24 17 19 "
197 | ]
198 | },
199 | "execution_count": 4,
200 | "metadata": {},
201 | "output_type": "execute_result"
202 | }
203 | ],
204 | "source": [
205 | "df.head()"
206 | ]
207 | },
208 | {
209 | "cell_type": "code",
210 | "execution_count": 5,
211 | "id": "d0b63dde",
212 | "metadata": {},
213 | "outputs": [],
214 | "source": [
215 | "%matplotlib inline"
216 | ]
217 | },
218 | {
219 | "cell_type": "code",
220 | "execution_count": 6,
221 | "id": "01181bed",
222 | "metadata": {},
223 | "outputs": [
224 | {
225 | "data": {
226 | "text/html": [
227 | "\n",
228 | "\n",
241 | "
\n",
242 | " \n",
243 | " \n",
244 | " | \n",
245 | " year | \n",
246 | " fuelCost08 | \n",
247 | "
\n",
248 | " \n",
249 | " \n",
250 | " \n",
251 | " | 0 | \n",
252 | " 2000 | \n",
253 | " 2184.94 | \n",
254 | "
\n",
255 | " \n",
256 | " | 1 | \n",
257 | " 2001 | \n",
258 | " 2201.48 | \n",
259 | "
\n",
260 | " \n",
261 | " | 2 | \n",
262 | " 2002 | \n",
263 | " 2229.38 | \n",
264 | "
\n",
265 | " \n",
266 | " | 3 | \n",
267 | " 2003 | \n",
268 | " 2273.99 | \n",
269 | "
\n",
270 | " \n",
271 | " | 4 | \n",
272 | " 2004 | \n",
273 | " 2264.57 | \n",
274 | "
\n",
275 | " \n",
276 | " | 5 | \n",
277 | " 2005 | \n",
278 | " 2271.01 | \n",
279 | "
\n",
280 | " \n",
281 | " | 6 | \n",
282 | " 2006 | \n",
283 | " 2287.00 | \n",
284 | "
\n",
285 | " \n",
286 | " | 7 | \n",
287 | " 2007 | \n",
288 | " 2284.15 | \n",
289 | "
\n",
290 | " \n",
291 | " | 8 | \n",
292 | " 2008 | \n",
293 | " 2285.68 | \n",
294 | "
\n",
295 | " \n",
296 | " | 9 | \n",
297 | " 2009 | \n",
298 | " 2183.23 | \n",
299 | "
\n",
300 | " \n",
301 | " | 10 | \n",
302 | " 2010 | \n",
303 | " 2116.50 | \n",
304 | "
\n",
305 | " \n",
306 | " | 11 | \n",
307 | " 2011 | \n",
308 | " 2103.86 | \n",
309 | "
\n",
310 | " \n",
311 | " | 12 | \n",
312 | " 2012 | \n",
313 | " 2066.26 | \n",
314 | "
\n",
315 | " \n",
316 | " | 13 | \n",
317 | " 2013 | \n",
318 | " 1996.78 | \n",
319 | "
\n",
320 | " \n",
321 | " | 14 | \n",
322 | " 2014 | \n",
323 | " 1987.84 | \n",
324 | "
\n",
325 | " \n",
326 | " | 15 | \n",
327 | " 2015 | \n",
328 | " 1943.05 | \n",
329 | "
\n",
330 | " \n",
331 | " | 16 | \n",
332 | " 2016 | \n",
333 | " 1894.37 | \n",
334 | "
\n",
335 | " \n",
336 | " | 17 | \n",
337 | " 2017 | \n",
338 | " 1894.86 | \n",
339 | "
\n",
340 | " \n",
341 | " | 18 | \n",
342 | " 2018 | \n",
343 | " 1905.42 | \n",
344 | "
\n",
345 | " \n",
346 | " | 19 | \n",
347 | " 2019 | \n",
348 | " 1900.22 | \n",
349 | "
\n",
350 | " \n",
351 | " | 20 | \n",
352 | " 2020 | \n",
353 | " 1920.10 | \n",
354 | "
\n",
355 | " \n",
356 | "
\n",
357 | "
"
358 | ],
359 | "text/plain": [
360 | " year fuelCost08\n",
361 | "0 2000 2184.94\n",
362 | "1 2001 2201.48\n",
363 | "2 2002 2229.38\n",
364 | "3 2003 2273.99\n",
365 | "4 2004 2264.57\n",
366 | "5 2005 2271.01\n",
367 | "6 2006 2287.00\n",
368 | "7 2007 2284.15\n",
369 | "8 2008 2285.68\n",
370 | "9 2009 2183.23\n",
371 | "10 2010 2116.50\n",
372 | "11 2011 2103.86\n",
373 | "12 2012 2066.26\n",
374 | "13 2013 1996.78\n",
375 | "14 2014 1987.84\n",
376 | "15 2015 1943.05\n",
377 | "16 2016 1894.37\n",
378 | "17 2017 1894.86\n",
379 | "18 2018 1905.42\n",
380 | "19 2019 1900.22\n",
381 | "20 2020 1920.10"
382 | ]
383 | },
384 | "execution_count": 6,
385 | "metadata": {},
386 | "output_type": "execute_result"
387 | }
388 | ],
389 | "source": [
390 | "avg_by_year = df.groupby(['year'], as_index=False).agg({'fuelCost08': 'mean'}).round(2)\n",
391 | "avg_by_year"
392 | ]
393 | },
394 | {
395 | "cell_type": "code",
396 | "execution_count": 7,
397 | "id": "02d213d7",
398 | "metadata": {},
399 | "outputs": [],
400 | "source": [
401 | "mpg_model = smf.ols(\"fuelCost08 ~ year\", data=avg_by_year).fit()"
402 | ]
403 | },
404 | {
405 | "cell_type": "code",
406 | "execution_count": 8,
407 | "id": "343ec311",
408 | "metadata": {},
409 | "outputs": [
410 | {
411 | "data": {
412 | "text/plain": [
413 | "0 2325.850476\n",
414 | "1 2303.716333\n",
415 | "2 2281.582190\n",
416 | "3 2259.448048\n",
417 | "4 2237.313905\n",
418 | "5 2215.179762\n",
419 | "6 2193.045619\n",
420 | "7 2170.911476\n",
421 | "8 2148.777333\n",
422 | "9 2126.643190\n",
423 | "10 2104.509048\n",
424 | "11 2082.374905\n",
425 | "12 2060.240762\n",
426 | "13 2038.106619\n",
427 | "14 2015.972476\n",
428 | "15 1993.838333\n",
429 | "16 1971.704190\n",
430 | "17 1949.570048\n",
431 | "18 1927.435905\n",
432 | "19 1905.301762\n",
433 | "20 1883.167619\n",
434 | "dtype: float64"
435 | ]
436 | },
437 | "execution_count": 8,
438 | "metadata": {},
439 | "output_type": "execute_result"
440 | }
441 | ],
442 | "source": [
443 | "mpg_model.fittedvalues"
444 | ]
445 | },
446 | {
447 | "cell_type": "code",
448 | "execution_count": 9,
449 | "id": "8bf69ac9",
450 | "metadata": {},
451 | "outputs": [
452 | {
453 | "data": {
454 | "text/html": [
455 | "\n",
456 | "OLS Regression Results\n",
457 | "\n",
458 | " | Dep. Variable: | fuelCost08 | R-squared: | 0.795 | \n",
459 | "
\n",
460 | "\n",
461 | " | Model: | OLS | Adj. R-squared: | 0.784 | \n",
462 | "
\n",
463 | "\n",
464 | " | Method: | Least Squares | F-statistic: | 73.69 | \n",
465 | "
\n",
466 | "\n",
467 | " | Date: | Sat, 09 Oct 2021 | Prob (F-statistic): | 5.79e-08 | \n",
468 | "
\n",
469 | "\n",
470 | " | Time: | 11:20:05 | Log-Likelihood: | -118.43 | \n",
471 | "
\n",
472 | "\n",
473 | " | No. Observations: | 21 | AIC: | 240.9 | \n",
474 | "
\n",
475 | "\n",
476 | " | Df Residuals: | 19 | BIC: | 242.9 | \n",
477 | "
\n",
478 | "\n",
479 | " | Df Model: | 1 | | | \n",
480 | "
\n",
481 | "\n",
482 | " | Covariance Type: | nonrobust | | | \n",
483 | "
\n",
484 | "
\n",
485 | "\n",
486 | "\n",
487 | " | coef | std err | t | P>|t| | [0.025 | 0.975] | \n",
488 | "
\n",
489 | "\n",
490 | " | Intercept | 4.659e+04 | 5182.756 | 8.990 | 0.000 | 3.57e+04 | 5.74e+04 | \n",
491 | "
\n",
492 | "\n",
493 | " | year | -22.1341 | 2.578 | -8.584 | 0.000 | -27.531 | -16.737 | \n",
494 | "
\n",
495 | "
\n",
496 | "\n",
497 | "\n",
498 | " | Omnibus: | 0.027 | Durbin-Watson: | 0.286 | \n",
499 | "
\n",
500 | "\n",
501 | " | Prob(Omnibus): | 0.986 | Jarque-Bera (JB): | 0.137 | \n",
502 | "
\n",
503 | "\n",
504 | " | Skew: | 0.063 | Prob(JB): | 0.934 | \n",
505 | "
\n",
506 | "\n",
507 | " | Kurtosis: | 2.624 | Cond. No. | 6.67e+05 | \n",
508 | "
\n",
509 | "
Notes:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
[2] The condition number is large, 6.67e+05. This might indicate that there are
strong multicollinearity or other numerical problems."
510 | ],
511 | "text/plain": [
512 | "\n",
513 | "\"\"\"\n",
514 | " OLS Regression Results \n",
515 | "==============================================================================\n",
516 | "Dep. Variable: fuelCost08 R-squared: 0.795\n",
517 | "Model: OLS Adj. R-squared: 0.784\n",
518 | "Method: Least Squares F-statistic: 73.69\n",
519 | "Date: Sat, 09 Oct 2021 Prob (F-statistic): 5.79e-08\n",
520 | "Time: 11:20:05 Log-Likelihood: -118.43\n",
521 | "No. Observations: 21 AIC: 240.9\n",
522 | "Df Residuals: 19 BIC: 242.9\n",
523 | "Df Model: 1 \n",
524 | "Covariance Type: nonrobust \n",
525 | "==============================================================================\n",
526 | " coef std err t P>|t| [0.025 0.975]\n",
527 | "------------------------------------------------------------------------------\n",
528 | "Intercept 4.659e+04 5182.756 8.990 0.000 3.57e+04 5.74e+04\n",
529 | "year -22.1341 2.578 -8.584 0.000 -27.531 -16.737\n",
530 | "==============================================================================\n",
531 | "Omnibus: 0.027 Durbin-Watson: 0.286\n",
532 | "Prob(Omnibus): 0.986 Jarque-Bera (JB): 0.137\n",
533 | "Skew: 0.063 Prob(JB): 0.934\n",
534 | "Kurtosis: 2.624 Cond. No. 6.67e+05\n",
535 | "==============================================================================\n",
536 | "\n",
537 | "Notes:\n",
538 | "[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.\n",
539 | "[2] The condition number is large, 6.67e+05. This might indicate that there are\n",
540 | "strong multicollinearity or other numerical problems.\n",
541 | "\"\"\""
542 | ]
543 | },
544 | "execution_count": 9,
545 | "metadata": {},
546 | "output_type": "execute_result"
547 | }
548 | ],
549 | "source": [
550 | "mpg_model.summary()"
551 | ]
552 | },
553 | {
554 | "cell_type": "code",
555 | "execution_count": 10,
556 | "id": "a715f8b7",
557 | "metadata": {},
558 | "outputs": [
559 | {
560 | "data": {
561 | "image/png": "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\n",
562 | "text/plain": [
563 | ""
564 | ]
565 | },
566 | "metadata": {
567 | "needs_background": "light"
568 | },
569 | "output_type": "display_data"
570 | }
571 | ],
572 | "source": [
573 | "fig, ax = plt.subplots()\n",
574 | "ax.scatter(x=avg_by_year['year'], y=avg_by_year['fuelCost08'])\n",
575 | "ax.plot(avg_by_year['year'], mpg_model.fittedvalues);"
576 | ]
577 | },
578 | {
579 | "cell_type": "code",
580 | "execution_count": 11,
581 | "id": "9a3a36f7",
582 | "metadata": {},
583 | "outputs": [
584 | {
585 | "data": {
586 | "image/png": "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\n",
587 | "text/plain": [
588 | ""
589 | ]
590 | },
591 | "metadata": {
592 | "needs_background": "light"
593 | },
594 | "output_type": "display_data"
595 | }
596 | ],
597 | "source": [
598 | "fig, ax = plt.subplots()\n",
599 | "ax.scatter(x=avg_by_year['year'], y=avg_by_year['fuelCost08'])\n",
600 | "ax.plot(avg_by_year['year'], mpg_model.fittedvalues)\n",
601 | "ax.set_xlim((2010,2020))\n",
602 | "ax.set_ylim((1800,2200));"
603 | ]
604 | },
605 | {
606 | "cell_type": "code",
607 | "execution_count": 13,
608 | "id": "f49c42e4",
609 | "metadata": {},
610 | "outputs": [
611 | {
612 | "data": {
613 | "text/plain": [
614 | "1970.0"
615 | ]
616 | },
617 | "execution_count": 13,
618 | "metadata": {},
619 | "output_type": "execute_result"
620 | }
621 | ],
622 | "source": [
623 | "df_2010 = df.query('year >= 2010').copy()\n",
624 | "avg_fuel_cost = df_2010['fuelCost08'].mean().round(0)\n",
625 | "avg_fuel_cost"
626 | ]
627 | },
628 | {
629 | "cell_type": "code",
630 | "execution_count": 14,
631 | "id": "a24166c0",
632 | "metadata": {},
633 | "outputs": [
634 | {
635 | "data": {
636 | "image/png": "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\n",
637 | "text/plain": [
638 | ""
639 | ]
640 | },
641 | "metadata": {},
642 | "output_type": "display_data"
643 | }
644 | ],
645 | "source": [
646 | "mpl.style.use('ggplot')\n",
647 | "fig, (ax1, ax2) = plt.subplots(nrows=1, ncols=2, \n",
648 | " figsize=(12,6))\n",
649 | "\n",
650 | "ax1.scatter(x=avg_by_year['year'], \n",
651 | " y=avg_by_year['fuelCost08'])\n",
652 | "ax1.plot(avg_by_year['year'], \n",
653 | " mpg_model.fittedvalues, \n",
654 | " color='forestgreen', linestyle='--')\n",
655 | "\n",
656 | "ax1.set(xlabel='Year', ylabel='Fuel Cost', \n",
657 | " ylim=(1850, 2200), xlim=(2010,2020))\n",
658 | "ax1.yaxis.set_major_formatter('${x:,.0f}')\n",
659 | "ax1.axhline(avg_fuel_cost, linestyle=':', color='orange')\n",
660 | "ax1.annotate(f'${avg_fuel_cost}', xy=(2017, avg_fuel_cost))\n",
661 | "\n",
662 | "ax2.hist(df_2010['fuelCost08'], color = \"skyblue\", ec=\"white\")\n",
663 | "ax2.xaxis.set_major_formatter('${x:,.0f}')\n",
664 | "ax2.set(xlabel='Fuel Costs', ylabel='Num autos')\n",
665 | "ax2.axvline(avg_fuel_cost, linestyle=':')\n",
666 | "ax2.annotate(f'${avg_fuel_cost}', xy=(avg_fuel_cost, 3500))\n",
667 | "\n",
668 | "fig.suptitle('EPA Estimated FuelCosts', \n",
669 | " weight='bold', size=14)\n",
670 | "fig.savefig(image_dir/'line_hist.svg', \n",
671 | " transparent=False, dpi=200, bbox_inches=\"tight\")"
672 | ]
673 | },
674 | {
675 | "cell_type": "code",
676 | "execution_count": null,
677 | "id": "7416766b",
678 | "metadata": {},
679 | "outputs": [],
680 | "source": []
681 | }
682 | ],
683 | "metadata": {
684 | "kernelspec": {
685 | "display_name": "Python 3 (ipykernel)",
686 | "language": "python",
687 | "name": "python3"
688 | },
689 | "language_info": {
690 | "codemirror_mode": {
691 | "name": "ipython",
692 | "version": 3
693 | },
694 | "file_extension": ".py",
695 | "mimetype": "text/x-python",
696 | "name": "python",
697 | "nbconvert_exporter": "python",
698 | "pygments_lexer": "ipython3",
699 | "version": "3.8.11"
700 | }
701 | },
702 | "nbformat": 4,
703 | "nbformat_minor": 5
704 | }
705 |
--------------------------------------------------------------------------------