Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Matplotlib Plot Styling and Customization Techniques

Tech May 15 1

Plot Creation Methods

Matplotlib provides multiple approaches for creating plots:

# Method 1: Basic figure and plot
figure = plt.figure(figsize=(12, 8))
plt.plot(data_x, data_y, linestyle='--', color='red', linewidth=2, 
         marker='o', markerfacecolor='blue', markersize=8, zorder=3)

# Method 2: Subplot indexing
figure = plt.figure(figsize=(12, 8))
plt.subplot(3, 3, index)
plt.plot(...)

axis = plt.subplot(3, 3, index)
axis.plot(...)

# Method 3: Subplots with gridspec
fig, axes = plt.subplots(3, 3, figsize=(12, 8))
fig, axes = plt.subplots(3, 1, figsize=(12, 10), 
                        gridspec_kw={'height_ratios': [1, 1, 1]})

axes[0, 0].plot(...)

# Method 4: Single axis
fig, ax = plt.subplots(figsize=(12, 8))
ax.plot(...)
plt.plot(...)

Style Configuration

axes[i,j].set_xlabel('Recall', fontsize=14, fontweight='bold', loc="center", labelpad=20)
axes[i,j].set_ylabel('Precision', fontsize=14, fontweight='bold')
axes[i,j].set_title(f'OvR Precision-Recall Curve ({feature_type}-Ch{channel})', 
                   fontsize=14, fontweight='bold')
axes[i,j].legend(loc="best", fontsize=12)
axes[i,j].set_xlim([0.0, 1.05])
axes[i,j].set_ylim([0.0, 1.05])

# Configure tick parameters
axes[i,j].tick_params(axis='both', which='both', width=2, labelsize=14)
axes[i,j].spines['top'].set_linewidth(2)
axes[i,j].spines['bottom'].set_linewidth(2)
axes[i,j].spines['left'].set_linewidth(2)
axes[i,j].spines['right'].set_linewidth(2)

fig, ax = plt.subplots(figsize=(10, 6))

plt.xlabel('Recall', fontsize=14, fontweight='bold')
plt.ylabel('Precision', fontsize=14, fontweight='bold')
plt.title(f'Micro-Averaged Precision-Recall Curve ({feature_type})', 
         fontsize=14, fontweight='bold')

plt.legend(loc="lower left", fontsize=12)
plt.legend(loc="upper right", fontsize=12)

plt.tick_params(axis='both', which='both', width=2, labelsize=14)
ax.spines['top'].set_linewidth(2)
ax.spines['bottom'].set_linewidth(2)
ax.spines['left'].set_linewidth(2)
ax.spines['right'].set_linewidth(2)

plt.xlim([0.0, 1.05])
plt.ylim([0.0, 1.05])
plt.grid(True)

plt.tight_layout()
plt.savefig(f"{output_directory}/{timestamp}_figure1.png")
plt.show()
plt.close()

Export Formats

Matplotlib supports various file formats for saving visualizations:

  • PNG - Lossless compression for web and applications
  • JPEG - Lossy compression for photographic content
  • SVG - Vector format for scalible graphics
  • PDF - High-quality print and archival format
  • PS/EPS - PostScript formats for publishing
  • TIFF - Versatile raster format for professional use

Text Annotation

plt.text(x_coord, y_coord, text_string, **kwargs)

# Examples
axis[0].text(3, 5, "Coordinate (3, 5)", fontsize=12, color='red')
plt.text(3, 5, "Coordinate (3, 5)", fontsize=12, color='red')
plt.text(3, 5, "Coordinate (3, 5)", fontsize=12, color='blue', 
         font="arial", style='italic', weight='bold')
plt.text(3, 5, "Rotated Annotation", fontsize=12, color='green', rotation=45)
plt.text(0.5, 0.95, f'ARI: {ari_value:.3f}, NMI: {nmi_value:.3f}', 
         ha='center', va='center', transform=plt.gca().transAxes)
axis[0].text(0.5, 0.95, f'ARI: {ari_value:.3f}, NMI: {nmi_value:.3f}', 
            ha='center', va='center', transform=axis[0].transAxes)

Subplot Labeling

import matplotlib.pyplot as plt

