devnotes.

Univariate Plots in Python

Univariate Plots in Python

Plots for one variable at a time are the first visual step of EDA. We use the wine dataset.

# 1) Bar plot: how many wines per quality score
quality_counts = df["quality"].value_counts().sort_index()
plt.figure(figsize=(8, 5))
plt.bar(quality_counts.index, quality_counts.values, color="deeppink")
plt.title("Count Plot of Quality")
plt.xlabel("Quality")
plt.ylabel("Count")
plt.show()

# 2) Histogram + KDE for every numeric column, with skewness in the title
num_cols = df.select_dtypes(include=["int64", "float64"]).columns
plt.figure(figsize=(14, len(num_cols) * 3))
for i, col in enumerate(num_cols, 1):
    plt.subplot(len(num_cols), 2, i)
    sns.histplot(df[col], kde=True)
    plt.title(f"{col} | Skewness: {round(df[col].skew(), 2)}")
plt.tight_layout()
plt.show()

# 3) Swarm plot to spot outliers
plt.figure(figsize=(8, 8))
sns.swarmplot(y="alcohol", data=df, color="skyblue")
plt.title("Swarm Plot of Alcohol")
plt.show()

1. Bar plot - count of each quality score

A bar plot compares categories or discrete values. In WineQT most wines score 5 or 6; very few score 3 or 8. This tells us the target is imbalanced, which matters later for classification (accuracy can be misleading; use F1 or class weights).

Tip: for many long category names use a horizontal bar chart (plt.barh).

2. Histogram with KDE - shape of the distribution

  • The histogram groups values into bins; bar height = how many values fall in the bin.
  • The KDE (Kernel Density Estimate) line is a smooth curve of the same distribution.
  • Try different bins values; too few hides detail and too many shows noise.

Reading skewness

SkewnessShapeMeaning
about 0symmetricmean is close to median
greater than 0right (positive) skewlong tail to the right, some very high values
less than 0left (negative) skewlong tail to the left, some very low values

Rule of thumb: absolute skewness above about 1 is strong. Columns like chlorides and residual sugar in the wine data are strongly right-skewed and usually benefit from a log transform.

3. Swarm plot - every point, and outliers

A swarm plot draws each observation as a point, spreading them sideways so they do not overlap. Dense areas show where most values sit; isolated points far from the crowd are potential outliers.

Swarm plots are great for up to a few hundred points. For large data (thousands of rows) use a box plot, strip plot with alpha, or a violin plot, because the swarm becomes slow and crowded.

Other useful univariate plots

sns.boxplot(x=df["alcohol"])                 # median, IQR, outliers
sns.violinplot(y=df["alcohol"])              # shape + box in one
sns.kdeplot(df["alcohol"], fill=True)        # smooth density
sns.ecdfplot(df["alcohol"])                  # cumulative distribution
df["quality"].value_counts().plot.pie(autopct="%1.1f%%")   # few categories only

Checklist when you see a univariate plot

  1. Is it symmetric or skewed?
  2. Is there one peak (unimodal) or more (multimodal - hint of hidden groups)?
  3. Are there gaps or spikes (data-entry patterns, rounding)?
  4. Are there extreme values? Are they errors or real?
  5. What transformation, if any, would help?
Univariate Plots in Python | Exploratory Data Analysis | DevNotes