"""
# Exploring IRIS Data with Python
In this Kernal, I will explore the small 'IRIS' dataset which contains information about several observations of a few different IRIS flower species. I will use this as a chance to pgo through a  few different way of visualizing data using Python. This should serves as a pretty nice reference for previewing/visualizing data, especially using Pandas DataFrames and Seaborn. 

![](https://thumbs.gfycat.com/EnergeticHeartfeltAztecant-small.gif)
"""
"""
# Imports:
"""
# This Python 3 environment comes with many helpful analytics libraries installed
# It is defined by the kaggle/python docker image: https://github.com/kaggle/docker-python
# For example, here's several helpful packages to load in 

import numpy as np # linear algebra
import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)
import matplotlib.pyplot as plt
import seaborn as sns
import warnings

%matplotlib inline
sns.set_style("whitegrid")

# Supress warnings
warnings.filterwarnings('ignore')

# Input data files are available in the "../input/" directory.
# For example, running this (by clicking run or pressing Shift+Enter) will list the files in the input directory

import os
print(os.listdir("../input"))

# Any results you write to the current directory are saved as output.
"""
# Load & Preview Data using Pandas:
1. Store Data into a Pandas DataFrame
2. Preview the Data
3. Check if there is any missing data that needs to be imputed
"""
DF_iris = pd.read_csv("../input/Iris.csv") # Load Iris data into pandas DataFrame
print(DF_iris.keys()) # Print a list of the index keys
print(DF_iris.shape) # Return the number of (rows, columns) in the dataset
DF_iris.head() # Shows the first 5 rows of data
DF_iris.describe() # Show some very basic stats on the numerical data columns
# Check for any missing data:
print('Missing Training Data:')
DF_iris.isnull().sum()
"""
# Lets Start to explore the data:
1. How many different species are there, and how many samples of each?
2. How are the numerical variables distributed?
3. What are some different plotting tools that we can use to visualize these data?

"""
# First, Let's drop the ID column from the DF, since that is not going to be interesting to explore
DF_iris.drop(labels = ['Id'], axis = 1, inplace = True)
DF_iris.head()
vars = ['SepalLengthCm','SepalWidthCm','PetalLengthCm','PetalWidthCm']
print(vars)
"""
# Visualizing the Species Data:
"""
print(DF_iris.Species.value_counts())
sns.countplot(DF_iris.Species);
"""
Ok. So it looks like this dataset only consists of 3 different species and there is an even 50 observations of each one. Next let's try exploring the numerical variables

# Visualizing the Observational Data:
"""
# We can use built-in features of a Pandas DataFrame to plot the distributions of all of the variables...
# However, these are not the prettiest plots...
DF_iris.hist(grid=False)
fig=plt.gcf()
fig.set_size_inches(12,6)
plt.show()
"""
We can use FacetGrid for nice seaborn subplots with less lines of code:

documentation for using **FacetGrid**: (https://seaborn.pydata.org/generated/seaborn.FacetGrid.html)
"""
grid = sns.FacetGrid(pd.melt(DF_iris[vars]), col = 'variable', col_wrap = 4, size = 5.0, 
                    aspect = 1.0, sharex = False, sharey = False)
