Your first chart
Hook
Numbers are how you find the story. Charts are how you tell it. Your first chart doesn’t need to be pretty — it needs a title, axis labels, and a data source.
Concept
matplotlib’s basic chart loop:
- Pull the data into a DataFrame.
- Pick the right chart type. Comparing values across categories → bar chart.
- Plot.
df.plot(kind='bar', x='label', y='value'). - Add title, axis labels, and a source caption. Always.
- Save or
plt.show().
import matplotlib.pyplot as pltimport pandas as pdfrom sqlalchemy import create_engine
eng = create_engine("postgresql+psycopg://onepride:lions@localhost:5432/onepride")
df = pd.read_sql( """SELECT player_display_name, SUM(rushing_yards) AS yards FROM weekly_stats WHERE recent_team = 'DET' AND season = 2024 AND season_type = 'REG' GROUP BY player_display_name ORDER BY yards DESC LIMIT 5""", eng,)
ax = df.plot(kind='barh', x='player_display_name', y='yards', color='#0076B6', legend=False, figsize=(7, 4))ax.invert_yaxis() # top bar = leaderax.set_title('Lions 2024 rushing leaders (regular season)')ax.set_xlabel('Rushing yards')ax.set_ylabel('')ax.figure.text(0.99, 0.01, 'Source: nflverse', ha='right', fontsize=8, color='gray')plt.tight_layout()plt.savefig('rushing-leaders-2024.png', dpi=150)(GROUP BY is technically Level 2 territory — but you can use the snippet
above and read it as “sum per player.” You’ll write your own next level.)
Lions example
The snippet above is the example. Run it in a Jupyter cell and you’ll get a horizontal bar chart with Jahmyr Gibbs on top (≈1,400 rushing yards), David Montgomery second (≈775), then situational backs below.
A few small choices that matter:
- Horizontal bars (
barh) when labels are long names. Vertical bar charts cram or rotate the labels. - Invert the y-axis so the leader is on top — that’s the convention readers expect.
color='#0076B6'— one color, the 1PRIDE accent. No rainbow per bar.- A source caption. Always. Charts get screenshotted out of context.
Try it
Make a bar chart of Lions passing yards by week for 2024 regular season. Use
vertical bars (kind='bar'), week on the x-axis, yards on the y-axis. Title,
axis labels, source caption — all three.
Common mistakes
- No title. A chart without a title is a Rorschach test.
- No source. You can always re-find it, but the reader can’t.
- Default matplotlib palette. Tab-orange and sky-blue everywhere. Pick a
color that matches your subject. Honolulu Blue (
#0076B6) for Lions charts. - Skipping
plt.tight_layout(). Long labels get cut off in the saved PNG. plt.savefigafterplt.show().plt.show()resets the figure in some setups. Save first, then show — or skip show and just save.
Quick check
- Why
barhinstead ofbarfor player-name bar charts? - What three labels does every chart need?
- What does
ax.invert_yaxis()do in a horizontal bar chart, and why?