Analyze the U.S. Unemployment Rate in Python
Use official U.S. unemployment data to build a repeatable Python workflow. This tutorial covers data access, cleaning, recent change measures, historical charts, a Plotly animation, and careful interpretation of the July 2026 labor market.
Table of contents What the rate tells us Get BLS or FRED data Set up Python Load and inspect data Clean the series Measure recent changes Historical chart Recent trend chart Animated unemployment trend What latest data means Unemployment and wages Common mistakes FAQ Methodology and sources
Python makes it easy to turn official labor market data into a repeatable monthly workflow. If you searched for unemployment rate analysis Python, this tutorial shows exactly how to load the U.S. unemployment series, clean it, measure recent changes, build charts, and explain the results without making the data sound more certain than it is.
The latest available Current Population Survey estimate is for July 2026. The seasonally adjusted U.S. unemployment rate was 4.1 percent, compared with 4.2 percent in June 2026 and 4.3 percent in July 2025. BLS also reported 6.9 million unemployed people in July. Those numbers are useful, but one month does not prove that a lasting trend has started.
The workflow below uses FRED for simple data access and BLS as the original statistical source. You will use pandas for cleaning and calculations, matplotlib for static charts, and Plotly for an animated view of annual unemployment history.
Quick answer
What the U.S. unemployment rate tells us
The unemployment rate is the share of the labor force that is unemployed and actively looking for work. The labor force includes people who have a job and people who do not have a job but are looking for one. People who are not working and are not actively looking are outside the labor force, so they are not counted as unemployed.
That detail matters. A lower unemployment rate can be good news when more people find jobs. It can also move lower when some people leave the labor force. This is why a careful labor market analysis Python workflow should look at the unemployment rate together with measures such as labor force participation and the employment population ratio.
Businesses watch unemployment because it can affect hiring conditions and wage pressure. Researchers use it to compare business cycles. Investors and policy analysts use it as one part of a wider economic picture. Job seekers may use it to understand how easy or hard it is to find work, although national data will not describe every local job market.
Get unemployment data from BLS or FRED
The U.S. Bureau of Labor Statistics is the original source for the national unemployment rate. The measure comes from the Current Population Survey. The seasonally adjusted national series ID is LNS14000000.
FRED, maintained by the Federal Reserve Bank of St. Louis, republishes the same headline series under the code UNRATE. FRED is convenient for Python because a simple CSV link can return the full history in one table. For this tutorial, we use FRED for access and BLS for source verification.
The series is monthly, seasonally adjusted, and begins in January 1948. At the time of this analysis, the latest observation is July 2026. The data were accessed and checked on August 18, 2026.
BLS can also revise seasonally adjusted household data when new seasonal factors are applied. If you save a chart today and rebuild it later, a few older values may differ slightly. Record the data access date so a reader can understand which data vintage you used.
Set up Python for unemployment rate analysis
You only need a small set of libraries. pandas handles the time series, matplotlib creates static charts, Plotly creates the animation, and requests is useful if you also want to call the BLS API directly.
pip install pandas matplotlib plotly requests
After installation, import the libraries in your analysis script or notebook.
import pandas as pd
import matplotlib.pyplot as plt
import plotly.express as px
Load and inspect the data
The simplest FRED data Python method for this series is the downloadable CSV endpoint. It does not need a FRED API key for this basic use.
url = "https://fred.stlouisfed.org/graph/fredgraph.csv?id=UNRATE"
unemployment = pd.read_csv(url)
unemployment = unemployment.rename(
columns={unemployment.columns[0]: "date", "UNRATE": "rate"}
)
print(unemployment.head())
print(unemployment.dtypes)
print(unemployment.tail())
This first check is simple but important. You want one date column and one unemployment rate column. You also want to confirm that the table starts in 1948 and reaches the latest published month. If the last date is older than the latest BLS release, do not publish until you know why.
Optional check with the BLS API
You can also request recent BLS unemployment data in Python. This is useful when you want the source data directly from BLS or when you are building a wider BLS workflow.
import requests
payload = {
"seriesid": ["LNS14000000"],
"startyear": "2022",
"endyear": "2026"
}
response = requests.post(
"https://api.bls.gov/publicAPI/v2/timeseries/data/",
json=payload,
timeout=30
)
bls_data = response.json()
print(bls_data["Results"]["series"][0]["data"][:3])
The BLS public API has request limits, so a registration key can be useful for larger jobs. For a full historical tutorial, the FRED CSV remains easier because it returns the long series in one request.
Clean and prepare the unemployment series
Economic time series often look clean until one missing value or text field breaks a calculation. Convert the date column, convert the rate column to numeric values, sort by time, then check the missing rows.
unemployment["date"] = pd.to_datetime(unemployment["date"])
unemployment["rate"] = pd.to_numeric(
unemployment["rate"], errors="coerce"
)
unemployment = unemployment.sort_values("date").reset_index(drop=True)
print(unemployment.dtypes)
print(unemployment["date"].min())
print(unemployment["date"].max())
print(unemployment[unemployment["rate"].isna()])
The October 2025 row should remain missing. That gap is not a coding error. It reflects a real break in data collection. For descriptive charts, leaving the value missing is the most transparent choice.
Do not fill the gap unless your research design truly needs a complete monthly series. If you estimate a value for a model, label it as an estimate and keep the original BLS observation separate from the modeled value.
Measure recent changes in unemployment
Now calculate the measures a reader is most likely to care about. The code below finds the latest rate, the previous published month, the value 12 months earlier, the recent observed range, and the long run average.
valid = unemployment.dropna(subset=["rate"]).copy()
latest = valid.iloc[-1]
previous = valid.iloc[-2]
year_ago_date = latest["date"] - pd.DateOffset(years=1)
year_ago = unemployment.loc[
unemployment["date"].eq(year_ago_date), "rate"
].iloc[0]
recent_start = latest["date"] - pd.DateOffset(months=11)
recent = unemployment[
unemployment["date"].between(recent_start, latest["date"])
]
monthly_change = latest["rate"] - previous["rate"]
yearly_change = latest["rate"] - year_ago
recent_min = recent["rate"].min()
recent_max = recent["rate"].max()
long_run_average = unemployment["rate"].mean()
For July 2026, the calculation gives a 4.1 percent unemployment rate. That is 0.1 percentage point lower than June 2026 and 0.2 percentage point lower than July 2025. The recent 12 month window has 11 observed months because October 2025 is missing.
Current unemployment summary
| Metric | Value | Reference period |
|---|---|---|
| Latest unemployment rate | 4.1% | July 2026 |
| Previous published month | 4.2% | June 2026 |
| 12 months earlier | 4.3% | July 2025 |
| Monthly change | 0.1 point lower | June to July 2026 |
| 12 month change | 0.2 point lower | July 2025 to July 2026 |
| Recent observed minimum | 4.1% | August 2025 to July 2026 |
| Recent observed maximum | 4.5% | August 2025 to July 2026 |
| Long run average | 5.7% | January 1948 to July 2026 |
The long run average is about 5.7 percent. That does not mean 5.7 percent is a target or a normal rate for every period. It is only a simple historical average across a series that includes recessions, recoveries, demographic change, and major economic shocks.
Plot the U.S. unemployment rate in Python
A long historical chart gives the latest number context. The line below uses every published monthly observation and leaves missing values as gaps.
fig, ax = plt.subplots(figsize=(10, 5))
ax.plot(unemployment["date"], unemployment["rate"], linewidth=1.5)
ax.set_title("U.S. Unemployment Rate, January 1948 to Latest")
ax.set_xlabel("Year")
ax.set_ylabel("Unemployment rate, percent")
ax.grid(True, alpha=0.25)
plt.show()
Monthly U.S. unemployment rate, 1948 to July 2026
Interactive chart. Hover to inspect any published month.
The historical series shows why context matters. The unemployment rate has moved through many cycles, and the April 2020 shock stands far above most of the record. In the data used here, the series reaches 14.8 percent in April 2020 and a low of 2.5 percent in 1953. The July 2026 rate of 4.1 percent sits below the full period average of about 5.7 percent.
That comparison is descriptive, not a forecast. A rate below the long run average does not tell us what unemployment will do next month. It only helps us place the latest observation in the history of the series.
Look more closely at recent unemployment trends
The full history is useful, but it compresses recent changes. A second chart focused on the latest 36 months makes small moves easier to see.
latest_date = valid["date"].max()
recent_36 = unemployment[
unemployment["date"] >= latest_date - pd.DateOffset(months=35)
]
fig, ax = plt.subplots(figsize=(10, 5))
ax.plot(
recent_36["date"],
recent_36["rate"],
marker="o",
markersize=3,
linewidth=1.5
)
ax.set_title("Recent U.S. Unemployment Rate")
ax.set_xlabel("Month")
ax.set_ylabel("Unemployment rate, percent")
ax.grid(True, alpha=0.25)
plt.show()
Recent U.S. unemployment rate
August 2023 through July 2026, with the October 2025 gap preserved.
The recent view shows a gradual rise from the very low rates seen earlier in the period, followed by a narrow range during much of 2025 and early 2026. Within the latest 12 month window, the observed rate ranges from 4.1 percent to 4.5 percent. July 2026 is at the bottom of that observed range.
BLS still described the July unemployment rate as changed little. That language is a useful reminder that monthly survey estimates have sampling error. A move of one tenth of a percentage point can matter, but it should not be treated as a major turning point by itself.
Animate the long term unemployment trend
Animation can help a reader see how the U.S. labor market changed over decades. For a smoother view, calculate annual averages and reveal one additional year in each frame.
There is one special choice in this dataset. Since October 2025 was not collected, 2025 does not contain all 12 monthly observations. The animation below uses only years with 12 published monthly values, so 2024 is the latest complete year.
annual = (
unemployment.assign(year=unemployment["date"].dt.year)
.groupby("year")["rate"]
.agg(["mean", "count"])
.reset_index()
)
annual_complete = annual[annual["count"] == 12].copy()
annual_complete = annual_complete.rename(columns={"mean": "rate"})
frames = []
for end_year in annual_complete["year"]:
part = annual_complete[annual_complete["year"] <= end_year].copy()
part["frame_year"] = end_year
frames.append(part)
animated = pd.concat(frames, ignore_index=True)
fig = px.line(
animated,
x="year",
y="rate",
animation_frame="frame_year",
range_x=[1948, annual_complete["year"].max()],
range_y=[0, annual_complete["rate"].max() + 1],
title="Annual Average U.S. Unemployment Rate"
)
fig.update_xaxes(title="Year")
fig.update_yaxes(title="Annual average unemployment rate, percent")
fig.show()
Animated annual average U.S. unemployment rate
Press Play to reveal one complete year at a time. Use Pause or drag the year slider to inspect a specific point in history.
Watch how high unemployment periods stand out from long stretches of lower unemployment. The goal is not visual decoration. The animation makes the sequence of labor market cycles easier to follow, especially for readers who are new to time series analysis.
What the latest unemployment data means
The latest facts are straightforward. The U.S. unemployment rate was 4.1 percent in July 2026. It was 4.2 percent in June and 4.3 percent a year earlier. BLS counted about 6.9 million unemployed people. The rate is also below the long run average in the monthly series used for this tutorial.
Still, the unemployment rate is not the whole labor market. In July, BLS reported a labor force participation rate of 61.4 percent and an employment population ratio of 58.9 percent. Both changed little during the month. Since January, BLS reported declines in both measures. That wider context is one reason a lower unemployment rate should not automatically be read as a stronger labor market.
Payroll employment also changed little in July, with a reported change of 23,000 fewer nonfarm payroll jobs. BLS revised the May and June payroll gains lower as more information arrived. Those revisions show why analysts should separate the latest estimate from a final statement about economic direction.
A careful interpretation is that unemployment remained relatively low by long historical standards in July 2026, while other labor market measures showed a softer picture than the unemployment rate alone. That is an observation based on several indicators, not a prediction about the next release.
How unemployment can relate to wages
Unemployment and wages can move together because employers compete for workers. When unemployment is low and qualified workers are hard to find, firms may raise pay to attract or keep staff. When labor demand weakens, workers may have less bargaining power. This relationship is useful, but it is not automatic.
In July 2026, BLS reported average hourly earnings of 37.62 dollars for employees on private nonfarm payrolls. That was 3.2 percent higher than a year earlier in nominal terms. A separate BLS real earnings release showed average hourly earnings adjusted for inflation were 0.2 percent lower from July 2025 to July 2026.
Those two facts show why wage analysis needs more than one number. Inflation, productivity, worker skills, industry mix, hours, bargaining conditions, and labor demand can all affect pay. Use unemployment as one input in a wage study, not as a single cause of wage growth.
Common mistakes in unemployment analysis
- Confusing unemployment with labor force participation. A person can be without a job and still not count as unemployed if that person is not actively looking for work.
- Ignoring missing data. October 2025 is not a normal blank value. It is a known gap in Current Population Survey collection.
- Mixing seasonally adjusted and unadjusted rates. Use one basis consistently unless you have a clear reason to compare them.
- Reacting too strongly to one month. Small monthly moves can reverse and survey estimates contain sampling error.
- Treating the long run average as a target. A historical mean is a descriptive benchmark, not an official estimate of full employment.
- Using unclear chart scales. Label percent values clearly and keep the same unit across related charts.
- Treating correlation as proof of cause. Unemployment, wages, inflation, and growth affect each other through many channels.
- Forgetting data revisions and access dates. Save the source series ID and the date you downloaded the data.
Conclusion
A strong unemployment rate analysis Python workflow is more than a line chart. Start with an official series, clean dates and numeric values, keep real missing observations visible, calculate recent changes, and compare the latest rate with both recent and long history. Then explain what the data can tell us and what it cannot.
The same code can be reused when BLS publishes a new month. Refresh the FRED CSV, verify the latest number against BLS, rebuild the summary table and charts, and update the interpretation. That repeatable process is more useful than a one time chart because it gives you a consistent way to track the U.S. labor market over time.
Frequently asked questions
How do I get U.S. unemployment data in Python?Use FRED series UNRATE for a simple CSV download, or request BLS series LNS14000000 through the BLS public API. Convert the date field with pandas, convert the rate to numeric values, sort by date, then check missing observations before calculating changes.
What is the FRED series code for the U.S. unemployment rate?The FRED series code is UNRATE. It represents the seasonally adjusted civilian unemployment rate for the United States and is sourced from the U.S. Bureau of Labor Statistics.
What is the BLS series code for the unemployment rate?The BLS series code used in this tutorial is LNS14000000. It is the seasonally adjusted unemployment rate for the civilian labor force.
Is the U.S. unemployment rate seasonally adjusted?BLS publishes both adjusted and unadjusted measures. This tutorial uses the seasonally adjusted headline series because it removes recurring seasonal patterns and makes month to month comparisons easier.
How can I plot unemployment over time with pandas and matplotlib?Load the series into a pandas DataFrame, parse the date column, convert the rate column to numeric values, then pass the date and rate columns to matplotlib. Add a title, axis labels, and a source note so the chart is easy to understand and cite.
Why can unemployment fall even when job growth is weak?The unemployment rate depends on both unemployed people and the size of the labor force. If people stop looking for work, they can leave the labor force and no longer count as unemployed. This is why participation and employment measures should be checked with the unemployment rate.
Methodology note
| Primary source | U.S. Bureau of Labor Statistics |
| Series ID | LNS14000000 |
| FRED mirror | UNRATE |
| Observation range used | January 1948 through July 2026 |
The recent 12-month range uses the available published observations from August 2025 through July 2026. It contains 11 observations because October 2025 was not collected. Annual animation calculations use only years with 12 published monthly observations, which makes 2024 the latest complete year in the animation. Economic data and seasonal factors can be revised.
Suggested internal links
- How to analyze FRED data with Python
- Wage growth analysis with Python and BLS data
- Labor force participation rate analysis in pandas
- Python time series visualization with matplotlib and Plotly
- U.S. economic indicators for data analysis projects
Official sources
Data tutorial prepared from official U.S. labor market sources.
Download Complete Analysis File
Downloads
Files attached to this article for your reference.