# Create 2x2 subplot grid
fig, axes = plt.subplots(2, 2, figsize=(10, 8))

# Generate sequential labels
label_count = 4 
labels = [f'({chr(97 + i)})' for i in range(label_count)]

# Apply labels to each subplot
for idx, ax in enumerate(axes.flatten()):
    ax.text(-0.1, 1.1, labels[idx], transform=ax.transAxes, 
           font="arial", fontsize=18, fontweight='bold', va='top')

plt.show()

Transparency Control

import matplotlib.pyplot as plt
import numpy as np

# Line transparency
x_values = [0, 1, 2, 3, 4]
y_values = [0, 2, 4, 6, 8]
plt.plot(x_values, y_values, alpha=0.5)

# Scatter plot transparency
plt.scatter(x_values, y_values, alpha=0.3)

# Bar plot transparency
plt.bar(x_values, y_values, alpha=0.7)

# Area fill transparency
plt.fill_between(x_values, y_values, alpha=0.2)

# Histogram transparency
sample_data = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]
plt.hist(sample_data, alpha=0.6)

# Combined transparency example
x_range = np.linspace(0, 10, 100)
y_sine = np.sin(x_range)
y_cosine = np.cos(x_range)

plt.plot(x_range, y_sine, label='sin(x)', alpha=0.5)
plt.plot(x_range, y_cosine, label='cos(x)', alpha=0.7)
plt.fill_between(x_range, y_sine, y_cosine, alpha=0.3, color='gray')
plt.scatter(x_range[::10], y_sine[::10], alpha=0.6)
plt.legend()
plt.show()

Element Stacking Order

import matplotlib.pyplot as plt
import numpy as np

# Generate sample data
x_data = np.linspace(0, 10, 100)
y_data = np.sin(x_data)

# Create plot with controlled z-order
plt.figure()
plt.plot(x_data, y_data, label='Sin(x)', zorder=3)
plt.grid(True, zorder=2)
plt.legend(loc='upper right', zorder=4)
plt.title("Z-Order Control Example")
plt.show()

# Complex z-order example
x_points = np.arange(10)
y_points = 2.5 * np.sin(x_points / 20 * np.pi)
error_values = np.linspace(0.05, 0.2, 10)

plt.figure()
plt.bar(x_points, y_points + 3, color='blue', label='Bar', zorder=3)
plt.errorbar(x_points, y_points, yerr=error_values, label='Error Bar', 
             fmt='-o', zorder=4)
plt.scatter(x_points, y_points - 3, color='red', label='Scatter', zorder=5)
plt.grid(True, zorder=2)
plt.legend(loc='upper right', zorder=6)
plt.title("Multi-Element Z-Order Example")
plt.show()

Utility Functions

def format_axis(axis, x_label, y_label, x_limits=None, y_limits=None, 
               plot_title=None, enable_grid=True, show_legend=True, 
               legend_position="upper right"):
    """
    Configures axis formatting with labels, titles, and styling.
    
    Parameters:
    axis : matplotlib.axes.Axes - Target axis object
    x_label : str - X-axis label text
    y_label : str - Y-axis label text
    x_limits : tuple, optional - X-axis range (min, max)
    y_limits : tuple, optional - Y-axis range (min, max)
    plot_title : str, optional - Plot title text
    enable_grid : bool, optional - Grid display toggle
    show_legend : bool, optional - Legend display toggle
    legend_position : str, optional - Legend placement
    """
    axis.set_xlabel(x_label, fontsize=14, fontweight='bold')
    axis.set_ylabel(y_label, fontsize=14, fontweight='bold')

    if x_limits is not None:
        axis.set_xlim(x_limits)
    if y_limits is not None:
        axis.set_ylim(y_limits)
    if plot_title is not None:
        axis.set_title(plot_title, fontsize=12)
    if show_legend:
        axis.legend(loc=legend_position, fontsize=12)
    if enable_grid:    
        axis.grid(enable_grid, zorder=0)
        
    axis.tick_params(axis='both', which='both', width=2, labelsize=14)
    axis.spines['top'].set_linewidth(2)
    axis.spines['bottom'].set_linewidth(2)
    axis.spines['left'].set_linewidth(2)
    axis.spines['right'].set_linewidth(2)

