class: center, middle, inverse, title-slide .title[ # ISA 419: Data-Driven Security ] .subtitle[ ## 08: Visualizing Data with Pandas ] .author[ ###
Fadel M. Megahed, PhD
Professor
Farmer School of Business
Miami University
@FadelMegahed
fmegahed
fmegahed@miamioh.edu
Automated Scheduler for Office Hours
] .date[ ### Spring 2025 ] --- ## Quick Refresher of Last Week's Class ✅ Ensure that your imported data is **technically correct** (rename columns and fix `dtypes`) ✅ Understand how to change the unit of analysis by grouping and aggregating data. ✅ Use the `agg()` function to do aggregations on grouped data. --- ## Learning Objectives for Today's Class - Create quick visualizations using the `plot` method from [pandas](https://pandas.pydata.org/docs/user_guide/visualization.html) (with an understanding of the effect of different backends). - Utilize `auto-viz` type plots to create a quick EDA of your data. --- class: inverse, center, middle # Plotting with Pandas --- ## Our Data - We will use the `merged_ips` data set from a previous class to demonstrate how to plot data in pandas. .font80[ ``` python import pandas as pd toxic_ips = pd.read_csv( "https://raw.githubusercontent.com/fmegahed/isa419/main/data/listed_ip_90_all.csv", header = None, names = ['ip', 'frequency', 'lastseen'] ) geolocation = pd.read_csv( 'https://raw.githubusercontent.com/fmegahed/isa419/main/data/ip_geolocation.csv', names = ['ip', 'country', 'city', 'latitude', 'longitude'] ) merged_ips = ( toxic_ips .merge(right = geolocation, how = 'left', on ='ip') .dropna() .assign( lastseen = lambda df: df['lastseen'].astype('datetime64[ns]') ) ) merged_ips.dtypes[0:3] ``` ``` ## ip object ## frequency int64 ## lastseen datetime64[ns] ## dtype: object ``` ] --- ## Plotting with Pandas - The `plot` method in pandas is a wrapper around `matplotlib` (by default) and is a quick way to visualize data. - The `plot` method is available on both `Series` and `DataFrame` objects.  .footnote[ <html> <hr> </html> **Source:** The figure is from the [Pandas Documentation](https://pandas.pydata.org/docs/getting_started/intro_tutorials/04_plotting.html) ] --- ## Class Activity to Assess your Understanding so Far
−
+
05
:
00
.panelset[ .panel[.panel-name[Task] - Write Python code to produce a data frame containing the total number of toxic IP frequencies by country. - Then, identify the top 10 countries with the highest toxic IP frequencies. ] .panel[.panel-name[Hints] <html> <details> <summary>Please let me know in class if you need any hints.</summary> <p>Use the `groupby` method to group the data by country and then use the `agg` method to aggregate the data. Then, use the <i>sort_values</i> method to sort the data in descending order by setting the <i>ascending</i> parameter to `False`.</p> </html> ] .panel[.panel-name[Solution] .font80[ ``` ## frequency ## country ## Georgia 1712171 ## Ukraine 928770 ## Russia 661849 ## Germany 444641 ## Canada 443046 ## United States 230434 ## Finland 188501 ## Poland 152569 ## India 120881 ## The Netherlands 84973 ``` ] ] ] --- ## Plotting with Pandas (Plot `kind`) <iframe src="https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.plot.html" width="100%" height="500px" data-external="1"></iframe> --- ## Plotting with Pandas (`line` Plot) .pull-left[ .font80[ .center[**Data Prep:**] ``` python # Aggregating the frequencies by day daily_freq = ( merged_ips .groupby(merged_ips['lastseen'].dt.date) .agg(sum_freq = ('frequency', 'sum')) .reset_index() # to have last seen as col .rename(columns = {'lastseen': 'date'}) ) daily_freq.head(n=2) ``` ``` ## date sum_freq ## 0 2023-10-26 8952 ## 1 2023-10-27 4642 ``` ] ] .pull-right[ .font80[ .center[**Plotting:**] ``` python daily_freq.plot( x = 'date', y = 'sum_freq', kind = 'line', title = 'Toxic IP Frequencies by Day', xlabel = 'Date', ylabel = 'Frequency', figsize = (10, 4) ) ``` <img src="data:image/png;base64,#08_data_viz_intro_files/figure-html/line_plot-1.png" width="960" style="display: block; margin: auto;" /> ] ] --- ## Plotting with Pandas (`bar` Plot) .pull-left[ .font80[ .center[**Data:**] ``` python # Aggregating the frequencies by country country_freq = ( merged_ips .groupby('country') .agg(sum_freq = ('frequency', 'sum')) .sort_values('sum_freq', ascending = False) .head(10) .reset_index() ) country_freq.head(n=2) ``` ``` ## country sum_freq ## 0 Georgia 1712171 ## 1 Ukraine 928770 ``` ] ] .pull-right[ .font80[ .center[**Plotting:**] ``` python country_freq.plot( x = 'country', y = 'sum_freq', kind = 'barh', title = 'Top 10 Countries with Toxic IP Freq', xlabel = 'Country', ylabel = 'Frequency', figsize = (10, 6), color = 'red' ) ``` <img src="data:image/png;base64,#08_data_viz_intro_files/figure-html/bar_plot-3.png" width="960" style="display: block; margin: auto;" /> ] ] --- ## Plotting with Pandas (`scatter` Plot) .pull-left[ .font80[ .center[**Data:**] ``` python country_freq.head(n=5) ``` ``` ## country sum_freq ## 0 Georgia 1712171 ## 1 Ukraine 928770 ## 2 Russia 661849 ## 3 Germany 444641 ## 4 Canada 443046 ``` ] ] .pull-right[ .font80[ .center[**Plotting:**] ``` python country_freq.plot( # scatter plots are better with two numeric vars # (this example is for illustration only) x = 'country', y = 'sum_freq', kind = 'scatter', title = 'Top 10 Countries with Toxic IP Freq', xlabel = 'Country', ylabel = 'Frequency', figsize = (12, 6) ) ``` <img src="data:image/png;base64,#08_data_viz_intro_files/figure-html/scatter_plot-5.png" width="1152" style="display: block; margin: auto;" /> ] ] --- ## Class Activity to Assess your Understanding so Far
−
+
10
:
00
.panelset[ .panel[.panel-name[Task] - Read the [`simulated_attack_data.csv`](https://raw.githubusercontent.com/fmegahed/isa419/main/data/simulated_attack_data.csv) file into a pandas data frame. - Then, answer the questions in the next three tabs. ] .panel[.panel-name[Task 1] - Create a histogram of the `Attempt Count` variable. - What does the histogram tell you about the `Attempt Count` variable? .can-edit.key-activity12a[ - Edit me to answer the question above. ] ] .panel[.panel-name[Task 2] - Create a scatter plot of the `Source Latitude` and `Source Longitude` variables. ] .panel[.panel-name[Task 3] - Utilize [this Stack Overflow thread](https://stackoverflow.com/a/67428742/10156153) to convert the scatter plot of the `Source Latitude` and `Source Longitude` variables into an interactive symbols map. ] ] --- class: inverse, center, middle # Automated Viasualizations in Python --- ## The `ydata-profiling` Package Data quality profiling and exploratory data analysis (EDA) are crucial steps in any business analytics application. [ydata-profiling](https://docs.profiling.ydata.ai/latest/) automates and standardizes the generation of detailed reports, complete with statistics and visualizations. The significance of the package lies in how it streamlines the process of understanding and preparing data for analysis in a single line of code! --- ## Usage of `ydata-profiling` ``` python import pandas as pd *from ydata_profiling import ProfileReport *profile = ProfileReport(sim_attack_df, title="Pandas Profiling Report", explorative=True) # the next line is needed since I am not using Colab for making the slides profile.to_file("../../figures/sim_attack_data_report.html") ``` --- ## Output of `ydata-profiling` <iframe src="https://fmegahed.github.io/isa419/figures/sim_attack_data_report.html" width="100%" height="500px" data-external="1"></iframe> --- ## Class Activity
−
+
10
:
00
.panelset[ .panel[.panel-name[Task] - Identify a similar package to `ydata-profiling` in Python. - Then, use the package to generate a report for the `merged_ips` data set. - Share the report with your neighboring classmate. - Discuss the insights and visualizations in your approach(es). ] ] --- class: inverse, center, middle # Recap --- ## Summary of Main Points By now, you should be able to do the following: - Create quick visualizations using the `plot` method from [pandas](https://pandas.pydata.org/docs/user_guide/visualization.html) (with an understanding of the effect of different backends). - Utilize `auto-viz` type plots to create a quick EDA of your data. --- ## 📝 Review and Clarification 📝 1. **Class Notes**: Take some time to revisit your class notes for key insights and concepts. 2. **Zoom Recording**: The recording of today's class will be made available on Canvas approximately 3-4 hours after the end of class. 3. **Questions**: Please don't hesitate to ask for clarification on any topics discussed in class. It's crucial not to let questions accumulate.