Source code for dsci_524_ezplot.plot_line

import matplotlib.pyplot as plt
import pandas as pd

[docs] def plot_line(df, x, y, title=None, xlabel=None, ylabel=None, x_decimals=None, y_decimals=None): """ Create a line plot using data from a pandas DataFrame. Parameters ---------- df : pandas.DataFrame Input DataFrame containing the data to plot x : str Column name for x-axis values y : str Column name for y-axis values title : str, optional Title of the plot (default: None) xlabel : str, optional Label for x-axis (default: x column name) ylabel : str, optional Label for y-axis (default: y column name) x_decimals : int, optional Number of decimal places for x-axis values (default: None) y_decimals : int, optional Number of decimal places for y-axis values (default: None) Returns ------- tuple - matplotlib.figure.Figure The figure object containing the plot - matplotlib.axes.Axes The axes object containing the plot elements Examples -------- >>> import pandas as pd >>> df = pd.DataFrame({'year': [2020, 2021, 2022], 'sales': [100, 150, 200]}) >>> fig, ax = plot_line(df, 'year', 'sales', 'Annual Sales', 'Year', 'Sales', ... x_decimals=0, y_decimals=2) """ # Data validation if len(df) < 2: raise ValueError("At least 2 data points are required to plot a line") if df[x].isna().any() or df[y].isna().any(): raise ValueError("Data contains missing values") if not (pd.api.types.is_numeric_dtype(df[x]) and pd.api.types.is_numeric_dtype(df[y])): raise ValueError("Both x and y must be numeric") if df[x].isin([float('inf'), float('-inf')]).any() or df[y].isin([float('inf'), float('-inf')]).any(): raise ValueError("Data contains invalid values (infinity)") if (df[x] < 0).any(): raise ValueError(f"All values in {x} must be non-negative") if (df[y] < 0).any(): raise ValueError(f"All values in {y} must be non-negative") # Create plot fig, ax = plt.subplots() ax.plot(df[x], df[y]) # Set labels and title ax.set_title(title) ax.set_xlabel(xlabel) ax.set_ylabel(ylabel) # Set decimal formatting if x_decimals is not None: ax.xaxis.set_major_formatter(plt.FuncFormatter(lambda x, p: f"{x:.{x_decimals}f}")) if y_decimals is not None: ax.yaxis.set_major_formatter(plt.FuncFormatter(lambda x, p: f"{x:.{y_decimals}f}")) return fig, ax