Skip to content

Commit c2590b0

Browse files
authored
feat: add image export capability to iris_analysis.py
Added save_visualizations(df, outdir='images') to export example plots as PNGs. Also added a CLI flag (--save-figs) so the script can be run headlessly to generate images for README previews and documentation. Uses matplotlib Agg backend for headless compatibility.
1 parent 601dbe6 commit c2590b0

1 file changed

Lines changed: 71 additions & 0 deletions

File tree

iris_analysis.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,74 @@ def load_and_inspect_iris():
4343

4444
if __name__ == "__main__":
4545
df = load_and_inspect_iris()
46+
47+
import os
48+
import matplotlib
49+
# Use Agg backend for headless environments (safe for servers and CI)
50+
matplotlib.use('Agg')
51+
import matplotlib.pyplot as plt
52+
import seaborn as sns
53+
54+
def save_visualizations(df, outdir='images'):
55+
"""Save example visualizations to `outdir` (PNG files)."""
56+
os.makedirs(outdir, exist_ok=True)
57+
sns.set(style="whitegrid")
58+
59+
# 1) Line chart (simulated trend)
60+
fig, ax = plt.subplots(figsize=(8, 4))
61+
ax.plot(df.index, df['sepal length (cm)'], label='Sepal Length')
62+
ax.plot(df.index, df['sepal width (cm)'], label='Sepal Width')
63+
ax.set_title('Sepal Length and Width Trends')
64+
ax.set_xlabel('Sample Index')
65+
ax.set_ylabel('Centimeters')
66+
ax.legend()
67+
fig.tight_layout()
68+
fig.savefig(os.path.join(outdir, 'line_sepal_trends.png'), dpi=150, bbox_inches='tight')
69+
plt.close(fig)
70+
71+
# 2) Bar chart (average petal length by species)
72+
mean_petal_length = df.groupby('species')['petal length (cm)'].mean().reset_index()
73+
fig, ax = plt.subplots(figsize=(6, 4))
74+
sns.barplot(data=mean_petal_length, x='species', y='petal length (cm)', ax=ax)
75+
ax.set_title('Average Petal Length by Species')
76+
ax.set_xlabel('Species')
77+
ax.set_ylabel('Average Petal Length (cm)')
78+
fig.tight_layout()
79+
fig.savefig(os.path.join(outdir, 'bar_mean_petal_length.png'), dpi=150, bbox_inches='tight')
80+
plt.close(fig)
81+
82+
# 3) Histogram (petal width distribution)
83+
fig, ax = plt.subplots(figsize=(6, 4))
84+
ax.hist(df['petal width (cm)'], bins=15, edgecolor='black')
85+
ax.set_title('Distribution of Petal Width')
86+
ax.set_xlabel('Petal Width (cm)')
87+
ax.set_ylabel('Frequency')
88+
fig.tight_layout()
89+
fig.savefig(os.path.join(outdir, 'hist_petal_width.png'), dpi=150, bbox_inches='tight')
90+
plt.close(fig)
91+
92+
# 4) Scatter plot (sepal length vs petal length)
93+
fig, ax = plt.subplots(figsize=(6, 4))
94+
sns.scatterplot(data=df, x='sepal length (cm)', y='petal length (cm)', hue='species', ax=ax)
95+
ax.set_title('Sepal Length vs Petal Length by Species')
96+
ax.set_xlabel('Sepal Length (cm)')
97+
ax.set_ylabel('Petal Length (cm)')
98+
ax.legend(title='Species')
99+
fig.tight_layout()
100+
fig.savefig(os.path.join(outdir, 'scatter_sepal_vs_petal.png'), dpi=150, bbox_inches='tight')
101+
plt.close(fig)
102+
103+
print(f"Saved visualizations to '{outdir}/'")
104+
105+
if __name__ == "__main__":
106+
import argparse
107+
parser = argparse.ArgumentParser(description="Iris dataset analysis and optional figure export")
108+
parser.add_argument("--save-figs", action="store_true", help="Generate and save example plots to ./images/")
109+
args = parser.parse_args()
110+
111+
df = load_and_inspect_iris()
112+
if df is None:
113+
raise SystemExit("Failed to load dataset. Exiting.")
114+
115+
if args.save_figs:
116+
save_visualizations(df)

0 commit comments

Comments
 (0)