grid.map(sns.distplot, 'value')
plt.show;
"""
These plots are definitely a bit prettier than the histogram plots we were able to generate above from pandas/plotly.

From these plots, we can see that some of the variables seem to be somewhat multui-modal. Perhaps this means that there are some differences between the different species. Probably more useful to plot the data, while highlighting the different plant species, though...
"""
"""
# Split Data by Species, Then Visualize:

Here is an example using plotly subplots to visualize the different species through seaborn **boxplots**:
Box plots can help visualize the distributions for each species, as well as show outliers...

"""
plt.figure(figsize=(25,5))
plt.subplot(1,4,1)
sns.boxplot(x='Species',y='PetalLengthCm',data=DF_iris)
plt.subplot(1,4,2)
sns.boxplot(x='Species',y='PetalWidthCm',data=DF_iris)
plt.subplot(1,4,3)
sns.boxplot(x='Species',y='SepalLengthCm',data=DF_iris)
plt.subplot(1,4,4)
sns.boxplot(x='Species',y='SepalWidthCm',data=DF_iris);
"""
We can also visualize each individual observation overlayed with the boxplots. See this example with 'SepalWidthCm'
"""
sns.boxplot(x='Species',y='SepalWidthCm',data=DF_iris)
sns.stripplot(x="Species", y="SepalWidthCm", data=DF_iris, jitter=True, edgecolor="gray"); # jitter shifts point slightly left-right so there isn't too much overlap
"""
Other plots also work good for visualizing the distribution of various variables.

Here is a similar example with **Violin plots** (I personally prefer box plots; these kind of looks a little Georgia O'Keeffe-esque):
"""
plt.figure(figsize=(25,5))
plt.subplot(1,4,1)
sns.violinplot(x='Species',y='PetalLengthCm',data=DF_iris)
plt.subplot(1,4,2)
sns.violinplot(x='Species',y='PetalWidthCm',data=DF_iris)
plt.subplot(1,4,3)
sns.violinplot(x='Species',y='SepalLengthCm',data=DF_iris)
plt.subplot(1,4,4)
sns.violinplot(x='Species',y='SepalWidthCm',data=DF_iris);
"""
# Visualize How Varibales Relate to Eachother (and differ by species):

seaborn has some pretty cool plots, such as **jointplot** :

try changing kind="_____"  to  “scatter” | “reg” | “resid” | “kde” | “hex”

documentation: (http://seaborn.pydata.org/generated/seaborn.jointplot.html)
"""
# Let's plot 2 variables against eachother...
g = sns.jointplot("PetalLengthCm", "PetalWidthCm", data=DF_iris, kind="reg")
"""
Notice that the jointplot offers some cool visualizations of a scatter and distributions of each variable. however, it doesn't help determine the differences between species. Here is where the **lmplot** helps out (documentation: https://seaborn.pydata.org/generated/seaborn.lmplot.html):
"""
g = sns.lmplot(x='PetalLengthCm', y='PetalWidthCm', hue='Species', data=DF_iris, fit_reg=False)
"""
Now we can see how IRIS flowers can really differ, depending on species!
"""
"""
# How about plotting the relationship between multiple variables (and Species) at once?

Seaborn has some pretty powerful built-in ways to plot a lot of data at once from a pandas dataframe:

**PairPlot** Documentation Link: (https://seaborn.pydata.org/tutorial/axis_grids.html)

Here we have distributions of each measurement variable, as well as scatter plots of each measurement variable plotted against the others. (All from only a single line of code!)

The Scatter plots in the upper-right and lower-left are slightly repetative... We can custamize this a bit more with different types of plot in each area... try uncommenting the lines of code below to see how you can customize which types of plots are shown:
"""
g = sns.pairplot(DF_iris, hue='Species', height=4)
# g.map_upper(sns.regplot) # some plot options: 'regplot', 'residplot', 'scatterplot'
#g.map_lower(sns.kdeplot)
#g.map_diag(plt.hist)
"""
# Parallel Coordinates Plot:

Since there is a relatively low number of predictor variables/features and the vlues of those predictors are on relatively sinilar scales, this dataset lends itself well to being visualized by a parallel coordinates plot. (note, certain variables were on vastly different scales, some normalization may be needed) This type of plot creates a line for each observation based on the value of each variable on the y-axis. We color code the plot ,by species, so we may be able to observe if there are any trends that distinguish between species.
"""

from pandas.plotting import parallel_coordinates

plt.figure(figsize=(15,10))
parallel_coordinates(DF_iris[['Species', 'SepalLengthCm', 'SepalWidthCm', 'PetalLengthCm', 'PetalWidthCm']],'Species')
"""
**All Wrapped-up**

Now that we have gone through some basic data exploration/visualization, you are ready to begin your data modeling / machine learning while being a bit more informed about the data that you are working with...
"""