sns.lineplot connects values along x. With hue, each group gets its own line. Order categorical months yourself or seaborn will sort alphabetically.
Goal
Plot rainfall by month for three cities, with markers and an ordered x-axis.
One series
df = pd.DataFrame(
{
"month": ["Jan", "Feb", "Mar", "Apr"],
"rain": [50, 40, 80, 150],
}
)
sns.lineplot(data=df, x="month", y="rain", marker="o")
plt.ylabel("mm")
plt.title("Nairobi rainfall")
plt.show()Hue by city
df = pd.DataFrame(
{
"month": ["Jan", "Feb", "Mar", "Apr"] * 3,
"city": ["Nairobi"] * 4 + ["Mombasa"] * 4 + ["Kisumu"] * 4,
"rain": [50, 40, 80, 150, 20, 15, 30, 90, 70, 80, 120, 180],
}
)
df["month"] = pd.Categorical(
df["month"], categories=["Jan", "Feb", "Mar", "Apr"], ordered=True
)
sns.lineplot(data=df, x="month", y="rain", hue="city", marker="o")
plt.ylabel("mm")
plt.title("Rainfall by city")
plt.show()Without the Categorical, April can appear before February because "Apr" < "Feb" as text.
Error band
rng = np.random.default_rng(0)
rows = []
for city, mean in [("Nairobi", 80), ("Mombasa", 40), ("Kisumu", 110)]:
for month in ["Jan", "Feb", "Mar", "Apr"]:
for _ in range(6):
rows.append(
{
"city": city,
"month": month,
"rain": mean + rng.normal(0, 12),
}
)
df = pd.DataFrame(rows)
df["month"] = pd.Categorical(
df["month"], categories=["Jan", "Feb", "Mar", "Apr"], ordered=True
)
sns.lineplot(data=df, x="month", y="rain", hue="city", marker="o")
plt.ylabel("mm")
plt.title("Mean with 95% CI")
plt.show()Several rows per city–month make seaborn draw a confidence interval around the mean. Pass errorbar=None to hide it.
Pitfall
lineplot aggregates duplicate x values. If you already have one row per point, that is fine — there is nothing to average.