def add_sequential_labels(axes_array, label_x=-0.1, label_y=1.1, start_char='a'):
    """
    Applies sequential labels to subplots.
    
    Parameters:
    axes_array : numpy array - Array of axis objects
    label_x : float, optional - X coordinate for label placement
    label_y : float, optional - Y coordinate for label placement
    start_char : str, optional - Starting character for sequence
    """
    label_count = len(axes_array)
    labels = [f'({chr(ord(start_char) + i)})' for i in range(label_count)]

    axes_flat = axes_array.flatten() if hasattr(axes_array, 'flatten') else axes_array
    for idx, ax in enumerate(axes_flat):
        ax.text(label_x, label_y, labels[idx], transform=ax.transAxes, 
               font="arial", fontsize=18, fontweight='bold', va='top')

Subplot Layout Management

import matplotlib.pyplot as plt
from matplotlib import gridspec

# subplots_adjust method
fig, ax = plt.subplots(2, 2)
plt.subplots_adjust(left=0.1, right=0.9, bottom=0.1, top=0.9, 
                   wspace=0.5, hspace=0.5)

# tight_layout method
fig, ax = plt.subplots(2, 2)
plt.tight_layout()

# constrained_layout method
fig, ax = plt.subplots(2, 2, constrained_layout=True)

# GridSpec for complex layouts
fig = plt.figure()
gs = gridspec.GridSpec(2, 2, figure=fig, width_ratios=[1, 2], 
                      height_ratios=[4, 1], wspace=0.5, hspace=0.5)
ax1 = fig.add_subplot(gs[0, 0])
ax2 = fig.add_subplot(gs[0, 1])
ax3 = fig.add_subplot(gs[1, :])

# add_subplot method
fig = plt.figure(figsize=(10, 6))
ax1 = fig.add_subplot(3, 2, 1)
ax2 = fig.add_subplot(3, 2, 3)
ax3 = fig.add_subplot(3, 2, 5)
fig.tight_layout()

# subplot2grid method
fig = plt.figure(figsize=(10, 6))
ax1 = plt.subplot2grid((3, 3), (0, 0), rowspan=3, colspan=2)
ax2 = plt.subplot2grid((3, 3), (0, 2), rowspan=2, colspan=1)
ax3 = plt.subplot2grid((3, 3), (2, 2))
plt.show()

Line and Marker Styling

import matplotlib.pyplot as plt

# Sample data
x_data = [1, 2, 3, 4, 5]
y_data = [2, 3, 5, 7, 11]

# Line style options
plt.plot(x_data, y_data, linestyle='--')  # Dashed
plt.plot(x_data, y_data, linestyle='-.')  # Dash-dot
plt.plot(x_data, y_data, linestyle=':')   # Dotted

# Color specification
plt.plot(x_data, y_data, color='red')
plt.plot(x_data, y_data, color='#FF5733')  # Hex code

# Marker configuration
plt.plot(x_data, y_data, marker='o')      # Circle
plt.plot(x_data, y_data, marker='s')      # Square
plt.plot(x_data, y_data, marker='^')      # Triangle

# Marker styling
plt.plot(x_data, y_data, marker='o', markerfacecolor='blue', 
         markeredgecolor='black', markersize=8)

# Line width control
plt.plot(x_data, y_data, linewidth=2)

# Combined styling
plt.plot(x_data, y_data, linestyle='--', color='red', linewidth=2, 
         marker='o', markersize=8)
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.title('Styled Plot Example')
plt.show()

Reference Lines

import matplotlib.pyplot as plt

fig, ax = plt.subplots()
ax.plot(range(10), range(10))

# Horizontal reference line
ax.axhline(y=5, color='r', linestyle='--', linewidth=2)

# Vertical reference line
ax.axvline(x=5, color='b', linestyle=':', linewidth=2)

# Limited span horizontal line
ax.axhline(y=0.5, xmin=0.25, xmax=0.75, color='green', 
           linestyle='-', linewidth=3)

plt.show()

Legend Configuration

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.lines import Line2D

x_range = np.linspace(0, 10, 100)
y_sine = np.sin(x_range)
y_cosine = np.cos(x_range)

# Basic legend
plt.plot(x_range, y_sine, label='sin(x)')
plt.plot(x_range, y_cosine, label='cos(x)')
plt.legend()

