├── 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 | [![](./readme_resources/python-data-visualization.jpg)](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 | " \n", 78 | " \n", 79 | " \n", 80 | " \n", 81 | " \n", 82 | " \n", 83 | " \n", 84 | " \n", 85 | " \n", 86 | " \n", 87 | " \n", 88 | " \n", 89 | " \n", 90 | " \n", 91 | " \n", 92 | " \n", 93 | " \n", 94 | " \n", 95 | " \n", 96 | " \n", 97 | " \n", 98 | " \n", 99 | " \n", 100 | " \n", 101 | " \n", 102 | " \n", 103 | " \n", 104 | " \n", 105 | " \n", 106 | " \n", 107 | " \n", 108 | " \n", 109 | " \n", 110 | " \n", 111 | " \n", 112 | " \n", 113 | " \n", 114 | " \n", 115 | " \n", 116 | " \n", 117 | " \n", 118 | " \n", 119 | " \n", 120 | " \n", 121 | " \n", 122 | " \n", 123 | " \n", 124 | " \n", 125 | " \n", 126 | " \n", 127 | " \n", 128 | " \n", 129 | " \n", 130 | " \n", 131 | " \n", 132 | " \n", 133 | " \n", 134 | " \n", 135 | " \n", 136 | " \n", 137 | " \n", 138 | " \n", 139 | " \n", 140 | " \n", 141 | " \n", 142 | " \n", 143 | " \n", 144 | " \n", 145 | " \n", 146 | " \n", 147 | " \n", 148 | " \n", 149 | " \n", 150 | " \n", 151 | " \n", 152 | " \n", 153 | " \n", 154 | " \n", 155 | " \n", 156 | " \n", 157 | " \n", 158 | " \n", 159 | " \n", 160 | " \n", 161 | " \n", 162 | " \n", 163 | " \n", 164 | " \n", 165 | " \n", 166 | " \n", 167 | " \n", 168 | " \n", 169 | " \n", 170 | " \n", 171 | " \n", 172 | " \n", 173 | " \n", 174 | " \n", 175 | " \n", 176 | " \n", 177 | " \n", 178 | " \n", 179 | " \n", 180 | "
makemodelyearcylinderstranydisplVClassco2barrels08fuelCost08fuelTypehighway08city08comb08
0AcuraNSX20006.0Automatic 4-spd3.0Two Seaters-118.3116672600Premium221518
1AcuraNSX20006.0Manual 6-spd3.2Two Seaters-118.3116672600Premium221518
2BMWM Coupe20006.0Manual 5-spd3.2Two Seaters-117.3478952500Premium231719
3BMWZ3 Coupe20006.0Automatic 4-spd2.8Two Seaters-117.3478952500Premium241719
4BMWZ3 Coupe20006.0Manual 5-spd2.8Two Seaters-117.3478952500Premium241719
\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 | " \n", 246 | " \n", 247 | " \n", 248 | " \n", 249 | " \n", 250 | " \n", 251 | " \n", 252 | " \n", 253 | " \n", 254 | " \n", 255 | " \n", 256 | " \n", 257 | " \n", 258 | " \n", 259 | " \n", 260 | " \n", 261 | " \n", 262 | " \n", 263 | " \n", 264 | " \n", 265 | " \n", 266 | " \n", 267 | " \n", 268 | " \n", 269 | " \n", 270 | " \n", 271 | " \n", 272 | " \n", 273 | " \n", 274 | " \n", 275 | " \n", 276 | " \n", 277 | " \n", 278 | " \n", 279 | " \n", 280 | " \n", 281 | " \n", 282 | " \n", 283 | " \n", 284 | " \n", 285 | " \n", 286 | " \n", 287 | " \n", 288 | " \n", 289 | " \n", 290 | " \n", 291 | " \n", 292 | " \n", 293 | " \n", 294 | " \n", 295 | " \n", 296 | " \n", 297 | " \n", 298 | " \n", 299 | " \n", 300 | " \n", 301 | " \n", 302 | " \n", 303 | " \n", 304 | " \n", 305 | " \n", 306 | " \n", 307 | " \n", 308 | " \n", 309 | " \n", 310 | " \n", 311 | " \n", 312 | " \n", 313 | " \n", 314 | " \n", 315 | " \n", 316 | " \n", 317 | " \n", 318 | " \n", 319 | " \n", 320 | " \n", 321 | " \n", 322 | " \n", 323 | " \n", 324 | " \n", 325 | " \n", 326 | " \n", 327 | " \n", 328 | " \n", 329 | " \n", 330 | " \n", 331 | " \n", 332 | " \n", 333 | " \n", 334 | " \n", 335 | " \n", 336 | " \n", 337 | " \n", 338 | " \n", 339 | " \n", 340 | " \n", 341 | " \n", 342 | " \n", 343 | " \n", 344 | " \n", 345 | " \n", 346 | " \n", 347 | " \n", 348 | " \n", 349 | " \n", 350 | " \n", 351 | " \n", 352 | " \n", 353 | " \n", 354 | " \n", 355 | " \n", 356 | "
yearfuelCost08
020002184.94
120012201.48
220022229.38
320032273.99
420042264.57
520052271.01
620062287.00
720072284.15
820082285.68
920092183.23
1020102116.50
1120112103.86
1220122066.26
1320131996.78
1420141987.84
1520151943.05
1620161894.37
1720171894.86
1820181905.42
1920191900.22
2020201920.10
\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 | "\n", 457 | "\n", 458 | " \n", 459 | "\n", 460 | "\n", 461 | " \n", 462 | "\n", 463 | "\n", 464 | " \n", 465 | "\n", 466 | "\n", 467 | " \n", 468 | "\n", 469 | "\n", 470 | " \n", 471 | "\n", 472 | "\n", 473 | " \n", 474 | "\n", 475 | "\n", 476 | " \n", 477 | "\n", 478 | "\n", 479 | " \n", 480 | "\n", 481 | "\n", 482 | " \n", 483 | "\n", 484 | "
OLS Regression Results
Dep. Variable: fuelCost08 R-squared: 0.795
Model: OLS Adj. R-squared: 0.784
Method: Least Squares F-statistic: 73.69
Date: Sat, 09 Oct 2021 Prob (F-statistic): 5.79e-08
Time: 11:20:05 Log-Likelihood: -118.43
No. Observations: 21 AIC: 240.9
Df Residuals: 19 BIC: 242.9
Df Model: 1
Covariance Type: nonrobust
\n", 485 | "\n", 486 | "\n", 487 | " \n", 488 | "\n", 489 | "\n", 490 | " \n", 491 | "\n", 492 | "\n", 493 | " \n", 494 | "\n", 495 | "
coef std err t P>|t| [0.025 0.975]
Intercept 4.659e+04 5182.756 8.990 0.000 3.57e+04 5.74e+04
year -22.1341 2.578 -8.584 0.000 -27.531 -16.737
\n", 496 | "\n", 497 | "\n", 498 | " \n", 499 | "\n", 500 | "\n", 501 | " \n", 502 | "\n", 503 | "\n", 504 | " \n", 505 | "\n", 506 | "\n", 507 | " \n", 508 | "\n", 509 | "
Omnibus: 0.027 Durbin-Watson: 0.286
Prob(Omnibus): 0.986 Jarque-Bera (JB): 0.137
Skew: 0.063 Prob(JB): 0.934
Kurtosis: 2.624 Cond. No. 6.67e+05


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 | --------------------------------------------------------------------------------