0% found this document useful (0 votes)
11 views22 pages

Python Visualization 1729600822

Uploaded by

S H PRAJWAL
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
11 views22 pages

Python Visualization 1729600822

Uploaded by

S H PRAJWAL
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 22

Blue Economy Project Visualization

Developed by: Abu Kibria, PhD

NC State University

October 10, 2024

In [45]: import matplotlib.pyplot as plt


import seaborn as sns
import pandas as pd

# Load data
be_dt = pd.read_excel("Cost by Project Stage.xlsx", sheet_name='kb_grphc')

# Extract columns for each stage


ax_a = be_dt['cost_bucket']
ay_p1 = be_dt['proj_scp_feasb']
ay_p2 = be_dt['proj_set_vald']
ay_p3 = be_dt['proj_dev']
ay_p4 = be_dt['mont_verif']
ay_p5 = be_dt['crdt_issu']
ay_p6 = be_dt['crdt_sale']

# Set font family for the entire plot


plt.rcParams["font.family"] = "Arial"
plt.rcParams["font.size"] = 11

# Create subplots with shared y-axis and shared x-axis


fig, axes = plt.subplots(nrows=1, ncols=6, figsize=(15, 6), sharey=True, sharex=Tr

# Colorblind-friendly color palette


colorblind_palette = sns.color_palette("colorblind")

# Plot each horizontal bar chart in a separate axis


bars1 = axes[0].barh(ax_a, ay_p1, color=colorblind_palette[0])
axes[0].set_title('Feasibility')

bars2 = axes[1].barh(ax_a, ay_p2, color=colorblind_palette[1])


axes[1].set_title('Validation')

bars3 = axes[2].barh(ax_a, ay_p3, color=colorblind_palette[2])


axes[2].set_title('Development')

bars4 = axes[3].barh(ax_a, ay_p4, color=colorblind_palette[3])


axes[3].set_title('Verification')

bars5 = axes[4].barh(ax_a, ay_p5, color=colorblind_palette[4])


axes[4].set_title('Credit Issue')
bars6 = axes[5].barh(ax_a, ay_p6, color=colorblind_palette[5])
axes[5].set_title('Credit Sale')

# Add the title "Conservation"


fig.suptitle('Conservation', fontsize=16, y=1.03, weight= 'bold')
# Set common labels for x and y axes
fig.text(0.5, .01, 'USD', ha='center', va='center', fontsize=12) # Common x-axis
fig.text(0.04, 0.5, '', ha='center', va='center', rotation='vertical', fontsize=12

# Set individual tick parameters


for ax in axes:
ax.tick_params(axis='x', labelsize=10) # x-axis now at the bottom
ax.tick_params(axis='y', labelsize=10) # y-axis labels (cost buckets) on the

# Remove top and right spines


ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)

# Remove gap between the graphs by adjusting the layout and setting w_pad to 0
plt.tight_layout(pad=0.5, w_pad=0, h_pad=0) # Adjust rect to remove gaps

# Display the plot


plt.show()

In [47]: import matplotlib.pyplot as plt


import seaborn as sns
import pandas as pd

# Load data
be_dt = pd.read_excel("Cost by Project Stage.xlsx", sheet_name='kb_grphr')

# Extract columns for each stage


ax_a = be_dt['cost_bucket']
ay_p1 = be_dt['proj_scp_feasb']
ay_p2 = be_dt['proj_set_vald']
ay_p3 = be_dt['proj_dev']
ay_p4 = be_dt['mont_verif']
ay_p5 = be_dt['crdt_issu']
ay_p6 = be_dt['crdt_sale']

# Set font family for the entire plot


plt.rcParams["font.family"] = "Arial"
plt.rcParams["font.size"] = 11

# Create subplots with shared y-axis and shared x-axis


fig, axes = plt.subplots(nrows=1, ncols=6, figsize=(15, 6), sharey=True, sharex=Tr

# Colorblind-friendly color palette


colorblind_palette = sns.color_palette("colorblind")

# Plot each horizontal bar chart in a separate axis


bars1 = axes[0].barh(ax_a, ay_p1, color=colorblind_palette[0])
axes[0].set_title('Feasibility')

bars2 = axes[1].barh(ax_a, ay_p2, color=colorblind_palette[1])


axes[1].set_title('Validation')

bars3 = axes[2].barh(ax_a, ay_p3, color=colorblind_palette[2])


axes[2].set_title('Development')

bars4 = axes[3].barh(ax_a, ay_p4, color=colorblind_palette[3])


axes[3].set_title('Verification')

bars5 = axes[4].barh(ax_a, ay_p5, color=colorblind_palette[4])


axes[4].set_title('Credit Issue')

bars6 = axes[5].barh(ax_a, ay_p6, color=colorblind_palette[5])


axes[5].set_title('Credit Sale')

# Add the title "Conservation"


fig.suptitle('Restoration', fontsize=16, y=1.03, weight= 'bold')
# Set common labels for x and y axes
fig.text(0.5, .01, 'USD', ha='center', va='center', fontsize=12) # Common x-axis
fig.text(0.04, 0.5, '', ha='center', va='center', rotation='vertical', fontsize=12

# Set individual tick parameters


for ax in axes:
ax.tick_params(axis='x', labelsize=10) # x-axis now at the bottom
ax.tick_params(axis='y', labelsize=10) # y-axis labels (cost buckets) on the

# Remove top and right spines


ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)

# Remove gap between the graphs by adjusting the layout and setting w_pad to 0
plt.tight_layout(pad=0.5, w_pad=0, h_pad=0) # Adjust rect to remove gaps

# Display the plot


plt.show()

In [61]: import matplotlib.pyplot as plt


import seaborn as sns
import pandas as pd

# Load data
be_dt = pd.read_excel("Cost by Project Stage.xlsx", sheet_name='Cost_stage')

# Sample data from your be_dt DataFrame


ax_a = be_dt['Project Phase']
ay_p1 = be_dt['Conservation']
ay_p2 = be_dt['Restoration']
prc_grp = be_dt['Price Type']
cost_p_con= be_dt['Conservation %']
cost_p_res= be_dt['Restoration %']

# Set font family and size for the entire plot


plt.rcParams["font.family"] = "Arial"
plt.rcParams["font.size"] = 11

# Create a new figure with two subplots (one for each price type)
price_types = prc_grp.unique()
fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(10, 4), sharey=True)

# Colorblind-friendly color palette


colorblind_palette = sns.color_palette("colorblind")

# Set bar width


bar_width = 0.4

# Loop over each price type and plot the bars for Conservation and Restoration
for i, price_type in enumerate(price_types):
ax = axes[i]

# Filter the data based on Price Type


idx = prc_grp == price_type
ax_a_filtered = ax_a[idx]
ay_p1_filtered = ay_p1[idx]
ay_p2_filtered = ay_p2[idx]

# Set bar positions


indices = np.arange(len(ax_a_filtered))

# Plot both sets of bars side by side


bars1 = ax.barh(indices - bar_width / 2, ay_p1_filtered, height=bar_width, col
label='Conservation')
bars2 = ax.barh(indices + bar_width / 2, ay_p2_filtered, height=bar_width, col
label='Restoration')

# Add title and axis labels


ax.set_title(f'{price_type}', fontsize=11, weight='bold')
ax.set_xlabel('USD', fontsize=12)

# Set y-ticks to match the project phases and center them between the bars
ax.set_yticks(indices)
ax.set_yticklabels(ax_a_filtered)

# Add a common legend, adjust position to avoid overlapping with title


handles, labels = axes[0].get_legend_handles_labels()
fig.legend(handles, ['Conservation', 'Restoration'], loc='upper center', fonts

# Customize tick parameters


ax.tick_params(axis='x', labelsize=10)
ax.tick_params(axis='y', labelsize=10)

# Remove top and right spines for cleaner look


ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)

# Adjust layout to make sure everything fits


plt.tight_layout()

# Display the plot


plt.show()
In [87]: import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import squarify

# Load data
be_dt = pd.read_excel("Cost by Project Stage.xlsx", sheet_name='Cost_stage')

# Sample data from your be_dt DataFrame


ax_a = be_dt['Project Phase']
cost_p_con = be_dt['Conservation %'].round(2)
cost_p_res = be_dt['Restoration %'].round(2)
prc_grp = be_dt['Price Type']

# Create a mapping of full project phase names to abbreviations (adjust as needed)


abbreviations = {
'Project scoping and feasibility assessment': 'PSFA',
'Project set-up and validation': 'PSV',
'Project development': 'PD',
'Monitoring and verification': 'MV',
'Credit issuance': 'CI',
'Credit sale' : 'CS'
}

# Apply the abbreviation to the Project Phase column


data = pd.DataFrame({
'Project Phase': ax_a.map(abbreviations), # Abbreviated project phase names
'Conservation %': cost_p_con,
'Restoration %': cost_p_res,
'Price Type': prc_grp
})

# Create a new column for labels combining 'Project Phase' and % of costs
data['Label'] = data['Project Phase'] + '\nCon: ' + data['Conservation %'].astype(

# Set font family for the plot


plt.rcParams["font.family"] = "Arial"
plt.rcParams["font.size"] = 10

# Get unique price groups


price_groups = data['Price Type'].unique()

# Create two treemaps, one for each price group


fig, axes = plt.subplots(1, 2, figsize=(10, 4))

for i, price_group in enumerate(price_groups):


ax = axes[i]

# Filter data for the current price group


price_data = data[data['Price Type'] == price_group]

# Set color palette for the treemap


colors = sns.color_palette("coolwarm", n_colors=len(price_data))
# Squarify plot for the current price group
squarify.plot(sizes=price_data['Conservation %'] + price_data['Restoration %']
label=price_data['Label'], color=colors, alpha=0.8, ax=ax)

# Add title
ax.set_title(f'{price_group}', fontsize=11, weight='bold')

# Remove axes
ax.axis('off')

# Adjust layout for better presentation


plt.tight_layout()

# Show plot
plt.show()

In [231… import matplotlib.pyplot as plt


import numpy as np
import pandas as pd
import seaborn as sns

# Load data
be_dt = pd.read_excel("Cost by Project Stage.xlsx", sheet_name='Cost_stage')

# Sample data from your be_dt DataFrame


ax_a = be_dt['Project Phase']
cost_p_con = be_dt['Conservation %'].round(2)
cost_p_res = be_dt['Restoration %'].round(2)
prc_grp = be_dt['Price Type']

# Create a mapping of full project phase names to abbreviations (adjust as needed)


abbreviations = {
'Project scoping and feasibility assessment': 'PSFA',
'Project set-up and validation': 'PSV',
'Project development': 'PD',
'Monitoring and verification': 'MV',
'Credit issuance': 'CI',
'Credit sale' : 'CS'
}

# Apply the abbreviation to the Project Phase column


data = pd.DataFrame({
'Project Phase': ax_a.map(abbreviations), # Abbreviated project phase names
'Conservation %': cost_p_con,
'Restoration %': cost_p_res,
'Price Type': prc_grp
})

# Get unique price groups


price_groups = data['Price Type'].unique()

# Set font family for the plot


plt.rcParams["font.family"] = "Arial"
plt.rcParams["font.size"] = 10

# Colorblind-friendly color palette


colorblind_palette = sns.color_palette("colorblind")

# Create a figure with polar subplots for each price group


fig, axes = plt.subplots(1, 2, subplot_kw=dict(projection='polar'), figsize=(8, 5)

# Iterate through price groups and create separate radial bar plots
for i, price_group in enumerate(price_groups):
ax = axes[i]

# Filter data for the current price group


price_data = data[data['Price Type'] == price_group]

# Number of variables we're plotting


num_vars = len(price_data)

# Compute the angle for each bar, with an offset for separation between Conser
angles = np.linspace(0, 2 * np.pi, num_vars, endpoint=False).tolist()
angles_con = np.array(angles) - (np.pi / (num_vars * 3)) # Shift Conservation
angles_res = np.array(angles) + (np.pi / (num_vars * 3)) # Shift Restoration

# Set up the width of each bar


width = 2 * np.pi / (num_vars * 4) # Narrower bars to fit side by side

# Plot Conservation % bars


bars1 = ax.bar(angles_con, price_data['Conservation %'], width=width, bottom=0

# Plot Restoration % bars next to Conservation %


bars2 = ax.bar(angles_res, price_data['Restoration %'], width=width, bottom=0,

# Set labels for the radial plot


ax.set_xticks(angles)
ax.set_xticklabels(price_data['Project Phase'], size=10)

# Ensure gridlines are behind bars


ax.grid(linewidth=.5, linestyle='--', zorder=0)
# Set the radial plot's title and add a legend
ax.set_title(f'', fontsize=12, weight=False)

# Add legend outside the polar subplots


handles, labels = axes[0].get_legend_handles_labels()
fig.legend(handles, ['Conservation', 'Restoration'], loc='lower center', fontsize=

# Adjust layout for better presentation


plt.tight_layout()

# Show plot
plt.show()

In [77]: import matplotlib.pyplot as plt


import numpy as np
import pandas as pd
import seaborn as sns

# Load data
be_dt = pd.read_excel("Cost by Project Stage.xlsx", sheet_name='Cost_stage')

# Sample data from your be_dt DataFrame


ax_a = be_dt['Project Phase']
ay_p1 = be_dt['Conservation']
ay_p2 = be_dt['Restoration']
prc_grp = be_dt['Price Type']
cost_p_con = be_dt['Conservation %']
cost_p_res = be_dt['Restoration %']

# Create a mapping of full project phase names to abbreviations (adjust as needed)


abbreviations = {
'Project scoping and feasibility assessment': 'PSFA',
'Project set-up and validation': 'PSV',
'Project development': 'PD',
'Monitoring and verification': 'MV',
'Credit issuance': 'CI',
'Credit sale' : 'CS'
}

# Apply the abbreviation to the Project Phase column


data = pd.DataFrame({
'Project Phase': ax_a.map(abbreviations), # Abbreviated project phase names
'Conservation %': cost_p_con,
'Restoration %': cost_p_res,
'Price Type': prc_grp
})

# Get unique price groups


price_groups = prc_grp.unique()

# Set font family and size for the entire plot


plt.rcParams["font.family"] = "Arial"
plt.rcParams["font.size"] = 10

# Colorblind-friendly color palette


colorblind_palette = sns.color_palette("colorblind")

# Create a 2x2 figure


fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(12, 6))

# --- First Plot (Top Left): Horizontal bar plots for Conservation and Restoration
# Loop over each price type and plot the bars for Conservation and Restoration
for i, price_type in enumerate(price_groups):
ax = axes[0, i] # Top row
idx = prc_grp == price_type
ax_a_filtered = ax_a[idx]
ay_p1_filtered = ay_p1[idx]
ay_p2_filtered = ay_p2[idx]

# Set bar positions


indices = np.arange(len(ax_a_filtered))
bar_width = 0.4

# Plot both sets of bars side by side


ax.barh(indices - bar_width / 2, ay_p1_filtered, height=bar_width, color=color
ax.barh(indices + bar_width / 2, ay_p2_filtered, height=bar_width, color=color

# Add title and axis labels


ax.set_title(f'{price_type}', fontsize=11, weight='bold')
ax.set_xlabel('USD', fontsize=10)

# Set y-ticks to match the project phases and center them between the bars
ax.set_yticks(indices)
ax.set_yticklabels(ax_a_filtered)

# Customize tick parameters


ax.tick_params(axis='x', labelsize=8)
ax.tick_params(axis='y', labelsize=10)
# Remove top and right spines for cleaner look
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)

# Add a common legend for the bar plots


handles, labels = axes[0, 0].get_legend_handles_labels()
fig.legend(handles, ['Conservation', 'Restoration'], loc='upper center', fontsize=

# --- Second Plot (Bottom): Polar bar plots for Conservation and Restoration ---
for i, price_group in enumerate(price_groups):
ax = axes[1, i] # Bottom row with polar plots
price_data = data[data['Price Type'] == price_group]

num_vars = len(price_data)
angles = np.linspace(0, 2 * np.pi, num_vars, endpoint=False).tolist()
angles_con = np.array(angles) - (np.pi / (num_vars * 3))
angles_res = np.array(angles) + (np.pi / (num_vars * 3))

width = 2 * np.pi / (num_vars * 4)

ax = plt.subplot(2, 2, i + 3, projection='polar') # Create a polar subplot

# Plot Conservation % bars


ax.bar(angles_con, price_data['Conservation %'], width=width, bottom=0, color=

# Plot Restoration % bars


ax.bar(angles_res, price_data['Restoration %'], width=width, bottom=0, color=c

# Set labels
ax.set_xticks(angles)
ax.set_xticklabels(price_data['Project Phase'], size=9, fontfamily= 'arial')
ax.grid(linewidth=0.3, linestyle='--', zorder=0, color= 'grey')
ax.spines['polar'].set_visible(False)

# Set the radial plot's title


ax.set_title('', fontsize=12)

# Adjust layout and display


plt.tight_layout()
plt.show()
In [169… import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import seaborn as sns

# Load data
be_dt = pd.read_excel("Cost by Project Stage.xlsx", sheet_name='Cost_stage')

# Extract relevant columns from the DataFrame


ax_a = be_dt['Project Phase']
cost_p_con = be_dt['Conservation %'].round(2)
cost_p_res = be_dt['Restoration %'].round(2)
prc_grp = be_dt['Price Type']

# Data for bar polot

ay_p1br = be_dt['Conservation']
ay_p2br = be_dt['Restoration']

# Create a mapping for abbreviated project phase names


abbreviations = {
'Project scoping and feasibility assessment': 'PSFA',
'Project set-up and validation': 'PSV',
'Project development': 'PD',
'Monitoring and verification': 'MV',
'Credit issuance': 'CI',
'Credit sale': 'CS'
}

# Apply the abbreviation to the Project Phase column


data = pd.DataFrame({
'Project Phase': ax_a.map(abbreviations),
'Conservation %': cost_p_con,
'Restoration %': cost_p_res,
'Price Type': prc_grp
})

# Set font and color palette


plt.rcParams["font.family"] = "Arial"
plt.rcParams["font.size"] = 10
colorblind_palette = sns.color_palette("colorblind")

# Get unique price groups


price_groups = data['Price Type'].unique()

# 2x2 grid for the plots


fig, axes = plt.subplots(2, 2, figsize=(12,8))

# Pie chart for price group 1


ax3 = axes[1, 0]
price_data_1 = data[data['Price Type'] == price_groups[0]]
sizes_3 = price_data_1['Conservation %'] + price_data_1['Restoration %']
labels_3 = price_data_1['Project Phase'] + '\nCon: ' + price_data_1['Conservation
explode_3 = [0.03] * len(sizes_3)
ax3.pie(sizes_3, labels=labels_3, explode=explode_3, autopct='%1.1f%%', textprops=
startangle=65, pctdistance=0.75, labeldistance=1.2, colors=colorblind_pale
ax3.set_title(f'', fontsize=11, weight='bold')

# Pie chart for price group 2


ax4 = axes[1, 1]
price_data_2 = data[data['Price Type'] == price_groups[1]]
sizes_4 = price_data_2['Conservation %'] + price_data_2['Restoration %']
labels_4 = price_data_2['Project Phase'] + '\nCon: ' + price_data_2['Conservation
explode_4 = [0.03] * len(sizes_4)
ax4.pie(sizes_4, labels=labels_4, explode=explode_4, autopct='%1.1f%%', textprops=
startangle=65, pctdistance=0.75, labeldistance=1.2, colors=colorblind_pale
ax4.set_title(f'', fontsize=11, weight='bold')

# Set bar width


bar_width = 0.4

# Horizontal bar charts for Conservation and Restoration (for both price groups)
for i, price_type in enumerate(price_groups):
ax = axes[0, i] # Top row for bar charts
idx = prc_grp == price_type
ax_a_filtered = ax_a[idx]
ay_p1_filtered = ay_p1br[idx]
ay_p2_filtered = ay_p2br[idx]

# Set bar positions


indices = np.arange(len(ax_a_filtered))

# Plot both sets of bars side by side


ax.barh(indices - bar_width / 2, ay_p1_filtered, height=bar_width, color=color
ax.barh(indices + bar_width / 2, ay_p2_filtered, height=bar_width, color=colo
# Add title and axis labels
ax.set_title(f'{price_type}', fontsize=11, weight='bold')
ax.set_xlabel('USD', fontsize=10)

# Set y-ticks to match the project phases


ax.set_yticks(indices)
ax.set_yticklabels(ax_a_filtered.map(abbreviations))

# Customize tick parameters


ax.tick_params(axis='x', labelsize=8)
ax.tick_params(axis='y', labelsize=10)

# Remove top and right spines for cleaner look


ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)

# Add a common legend for the bar plots


handles, labels = axes[0, 0].get_legend_handles_labels()
fig.legend(handles, ['Conservation', 'Restoration'], loc='upper center', fontsize=

# Adjust layout for better presentation


plt.tight_layout()

# Show plot
plt.show()

In [5]: import pandas as pd


import numpy as np
import matplotlib.pyplot as plt
# Load data
be_dt = pd.read_excel("cost per hectare per ecosystem per activity.xlsx", sheet_na

#define x and y coordinates


x = be_dt['Strategy']
y = data

In [35]: import numpy as np


import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

# Load data
be_dt = pd.read_excel("cost per hectare per ecosystem per activity.xlsx", sheet_na

# Prepare the angles and values for the bars


ANGLES = np.linspace(0, 2 * np.pi, len(be_dt), endpoint=False)
VALUES = be_dt["cost_000"].values.round(2)
LABELS = be_dt["Strategy"].values

# Group data by Price Type


price_grps = be_dt['Price Type'].unique()
# Set font family and size
plt.rcParams['font.family'] = 'Arial'
plt.rcParams['font.size'] = 11

# Define data labels


def get_label_rotation(angle, offset):
rotation = np.rad2deg(angle + offset)
if angle <= np.pi:
alignment = "right"
rotation += 180
else:
alignment = "left"
return rotation, alignment

def add_labels(angles, values, labels, offset, ax):


padding = 4
for angle, value, label in zip(angles, values, labels):
rotation, alignment = get_label_rotation(angle, offset)
ax.text(
x=angle,
y=value + padding,
s=label,
ha=alignment,
va="center",
rotation=rotation,
rotation_mode="anchor",
fontsize=10
)

# Group values
GROUP = be_dt["Eco_type"].values

PAD = 0 # Reduced padding to minimize extra bars


ANGLES_N = len(VALUES) + PAD * len(np.unique(GROUP))
ANGLES = np.linspace(1, 2 * np.pi, num=ANGLES_N, endpoint=False)
WIDTH = (1 * np.pi) / len(ANGLES)

# Offset to start bars at pi/2 (90 degrees)


OFFSET = np.pi / 2

# Calculate group sizes


GROUPS_SIZE = [len(group) for _, group in be_dt.groupby("Eco_type")]

# Determine indexes for each group


offset = 0
IDXS = []
for size in GROUPS_SIZE:
IDXS.extend(range(offset + PAD, offset + size + PAD))
offset += size + PAD

# Plotting
fig, ax = plt.subplots(figsize=(8, 7), subplot_kw={"projection": "polar"}) # Keep
ax.set_theta_offset(OFFSET)
ax.set_ylim(-100, 100)
ax.set_frame_on(False)
ax.xaxis.grid(False)
ax.yaxis.grid(False)
ax.set_xticks([])
ax.set_yticks([])

# Assign colors based on Price Type


# Define two colors: one for each type of price group
colorblind_palette = sns.color_palette("colorblind")
color1 = colorblind_palette[8] # Blue
color2 = colorblind_palette[3] # Orange
colors_map = {price_grps[0]: color1, price_grps[1]: color2} # Map price types to

# Create bar plot with assigned colors


COLORS = [colors_map[be_dt['Price Type'].iloc[i]] for i in IDXS] # Assign colors

ax.bar(
ANGLES[IDXS], VALUES, width=WIDTH, color=COLORS,
edgecolor="white", linewidth=2
)

# Add labels to the bars


add_labels(ANGLES[IDXS], VALUES, LABELS, OFFSET, ax)

# Extra customization: group lines and reference annotations

group_rotations = {
"Mangrove": 100, # Rotate Mangrove
"Saltmarsh":740, # Rotate Saltmarsh
"Seagrass": 300 # Rotate Seagrass
}
offset = 0
for group, size in zip(["Mangrove", "Saltmarsh", "Seagrass"], GROUPS_SIZE):
# Add line below bars
x1 = np.linspace(ANGLES[offset + PAD], ANGLES[offset + size + PAD - 1], num=50
ax.plot(x1, [-5] * 50, color="#333333")

# Add text for group name


rotation_angle = group_rotations.get(group, 0)
ax.text(
np.mean(x1), -20, group, color="#333333", fontsize=10, fontfamily='Arial',
fontweight="bold", ha="center", va="center", rotation=rotation_angle
)

# Add reference lines at 20, 40, 60, 80, and 100


for y in range(20, 101, 20):
ax.plot(np.linspace(ANGLES[offset], ANGLES[offset + PAD - 1], num=50), [y]
ax.text(0.55 * np.pi / 2, y + PAD, f"{y}", ha="right", size=7, color="dimg

offset += size + PAD

# Create a legend
handles = [plt.Rectangle((0, 0), 1, 1, color=colors_map[price_type]) for price_typ
ax.legend(handles, price_grps, title="", loc="upper right", fontsize=10, bbox_to_a
# Tight layout to reduce white space
plt.tight_layout()
plt.show()
In [49]: import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

# Load data
be_dt = pd.read_excel("cost per hectare per ecosystem per activity.xlsx", sheet_na

# Set font family and size


plt.rcParams['font.family'] = 'Arial'
plt.rcParams['font.size'] = 11

# Define data labels


def get_label_rotation(angle, offset):
rotation = np.rad2deg(angle + offset)
if angle <= np.pi:
alignment = "right"
rotation += 180
else:
alignment = "left"
return rotation, alignment

def add_labels(angles, values, labels, offset, ax):


padding = 4
for angle, value, label in zip(angles, values, labels):
rotation, alignment = get_label_rotation(angle, offset)
ax.text(
x=angle,
y=value + padding,
s=label,
ha=alignment,
va="center",
rotation=rotation,
rotation_mode="anchor",
fontsize=10
)

# Group data by Price Type


price_grps = be_dt['Price Type'].unique()

for price_grp in price_grps:


# Filter data for each price group
grp_data = be_dt[be_dt['Price Type'] == price_grp]

# Get values and labels for the group


ANGLES = np.linspace(0, 2 * np.pi, len(grp_data), endpoint=False)
VALUES = grp_data["cost_000"].values.round(2)
LABELS = grp_data["Strategy"].values

# Group values
GROUP = grp_data["Eco_type"].values

PAD = 0 # Reduced padding to minimize extra bars


ANGLES_N = len(VALUES) + PAD * len(np.unique(GROUP))
ANGLES = np.linspace(1, 2 * np.pi, num=ANGLES_N, endpoint=False)
WIDTH = (2 * np.pi) / len(ANGLES)*.5

# Offset to start bars at pi/2 (90 degrees)


OFFSET = np.pi / 2

# Calculate group sizes


GROUPS_SIZE = [len(group) for _, group in grp_data.groupby("Eco_type")]

# Determine indexes for each group


offset = 0
IDXS = []
for size in GROUPS_SIZE:
IDXS.extend(range(offset + PAD, offset + size + PAD))
offset += size + PAD

# Plotting
fig, ax = plt.subplots(figsize=(6, 5), subplot_kw={"projection": "polar"}) #
ax.set_title(f"{price_grp}", size=14) # Add title to each plot

ax.set_theta_offset(OFFSET)
ax.set_ylim(-100, 100)
ax.set_frame_on(False)
ax.xaxis.grid(False)
ax.yaxis.grid(False)
ax.set_xticks([])
ax.set_yticks([])

# Assign colors to groups


COLORS = [f"C{i}" for i, size in enumerate(GROUPS_SIZE) for _ in range(size)]

# Create bar plot


ax.bar(
ANGLES[IDXS], VALUES, width=WIDTH, color=COLORS,
edgecolor="white", linewidth=2
)

# Add labels to the bars


add_labels(ANGLES[IDXS], VALUES, LABELS, OFFSET, ax)

# Extra customization: group lines and reference annotations


offset = 0
group_rotations = {
"Mangrove": 100, # Rotate Mangrove
"Saltmarsh":740, # Rotate Saltmarsh
"Seagrass": 300 # Rotate Seagrass
}

for group, size in zip(["Mangrove", "Saltmarsh", "Seagrass"], GROUPS_SIZE):


# Add line below bars
x1 = np.linspace(ANGLES[offset + PAD], ANGLES[offset + size + PAD - 1], nu
ax.plot(x1, [-5] * 50, color="#333333")

# Add text for group name


rotation_angle = group_rotations.get(group, 0)
ax.text(
np.mean(x1), -20, group, color="#333333", fontsize=10, fontfamily='Ari
fontweight="bold", ha="center", va="center", rotation=rotation_angle
)

# Add reference lines at 20, 40, 60, 80, and 100


for y in range(20, 101, 20):
ax.plot(np.linspace(ANGLES[offset]*.7, ANGLES[offset + PAD - 1], num=5
ax.text(0.5 * np.pi / 2, y + PAD, f"{y}", ha="left", size=7, color="di

offset += size + PAD

# Tight layout to reduce white space


plt.tight_layout()
plt.show()

You might also like