import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import numpy as np
def pie_chart_single_row(df, columns=None, title="Data Distribution"):
"""
Creates a pie chart from a single row DataFrame with equal slice sizes.
Parameters:
df (pd.DataFrame): DataFrame with typically one row
columns (list, optional): List of column names to include. If None, uses all columns
title (str): Title for the pie chart
Returns:
plotly.graph_objects.Figure: Pie chart figure
"""
# Use first row of data
row_data = df.iloc[0]
# Select columns
if columns is None:
columns = df.columns.tolist()
# Filter data for selected columns
filtered_data = row_data[columns]
# Create labels and values (equal sizes)
labels = [f"{col}: {val}" for col, val in filtered_data.items()]
values = [1] * len(filtered_data) # Equal slice sizes
# Create pie chart
fig = go.Figure(data=[go.Pie(
labels=labels,
values=values,
hole=0.3, # Donut style
textinfo='label+percent',
textposition='outside',
marker=dict(
colors=px.colors.qualitative.Set3[:len(labels)],
line=dict(color='#FFFFFF', width=2)
)
)])
fig.update_layout(
title={
'text': title,
'x': 0.5,
'xanchor': 'center',
'font': {'size': 20, 'color': '#2E4057'}
},
font=dict(size=12),
showlegend=True,
legend=dict(
orientation="v",
yanchor="middle",
y=0.5,
xanchor="left",
x=1.01
),
margin=dict(t=80, b=20, l=20, r=150),
paper_bgcolor='white',
plot_bgcolor='white'
)
return fig
def pie_chart_column_values(df, column_name, title=None):
"""
Creates a pie chart based on unique values and their counts in a specific column.
Parameters:
df (pd.DataFrame): Input DataFrame
column_name (str): Name of the column to analyze
title (str, optional): Title for the pie chart
Returns:
plotly.graph_objects.Figure: Pie chart figure
"""
if column_name not in df.columns:
raise ValueError(f"Column '{column_name}' not found in DataFrame")
# Get value counts
value_counts = df[column_name].value_counts()
if title is None:
title = f"Distribution of {column_name}"
# Create pie chart
fig = go.Figure(data=[go.Pie(
labels=value_counts.index,
values=value_counts.values,
hole=0.4, # Donut style
textinfo='label+percent+value',
textposition='auto',
marker=dict(
colors=px.colors.qualitative.Pastel[:len(value_counts)],
line=dict(color='#FFFFFF', width=2)
),
hovertemplate='<b>%{label}</b><br>Count: %{value}<br>Percentage: %{percent}<extra></extra>'
)])
fig.update_layout(
title={
'text': title,
'x': 0.5,
'xanchor': 'center',
'font': {'size': 22, 'color': '#2E4057', 'family': 'Arial Black'}
},
font=dict(size=14, family='Arial'),
showlegend=True,
legend=dict(
orientation="v",
yanchor="middle",
y=0.5,
xanchor="left",
x=1.02,
font=dict(size=12)
),
margin=dict(t=100, b=50, l=50, r=200),
paper_bgcolor='#F8F9FA',
plot_bgcolor='white',
height=600
)
return fig
def create_kpi_cards(df, columns=None, cards_per_row=4, title="KPI Dashboard"):
"""
Creates beautiful KPI/metric cards from the first row of DataFrame.
Parameters:
df (pd.DataFrame): Input DataFrame
columns (list, optional): List of column names to include. If None, uses all columns
cards_per_row (int): Number of cards per row (default: 4)
title (str): Title for the dashboard
Returns:
plotly.graph_objects.Figure: KPI cards figure
"""
# Use first row of data
row_data = df.iloc[0]
# Select columns
if columns is None:
columns = df.columns.tolist()
# Filter data for selected columns
filtered_data = row_data[columns]
# Calculate subplot dimensions
n_cards = len(filtered_data)
n_rows = (n_cards + cards_per_row - 1) // cards_per_row
# Create color palette
colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FFEAA7', '#DDA0DD', '#98D8C8', '#F7DC6F']
# Create subplots
fig = make_subplots(
rows=n_rows,
cols=cards_per_row,
subplot_titles=[f"<b>{col}</b>" for col in filtered_data.index],
specs=[[{'type': 'indicator'}] * cards_per_row for _ in range(n_rows)],
vertical_spacing=0.15,
horizontal_spacing=0.1
)
# Add KPI cards
for i, (col, val) in enumerate(filtered_data.items()):
row = i // cards_per_row + 1
col_pos = i % cards_per_row + 1
color = colors[i % len(colors)]
# Format value based on type
if isinstance(val, (int, float)):
if val >= 1000000:
display_val = f"{val/1000000:.1f}M"
elif val >= 1000:
display_val = f"{val/1000:.1f}K"
else:
display_val = f"{val:.2f}" if isinstance(val, float) else str(val)
else:
display_val = str(val)
fig.add_trace(
go.Indicator(
mode="number",
value=val if isinstance(val, (int, float)) else 0,
number={
'font': {'size': 40, 'color': color, 'family': 'Arial Black'},
'suffix': '' if isinstance(val, (int, float)) else '',
},
title={
'text': f"<span style='font-size:16px; color:#2E4057; font-weight:bold'>{col}</span>",
'font': {'size': 16}
},
domain={'x': [0, 1], 'y': [0, 1]}
),
row=row, col=col_pos
)
# Add custom text for non-numeric values
if not isinstance(val, (int, float)):
fig.add_annotation(
text=f"<b style='color:{color}; font-size:32px'>{display_val}</b>",
x=0.5, y=0.4,
xref=f"x{i+1}", yref=f"y{i+1}",
showarrow=False,
font=dict(size=32, color=color, family='Arial Black')
)
# Update layout
fig.update_layout(
title={
'text': f"<b>{title}</b>",
'x': 0.5,
'xanchor': 'center',
'font': {'size': 28, 'color': '#2E4057', 'family': 'Arial Black'}
},
paper_bgcolor='#F8F9FA',
plot_bgcolor='white',
height=200 * n_rows + 100,
margin=dict(t=100, b=50, l=50, r=50),
font=dict(family='Arial')
)
return fig
# Example usage functions
def demo_functions():
"""
Demonstrates how to use all three functions with sample data.
"""
# Sample data for testing
sample_data = {
'Sales': [25000],
'Customers': [150],
'Revenue': [75000],
'Products': [45],
'Region': ['North'],
'Status': ['Active']
}
df_sample = pd.DataFrame(sample_data)
# Sample data for column-based pie chart
category_data = {
'Category': ['Electronics', 'Clothing', 'Electronics', 'Books', 'Clothing', 'Electronics', 'Books'],
'Sales': [100, 200, 150, 80, 120, 180, 90]
}
df_categories = pd.DataFrame(category_data)
print("Sample DataFrame for single row pie chart:")
print(df_sample)
print("\nSample DataFrame for column-based pie chart:")
print(df_categories)
# Function 1: Single row pie chart
fig1 = pie_chart_single_row(df_sample, title="Business Metrics Overview")
fig1.show()
# Function 2: Column values pie chart
fig2 = pie_chart_column_values(df_categories, 'Category', title="Sales by Category")
fig2.show()
# Function 3: KPI cards
fig3 = create_kpi_cards(df_sample, cards_per_row=3, title="Business Dashboard")
fig3.show()
# Uncomment the line below to run the demo
# demo_functions()
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import numpy as np
def pie_chart_single_row(df, columns=None, title="Data Distribution"):
"""
Creates a pie chart from a single row DataFrame with equal slice sizes.
Parameters:
df (pd.DataFrame): DataFrame with typically one row
columns (list, optional): List of column names to include. If None, uses all columns
title (str): Title for the pie chart
Returns:
plotly.graph_objects.Figure: Pie chart figure
"""
# Use first row of data
row_data = df.iloc[0]
# Select columns
if columns is None:
columns = df.columns.tolist()
# Filter data for selected columns
filtered_data = row_data[columns]
# Create labels and values (equal sizes)
labels = [f"{col}: {val}" for col, val in filtered_data.items()]
values = [1] * len(filtered_data) # Equal slice sizes
# Create pie chart
fig = go.Figure(data=[go.Pie(
labels=labels,
values=values,
hole=0.3, # Donut style
textinfo='label+percent',
textposition='outside',
marker=dict(
colors=px.colors.qualitative.Set3[:len(labels)],
line=dict(color='#FFFFFF', width=2)
)
)])
fig.update_layout(
title={
'text': title,
'x': 0.5,
'xanchor': 'center',
'font': {'size': 20, 'color': '#2E4057'}
},
font=dict(size=12),
showlegend=True,
legend=dict(
orientation="v",
yanchor="middle",
y=0.5,
xanchor="left",
x=1.01
),
margin=dict(t=80, b=20, l=20, r=150),
paper_bgcolor='white',
plot_bgcolor='white'
)
return fig
def pie_chart_column_values(df, column_name, title=None):
"""
Creates a pie chart based on unique values and their counts in a specific column.
Parameters:
df (pd.DataFrame): Input DataFrame
column_name (str): Name of the column to analyze
title (str, optional): Title for the pie chart
Returns:
plotly.graph_objects.Figure: Pie chart figure
"""
if column_name not in df.columns:
raise ValueError(f"Column '{column_name}' not found in DataFrame")
# Get value counts
value_counts = df[column_name].value_counts()
if title is None:
title = f"Distribution of {column_name}"
# Create pie chart
fig = go.Figure(data=[go.Pie(
labels=value_counts.index,
values=value_counts.values,
hole=0.4, # Donut style
textinfo='label+percent+value',
textposition='auto',
marker=dict(
colors=px.colors.qualitative.Pastel[:len(value_counts)],
line=dict(color='#FFFFFF', width=2)
),
hovertemplate='<b>%{label}</b><br>Count: %{value}<br>Percentage: %{percent}<extra></extra>'
)])
fig.update_layout(
title={
'text': title,
'x': 0.5,
'xanchor': 'center',
'font': {'size': 22, 'color': '#2E4057', 'family': 'Arial Black'}
},
font=dict(size=14, family='Arial'),
showlegend=True,
legend=dict(
orientation="v",
yanchor="middle",
y=0.5,
xanchor="left",
x=1.02,
font=dict(size=12)
),
margin=dict(t=100, b=50, l=50, r=200),
paper_bgcolor='#F8F9FA',
plot_bgcolor='white',
height=600
)
return fig
def create_kpi_cards(df, columns=None, cards_per_row=4, title="KPI Dashboard"):
"""
Creates beautiful KPI/metric cards from the first row of DataFrame.
Parameters:
df (pd.DataFrame): Input DataFrame
columns (list, optional): List of column names to include. If None, uses all columns
cards_per_row (int): Number of cards per row (default: 4)
title (str): Title for the dashboard
Returns:
plotly.graph_objects.Figure: KPI cards figure
"""
# Use first row of data
row_data = df.iloc[0]
# Select columns
if columns is None:
columns = df.columns.tolist()
# Filter data for selected columns
filtered_data = row_data[columns]
# Calculate subplot dimensions
n_cards = len(filtered_data)
n_rows = (n_cards + cards_per_row - 1) // cards_per_row
# Create color palette
colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FFEAA7', '#DDA0DD', '#98D8C8', '#F7DC6F']
# Create subplots
fig = make_subplots(
rows=n_rows,
cols=cards_per_row,
subplot_titles=[f"<b>{col}</b>" for col in filtered_data.index],
specs=[[{'type': 'indicator'}] * cards_per_row for _ in range(n_rows)],
vertical_spacing=0.15,
horizontal_spacing=0.1
)
# Add KPI cards
for i, (col, val) in enumerate(filtered_data.items()):
row = i // cards_per_row + 1
col_pos = i % cards_per_row + 1
color = colors[i % len(colors)]
# Format value based on type
if isinstance(val, (int, float)):
if val >= 1000000:
display_val = f"{val/1000000:.1f}M"
elif val >= 1000:
display_val = f"{val/1000:.1f}K"
else:
display_val = f"{val:.2f}" if isinstance(val, float) else str(val)
else:
display_val = str(val)
fig.add_trace(
go.Indicator(
mode="number",
value=val if isinstance(val, (int, float)) else 0,
number={
'font': {'size': 40, 'color': color, 'family': 'Arial Black'},
'suffix': '' if isinstance(val, (int, float)) else '',
},
title={
'text': f"<span style='font-size:16px; color:#2E4057; font-weight:bold'>{col}</span>",
'font': {'size': 16}
},
domain={'x': [0, 1], 'y': [0, 1]}
),
row=row, col=col_pos
)
# Add custom text for non-numeric values
if not isinstance(val, (int, float)):
fig.add_annotation(
text=f"<b style='color:{color}; font-size:32px'>{display_val}</b>",
x=0.5, y=0.4,
xref=f"x{i+1}", yref=f"y{i+1}",
showarrow=False,
font=dict(size=32, color=color, family='Arial Black')
)
# Update layout
fig.update_layout(
title={
'text': f"<b>{title}</b>",
'x': 0.5,
'xanchor': 'center',
'font': {'size': 28, 'color': '#2E4057', 'family': 'Arial Black'}
},
paper_bgcolor='#F8F9FA',
plot_bgcolor='white',
height=200 * n_rows + 100,
margin=dict(t=100, b=50, l=50, r=50),
font=dict(family='Arial')
)
return fig
# Example usage functions
def demo_functions():
"""
Demonstrates how to use all three functions with sample data.
"""
# Sample data for testing
sample_data = {
'Sales': [25000],
'Customers': [150],
'Revenue': [75000],
'Products': [45],
'Region': ['North'],
'Status': ['Active']
}
df_sample = pd.DataFrame(sample_data)
# Sample data for column-based pie chart
category_data = {
'Category': ['Electronics', 'Clothing', 'Electronics', 'Books', 'Clothing', 'Electronics', 'Books'],
'Sales': [100, 200, 150, 80, 120, 180, 90]
}
df_categories = pd.DataFrame(category_data)
print("Sample DataFrame for single row pie chart:")
print(df_sample)
print("\nSample DataFrame for column-based pie chart:")
print(df_categories)
# Function 1: Single row pie chart
fig1 = pie_chart_single_row(df_sample, title="Business Metrics Overview")
fig1.show()
# Function 2: Column values pie chart
fig2 = pie_chart_column_values(df_categories, 'Category', title="Sales by Category")
fig2.show()
# Function 3: KPI cards
fig3 = create_kpi_cards(df_sample, cards_per_row=3, title="Business Dashboard")
fig3.show()
def status_classification_chart(df, x_col, status_col, title=None, chart_type='bar'):
"""
Creates a beautiful classification chart showing status distribution across categories.
Parameters:
df (pd.DataFrame): Input DataFrame
x_col (str): Column name for X-axis (categories)
status_col (str): Column name for status/classification
title (str, optional): Title for the chart
chart_type (str): Type of chart - 'bar', 'stacked_bar', or 'grouped_bar'
Returns:
plotly.graph_objects.Figure: Classification chart figure
"""
if x_col not in df.columns or status_col not in df.columns:
raise ValueError(f"Columns '{x_col}' or '{status_col}' not found in DataFrame")
if title is None:
title = f"{status_col} Distribution by {x_col}"
# Get unique statuses and assign colors
unique_statuses = df[status_col].unique()
colors = px.colors.qualitative.Set2[:len(unique_statuses)]
color_map = dict(zip(unique_statuses, colors))
# Create cross-tabulation
crosstab = pd.crosstab(df[x_col], df[status_col])
fig = go.Figure()
if chart_type == 'stacked_bar':
# Stacked bar chart
for status in unique_statuses:
fig.add_trace(go.Bar(
name=status,
x=crosstab.index,
y=crosstab[status] if status in crosstab.columns else [0] * len(crosstab.index),
marker_color=color_map[status],
text=crosstab[status] if status in crosstab.columns else [0] * len(crosstab.index),
textposition='inside',
textfont=dict(color='white', size=12, family='Arial Bold'),
hovertemplate=f'<b>{x_col}</b>: %{{x}}<br><b>{status}</b>: %{{y}}<br><extra></extra>'
))
fig.update_layout(barmode='stack')
elif chart_type == 'grouped_bar':
# Grouped bar chart
for status in unique_statuses:
fig.add_trace(go.Bar(
name=status,
x=crosstab.index,
y=crosstab[status] if status in crosstab.columns else [0] * len(crosstab.index),
marker_color=color_map[status],
text=crosstab[status] if status in crosstab.columns else [0] * len(crosstab.index),
textposition='outside',
textfont=dict(color=color_map[status], size=11, family='Arial Bold'),
hovertemplate=f'<b>{x_col}</b>: %{{x}}<br><b>{status}</b>: %{{y}}<br><extra></extra>'
))
fig.update_layout(barmode='group')
else: # Default bar chart with color coding
# Create a single bar chart with colors based on dominant status
category_counts = df.groupby([x_col, status_col]).size().unstack(fill_value=0)
dominant_status = category_counts.idxmax(axis=1)
total_counts = category_counts.sum(axis=1)
bar_colors = [color_map[status] for status in dominant_status]
fig.add_trace(go.Bar(
x=total_counts.index,
y=total_counts.values,
marker_color=bar_colors,
text=total_counts.values,
textposition='outside',
textfont=dict(color='#2E4057', size=12, family='Arial Bold'),
hovertemplate='<b>%{x}</b><br>Total Count: %{y}<br><extra></extra>',
showlegend=False
))
# Add custom legend
for status, color in color_map.items():
fig.add_trace(go.Scatter(
x=[None], y=[None],
mode='markers',
marker=dict(size=15, color=color),
name=f'{status}',
showlegend=True
))
# Update layout
fig.update_layout(
title={
'text': f"<b>{title}</b>",
'x': 0.5,
'xanchor': 'center',
'font': {'size': 24, 'color': '#2E4057', 'family': 'Arial Black'}
},
xaxis_title=f"<b>{x_col}</b>",
yaxis_title="<b>Count</b>",
xaxis=dict(
titlefont=dict(size=16, color='#2E4057', family='Arial Bold'),
tickfont=dict(size=12, color='#2E4057'),
gridcolor='#E5E5E5'
),
yaxis=dict(
titlefont=dict(size=16, color='#2E4057', family='Arial Bold'),
tickfont=dict(size=12, color='#2E4057'),
gridcolor='#E5E5E5'
),
plot_bgcolor='white',
paper_bgcolor='#F8F9FA',
font=dict(family='Arial'),
legend=dict(
orientation="v",
yanchor="top",
y=1,
xanchor="left",
x=1.02,
bgcolor="rgba(255,255,255,0.8)",
bordercolor="#CCCCCC",
borderwidth=1,
font=dict(size=12)
),
margin=dict(t=80, b=60, l=60, r=150),
height=500
)
return fig
def cause_solution_analysis(df, cause_col, solution_col, title=None):
"""
Creates a beautiful cause-solution analysis visualization using Sankey diagram.
Parameters:
df (pd.DataFrame): Input DataFrame
cause_col (str): Column name for causes
solution_col (str): Column name for solutions
title (str, optional): Title for the chart
Returns:
plotly.graph_objects.Figure: Sankey diagram figure
"""
if cause_col not in df.columns or solution_col not in df.columns:
raise ValueError(f"Columns '{cause_col}' or '{solution_col}' not found in DataFrame")
if title is None:
title = f"Cause-Solution Analysis: {cause_col} → {solution_col}"
# Create cause-solution pairs and count frequencies
cause_solution_counts = df.groupby([cause_col, solution_col]).size().reset_index(name='count')
# Get unique causes and solutions
unique_causes = df[cause_col].unique()
unique_solutions = df[solution_col].unique()
# Create node labels and colors
all_nodes = list(unique_causes) + list(unique_solutions)
node_colors = (px.colors.qualitative.Set3[:len(unique_causes)] +
px.colors.qualitative.Pastel[:len(unique_solutions)])
# Create source, target, and value lists for Sankey
source = []
target = []
value = []
for _, row in cause_solution_counts.iterrows():
cause_idx = list(unique_causes).index(row[cause_col])
solution_idx = len(unique_causes) + list(unique_solutions).index(row[solution_col])
source.append(cause_idx)
target.append(solution_idx)
value.append(row['count'])
# Create Sankey diagram
fig = go.Figure(data=[go.Sankey(
node=dict(
pad=20,
thickness=25,
line=dict(color="black", width=1),
label=all_nodes,
color=node_colors,
hovertemplate='<b>%{label}</b><br>Total Flow: %{value}<extra></extra>'
),
link=dict(
source=source,
target=target,
value=value,
color=[node_colors[i] + '40' for i in source], # Semi-transparent links
hovertemplate='<b>%{source.label}</b> → <b>%{target.label}</b><br>Count: %{value}<extra></extra>'
)
)])
fig.update_layout(
title={
'text': f"<b>{title}</b>",
'x': 0.5,
'xanchor': 'center',
'font': {'size': 24, 'color': '#2E4057', 'family': 'Arial Black'}
},
font=dict(size=14, family='Arial'),
paper_bgcolor='#F8F9FA',
plot_bgcolor='white',
margin=dict(t=80, b=50, l=50, r=50),
height=600,
annotations=[
dict(
text="<b>Causes</b>",
x=0.15, y=1.05,
xref="paper", yref="paper",
showarrow=False,
font=dict(size=18, color='#2E4057', family='Arial Bold')
),
dict(
text="<b>Solutions</b>",
x=0.85, y=1.05,
xref="paper", yref="paper",
showarrow=False,
font=dict(size=18, color='#2E4057', family='Arial Bold')
)
]
)
return fig
# Enhanced demo function with new visualizations
def demo_all_functions():
"""
Demonstrates all five functions with comprehensive sample data.
"""
# Sample data for status classification
status_data = {
'Department': ['Sales', 'Marketing', 'IT', 'Sales', 'HR', 'IT', 'Marketing', 'Sales', 'HR', 'IT'],
'Status': ['Active', 'Pending', 'Active', 'Completed', 'Active', 'Pending', 'Completed', 'Active', 'Pending', 'Active'],
'Priority': ['High', 'Medium', 'Low', 'High', 'Medium', 'High', 'Low', 'Medium', 'High', 'Low']
}
df_status = pd.DataFrame(status_data)
# Sample data for cause-solution analysis
cause_solution_data = {
'Problem_Cause': ['Network Issue', 'User Error', 'Hardware Failure', 'Network Issue', 'Software Bug',
'User Error', 'Hardware Failure', 'Software Bug', 'Network Issue', 'User Error'],
'Solution_Applied': ['Restart Router', 'User Training', 'Replace Hardware', 'Update Firmware', 'Patch Software',
'Create Manual', 'Replace Hardware', 'Bug Fix', 'Restart Router', 'User Training']
}
df_cause_solution = pd.DataFrame(cause_solution_data)
print("Sample DataFrame for status classification:")
print(df_status)
print("\nSample DataFrame for cause-solution analysis:")
print(df_cause_solution)
# Function 4: Status classification chart
fig4 = status_classification_chart(df_status, 'Department', 'Status',
title="Department Status Distribution",
chart_type='grouped_bar')
fig4.show()
# Function 5: Cause-solution analysis
fig5 = cause_solution_analysis(df_cause_solution, 'Problem_Cause', 'Solution_Applied')
fig5.show()
# Uncomment the line below to run the comprehensive demo
# demo_all_functions()
For further actions, you may consider blocking this person and/or reporting abuse
Top comments (0)