Issue
I have this df:
Month Sector CWD
2592 1 COAST1 0.0
2593 2 COAST1 1.0
2594 3 COAST1 2.0
2595 4 COAST1 2.0
2596 5 COAST1 5.0
... ... ...
4363 8 COAST1 0.0
4364 9 COAST1 4.0
4365 10 COAST1 1.0
4366 11 COAST1 2.0
4367 12 COAST1 0.0
2592 1 COAST2 0.0
2593 2 COAST2 1.0
2594 3 COAST2 2.0
2595 4 COAST2 2.0
2596 5 COAST2 5.0
... ... ...
4363 8 COAST2 0.0
4364 9 COAST2 4.0
4365 10 COAST2 1.0
4366 11 COAST2 2.0
4367 12 COAST2 0.0
2592 1 JUNGL1 3.0
2593 2 JUNGL1 1.0
2594 3 JUNGL1 0.0
2595 4 JUNGL1 5.0
2596 5 JUNGL1 5.0
... ... ...
4363 8 JUNGL1 0.0
4364 9 JUNGL1 0.0
4365 10 JUNGL1 0.0
4366 11 JUNGL1 0.0
4367 12 JUNGL1 0.0
... ... ...
I want to plot grouped bar charts by df['Sector'] with x=df['Month'] and y=df['CWD']. Each df['Sector'] must have a bar (with different color). I want a graphic like this:
But there are more than 30 kind of Sectors. So i must plot 30 bars for each df['Month'] value. I tried this code:
fig = plt.figure('Graphic', figsize=(20,15), dpi=300)
ax1 = fig.add_axes([0.2, 0.25, 0.80, 0.60])
width=0.25
i=0
for i in df:
bar1 = plt.bar(df['Month']+width*i, df['CWD'], width, color = 'r')
But i get this error: TypeError: can't multiply sequence by non-int of type 'float'
PD: I need to iterate the color too (with random colors).
Would you mind to help me? Thanks in advance.
Solution
With the following toy dataframe:
import pandas as pd
df = pd.DataFrame({"Month": [1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 7, 7, 7, 6, 6, 6], "Sector": ["COAST1", "COAST1", "COAST1", "COAST1", "COAST1", "COAST1", "COAST1", "COAST1", "COAST1", "COAST1", "COAST2", "COAST2", "COAST2", "COAST2", "COAST2", "COAST2", "COAST2", "COAST2", "COAST2", "COAST2", "JUNGL1", "JUNGL1", "JUNGL1", "JUNGL1", "JUNGL1", "JUNGL1", "JUNGL1", "JUNGL1", "JUNGL1", "JUNGL1", "COAST1", "JUNGL1", "COAST2", "JUNGL1", "JUNGL1", "COAST1"], "CWD": [9.0, 1.0, 2.0, 8.0, 5.0, 8.0, 4.0, 6.0, 2.0, 3.0, 5.0, 1.0, 2.0, 5.0, 4.0, 8.0, 1.0, 1.0, 2.0, 9.0, 3.0, 8.0, 6.0, 7.0, 5.0, 1.0, 6.0, 4.0, 9.0, 2.0, 3.0, 4.0, 5.0, 8.0, 7.0, 2.0]})
Here is one way to do it:
import matplotlib
import numpy as np
from matplotlib import pyplot as plt
# Setup
df = df.sort_values(by=["Month", "Sector"]).reset_index(drop=True)
fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(10, 3))
width = 1
# Define colors for each unique sector
cm = plt.get_cmap("gist_rainbow")
mapping = {sector: cm(i * 100) for i, sector in enumerate(df["Sector"].unique())}
df["Colors"] = df["Sector"].apply(lambda x: mapping[x])
df["Colors"] = df["Colors"].apply(
lambda x: matplotlib.colors.rgb2hex(x, keep_alpha=True)
)
# Plot bars
for i in df["Month"].unique():
ax.bar(
x=[
i * 10 + x * width * 2
for x in range(1, df.loc[df["Month"] == i].shape[0] + 1)
],
height=df.loc[df["Month"] == i, "CWD"],
width=width,
color=df.loc[df["Month"] == i, "Colors"].tolist(),
)
# Position ticks and labels on x-axis
ax.set_xticks(
ticks=[
np.mean(
[
i * 10 + x * width * 2
for x in range(1, df.loc[df["Month"] == i].shape[0] + 1)
]
)
for i in df["Month"].unique()
]
)
ax.set_xticklabels(df["Month"].unique(), fontsize=10)
# In a Jupyter cell
fig
Output:
Answered By - Laurent
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.