# Customized legend
plt.plot(x_range, y_sine, '-b', label='sin(x)')
plt.plot(x_range, y_cosine, '-r', label='cos(x)')
plt.legend(loc='upper right', frameon=False, title='Functions', 
           fontsize='large')

# Custom legend handles
custom_lines = [Line2D([0], [0], color='b', lw=4),
                Line2D([0], [0], color='r', lw=4)]
plt.plot(x_range, y_sine, '-b')
plt.plot(x_range, y_cosine, '-r')
plt.legend(custom_lines, ['sin(x)', 'cos(x)'], loc='best')

# External legend placement
fig, axes = plt.subplots(3, 3, figsize=(12, 10))
fig.legend(labels=unique_labels, bbox_to_anchor=(0.5, 0), 
          loc='lower center', ncol=5, fontsize=12)
plt.subplots_adjust(left=0.08, right=0.98, bottom=0.12, top=0.95, 
                   wspace=0.35, hspace=0.4)
plt.show()

Axis Tick Management

import matplotlib.pyplot as plt
from matplotlib.ticker import MultipleLocator, MaxNLocator, FuncFormatter
import numpy as np

# Basic tick access
fig, ax = plt.subplots()
ax.plot(range(10))
print("X tick labels:", [tick.get_text() for tick in ax.get_xticklabels()])
print("Y tick labels:", [tick.get_text() for tick in ax.get_yticklabels()])

# Custom tick labels
fig, ax = plt.subplots()
ax.plot(range(10))
ax.set_xticklabels(['zero', 'one', 'two', 'three', 'four', 'five', 
                   'six', 'seven', 'eight', 'nine'], rotation=45)
ax.set_yticklabels(['0%', '10%', '20%', '30%', '40%', '50%', 
                   '60%', '70%', '80%', '90%'])

# Tick positioning
fig, ax = plt.subplots()
ax.plot(range(100))
ax.xaxis.set_major_locator(MultipleLocator(20))
ax.yaxis.set_major_locator(MultipleLocator(10))

# Advanced tick configuration
def square_formatter(value, position):
    return f'{int(value**2)}'

fig, ax = plt.subplots()
x_values = np.linspace(0, 10, 100)
y_values = np.sin(x_values) * 100
ax.plot(x_values, y_values, label='100 * sin(x)')

ax.xaxis.set_major_locator(MultipleLocator(1))
ax.yaxis.set_major_locator(MaxNLocator(5))
ax.xaxis.set_major_formatter(FuncFormatter(square_formatter))

ax.tick_params(axis='x', direction='out', length=6, width=2, colors='blue',
               grid_color='gray', grid_alpha=0.5, labelsize='medium', 
               labelcolor='green', rotation=45)
ax.tick_params(axis='y', direction='inout', length=12, width=2, colors='red',
               grid_alpha=0.5, labelsize='small', labelcolor='purple', rotation=0)

ax.grid(True)
ax.legend()
plt.show()

Axis Position Adjustment

import matplotlib.pyplot as plt
import numpy as np

x_data = np.linspace(0, 10, 100)
y_data = np.sin(x_data)

fig, ax = plt.subplots()
ax.plot(x_data, y_data)

# Move y-axis to right side
ax.yaxis.set_ticks_position('right')
ax.yaxis.set_label_position('right')
ax.spines['right'].set_position(('outward', 0))
ax.spines['left'].set_position(('axes', 1.02))
ax.spines['left'].set_visible(False)
ax.set_ylabel('Amplitude', fontsize=14, fontweight='bold', labelpad=20)

plt.show()

Color Bar Implementation

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.ticker import FuncFormatter

# Basic color bar
data = np.random.rand(10, 10)
fig, ax = plt.subplots()
color_axis = ax.imshow(data, cmap='viridis')
color_bar = fig.colorbar(color_axis, ax=ax)

# Customized color bar
def percentage_format(x, pos):
    return f'{x:.1%}'

data = np.random.rand(10, 10)
fig, ax = plt.subplots()
color_axis = ax.imshow(data, cmap='viridis')
color_bar = fig.colorbar(color_axis, ax=ax, orientation='horizontal')

