#!/usr/bin/env python3 """ Generate a python script that produces, for a given csv file, a png file that depicts a 2d graph where the x-axis is derived from the content of the first column of the csv file. The y-axis is derived from the content of the remaining columns. Show a separate graph for each remaining column using a unique color and add a legend derived from the remaining column names. Show the legend as title on top. Label the y-axis "#solved instances" and use integers only. make background white. Derive the name of the png file from the name of the csv file. Format long legends into a multi-line legend that is not wider than the chart. Add unique dot types for each graph. Only label x-axis if there are data points. Add prompt as comment. """ import pandas as pd import matplotlib.pyplot as plt from matplotlib.ticker import MaxNLocator import sys import os import textwrap import itertools def generate_graph(csv_file): # Check if file exists if not os.path.exists(csv_file): print(f"Error: The file '{csv_file}' was not found.") return # Derive output filename base_name = os.path.splitext(csv_file)[0] output_file = f"{base_name}.png" try: # Read the CSV df = pd.read_csv(csv_file) # Validation if len(df.columns) < 2: print("Error: CSV must have at least two columns.") return x_col = df.columns[0] y_cols = df.columns[1:] # Setup Plot fig, ax = plt.subplots(figsize=(10, 6)) # Set background to white fig.patch.set_facecolor('white') ax.set_facecolor('white') # Define a list of distinct markers marker_list = ['o', 's', '^', 'D', 'v', '<', '>', 'p', '*', 'h', 'X', 'd'] marker_cycle = itertools.cycle(marker_list) # Plot Data for col in y_cols: current_marker = next(marker_cycle) ax.plot(df[x_col], df[col], label=col, marker=current_marker) # Formatting Y-Axis ax.set_ylabel("#solved instances") ax.yaxis.set_major_locator(MaxNLocator(integer=True)) # Integers only # Formatting X-Axis ax.set_xlabel(x_col) # Force ticks to appear ONLY at the data points present in the X column ax.set_xticks(df[x_col]) # --- LEGEND FORMATTING --- handles, labels = ax.get_legend_handles_labels() # Wrap long label text labels = [ '\n'.join(textwrap.wrap(l, 25)) for l in labels ] # Limit columns to max 4 max_legend_cols = 4 actual_cols = min(len(labels), max_legend_cols) # Place legend as title on top ax.legend(handles, labels, loc='lower center', bbox_to_anchor=(0.5, 1.05), ncol=actual_cols, frameon=False, fontsize='medium', borderaxespad=0) # ------------------------- plt.tight_layout() # Save plt.savefig(output_file, dpi=300, bbox_inches='tight') print(f"Graph saved successfully to '{output_file}'") except Exception as e: print(f"An error occurred: {e}") if __name__ == "__main__": if len(sys.argv) != 2: print("Usage: python plot_csv.py ") else: generate_graph(sys.argv[1])