Matplotlib - Violin Plot
Matplotlib - Violin Plot
Section titled “Matplotlib - Violin Plot”Violin plots are a powerful visualization method that combines aspects of a box plot with a kernel density estimation (KDE) plot. They are used to visualize the distribution of numerical data and are particularly effective for comparing distributions across different categories.
Key features of a violin plot:
- Density Estimation: The main body of the violin is a KDE plot, mirrored on both sides. The width of the violin at a particular value indicates the estimated density or frequency of data points around that value.
- Box Plot Elements (Optional): Often, a miniature box plot or related markers are drawn inside the violin. This typically includes: - A marker for the median. - A box indicating the interquartile range (IQR: Q1 to Q3). - Sometimes lines (whiskers) extending to a certain range (though less common than in standard box plots).
Compared to a plain box plot, a violin plot provides a much richer understanding of the data’s distribution, revealing features like multimodality (multiple peaks) that are hidden by the summary statistics of a box plot.
The ax.violinplot() method in Matplotlib creates violin plots.
ax.violinplot(dataset, positions=None, showmeans=False, showextrema=True, showmedians=False, **kwargs)Key Parameters
Section titled “Key Parameters”dataset: A list or sequence of arrays/vectors. Each element corresponds to one violin.positions: Array-like. Sets the horizontal positions of the violins (defaults to[1, 2, 3, ...]).showmeans: Boolean. IfTrue, renders markers for the mean values.showextrema: Boolean. IfTrue(default), renders lines for the data extrema.showmedians: Boolean. IfTrue, renders markers for the median values.quantiles: Array-like between 0 and 1. If set (e.g.,[0.25, 0.75]), renders lines inside the violin for the specified quantiles (often used instead of a full box plot).bw_method: String or float. Method for calculating the estimator bandwidth for the KDE (affects smoothness).vert: Boolean. IfTrue(default), creates vertical violins. IfFalse, creates horizontal violins.
Example: Comparing distributions using violin plots.
import matplotlib.pyplot as pltimport numpy as np
# 1. Generate sample data (e.g., distributions with different shapes)np.random.seed(10)dist1_normal = np.random.normal(100, 10, 200)dist2_skewed = np.random.gamma(6, 15, 200) # Skewed distributiondist3_bimodal = np.concatenate([ np.random.normal(60, 10, 100), np.random.normal(110, 10, 100)]) # Two peaksdist4_uniform = np.random.uniform(70, 130, 200)
# Combine datasets into a listdata_to_plot = [dist1_normal, dist2_skewed, dist3_bimodal, dist4_uniform]labels = ['Normal', 'Skewed', 'Bimodal', 'Uniform']
# 2. Create the plotfig, ax = plt.subplots(figsize=(10, 6))
# 3. Create the violin plot# Show medians and quantiles (Q1, Q3) instead of default box/extremaparts = ax.violinplot(data_to_plot, showmeans=False, showmedians=True, quantiles=[[0.25, 0.75]] * len(data_to_plot) # Pass list of lists for quantiles )
# 4. Customize appearance (optional)colors = ['lightblue', 'lightgreen', 'lightcoral', 'lightsalmon']for pc, color in zip(parts['bodies'], colors): pc.set_facecolor(color) pc.set_edgecolor('black') pc.set_alpha(0.7)
# Customize median linesparts['cmedians'].set_colors('red')parts['cmedians'].set_linewidth(2)
# Customize quantile lines (if shown)if 'cquantiles' in parts: parts['cquantiles'].set_colors('black') parts['cquantiles'].set_linestyles(':') parts['cquantiles'].set_linewidth(1.5)
# Customize other parts (cbars for mean/extrema if shown, cmins, cmaxes)
# 5. Add labels and titleax.set_title('Comparison of Data Distributions using Violin Plots')ax.set_ylabel('Value')ax.set_xticks(np.arange(1, len(labels) + 1)) # Set positions for labelsax.set_xticklabels(labels)ax.yaxis.grid(True)
plt.show()This example generates data with different distribution shapes (normal, skewed, bimodal, uniform) and visualizes them using ax.violinplot. By showing the median and quantiles (representing the IQR), and observing the shape of the violin (the KDE), we get a much clearer picture of each distribution’s characteristics compared to just using a box plot.