color_bar.set_label('Intensity Scale')
color_bar.set_ticks([0.1, 0.3, 0.5, 0.7, 0.9])
color_bar.set_ticklabels(['Very Low', 'Low', 'Medium', 'High', 'Very High'])
color_bar.set_formatter(FuncFormatter(percentage_format))

plt.show()

Bar Chart Creation

import matplotlib.pyplot as plt
import numpy as np

# Basic bar chart
categories = ['Category A', 'Category B', 'Category C', 'Category D']
values = [10, 15, 7, 12]

plt.bar(categories, values, color='blue', edgecolor='black')
plt.title('Basic Bar Chart')
plt.xlabel('Categories')
plt.ylabel('Values')
plt.show()

# Grouped bar chart
categories = ['A', 'B', 'C', 'D']
values1 = [10, 15, 7, 10]
values2 = [5, 3, 9, 11]
x_positions = np.arange(len(categories))
bar_width = 0.35

fig, ax = plt.subplots()
bars1 = ax.bar(x_positions - bar_width/2, values1, bar_width, label='Group 1')
bars2 = ax.bar(x_positions + bar_width/2, values2, bar_width, label='Group 2')

ax.set_xlabel('Categories')
ax.set_ylabel('Values')
ax.set_title('Grouped Bar Chart')
ax.set_xticks(x_positions)
ax.set_xticklabels(categories)
ax.legend()
plt.show()

# Bar chart with error bars
errors = [0.5, 1.0, 0.5, 1.2]
plt.bar(categories, values, color='skyblue', yerr=errors, capsize=5)
plt.show()

Text Object Management

import matplotlib.pyplot as plt

# Basic text addition
plt.plot([1, 2, 3], [4, 5, 6])
plt.text(2, 5, 'Sample Text')

# Text customization
plt.plot([1, 2, 3], [4, 5, 6])
plt.text(2, 5, 'Styled Text', fontsize=12, color='red', 
         ha='center', va='bottom', rotation=45)

# Text object manipulation
fig, ax = plt.subplots()
ax.plot([1, 2, 3], [4, 5, 6])
text_obj = ax.text(2, 5, 'Dynamic Text', fontsize=12, color='blue')
text_obj.set_fontsize(14)
text_obj.set_color('green')

# Text search and modification
fig, ax = plt.subplots()
ax.plot([1, 2, 3], [4, 5, 6])
text1 = ax.text(1, 4, 'First Annotation', fontsize=12, color='blue')
text2 = ax.text(2, 5, 'Second Annotation', fontsize=12, color='red')
text3 = ax.text(3, 6, 'Third Annotation', fontsize=12, color='green')

def modify_text(axis, search_text, new_text, new_color='black', new_size=14):
    for text_element in axis.findobj(match=plt.Text):
        if text_element.get_text() == search_text:
            text_element.set_text(new_text)
            text_element.set_color(new_color)
            text_element.set_fontsize(new_size)
            break

modify_text(ax, 'Second Annotation', 'Updated Text', 
           new_color='purple', new_size=16)

# Text with bounding box
fig, ax = plt.subplots()
ax.plot([1, 2, 3], [4, 5, 6])
text_element = ax.text(2, 5, 'Highlighted Text', fontsize=12, color='blue', 
                      ha='center', va='bottom', rotation=45)
text_element.set_bbox(dict(facecolor='yellow', alpha=0.5, edgecolor='red'))

plt.show()

Mathematical Notation

import matplotlib.pyplot as plt

# Superscript and subscript
plt.figure()
plt.plot([1, 2, 3, 4, 5], [1, 4, 9, 16, 25])
plt.title(r'$y = x^2$')
plt.xlabel(r'$x_1$')
plt.ylabel(r'$x_{in}^2$')
plt.annotate(r'$Coordinate\ (x_1^3)$', (3, 9), textcoords="offset points", 
            xytext=(0,10), ha='center')

# Regular text in math expressions
plt.figure()
plt.plot([1, 2, 3], [1, 4, 9])
plt.title(r'$\alpha^2 + \beta^2 = \mathregular{constant}$')
plt.xlabel(r'$\mathregular{Time (seconds)}$')
plt.ylabel(r'$\mathregular{Distance (meters)}$')
plt.show()

Tags: matplotlib

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.