A radar chart (also known as spider or web chart) displays multivariate data on axes starting from a common center point, with values connected to form a polygon. Each axis represents a different variable, making it ideal for comparing multiple quantitative variables at once or visualizing strengths and weaknesses across categories.

""" anyplot.ai
radar-basic: Basic Radar Chart
Library: plotly 6.9.0 | Python 3.13.14
Quality: 92/100 | Updated: 2026-07-24
"""
import os
import plotly.graph_objects as go
THEME = os.getenv("ANYPLOT_THEME", "light")
PAGE_BG = "#FAF8F1" if THEME == "light" else "#1A1A17"
ELEVATED_BG = "#FFFDF6" if THEME == "light" else "#242420"
INK = "#1A1A17" if THEME == "light" else "#F0EFE8"
INK_SOFT = "#4A4A44" if THEME == "light" else "#B8B7B0"
GRID = "rgba(26, 26, 23, 0.10)" if THEME == "light" else "rgba(240, 239, 232, 0.10)"
# Imprint categorical palette — first series always brand green
IMPRINT = ["#009E73", "#C475FD", "#4467A3", "#BD8233", "#AE3030", "#2ABCCD", "#954477"]
# Derive translucent fill colors from the Imprint hexes (no hardcoded rgba)
r0, g0, b0 = bytes.fromhex(IMPRINT[0][1:])
r1, g1, b1 = bytes.fromhex(IMPRINT[1][1:])
FILL_SENIOR = f"rgba({r0}, {g0}, {b0}, 0.25)"
FILL_JUNIOR = f"rgba({r1}, {g1}, {b1}, 0.25)"
# Data - Employee performance comparison across competencies
categories = ["Communication", "Technical Skills", "Teamwork", "Problem Solving", "Leadership", "Creativity"]
senior_values = [85, 92, 78, 88, 72, 80]
junior_values = [70, 65, 82, 68, 55, 75]
# Close the polygon by repeating the first point
categories_closed = categories + [categories[0]]
senior_closed = senior_values + [senior_values[0]]
junior_closed = junior_values + [junior_values[0]]
fig = go.Figure()
fig.add_trace(
go.Scatterpolar(
r=senior_closed,
theta=categories_closed,
fill="toself",
fillcolor=FILL_SENIOR,
line={"color": IMPRINT[0], "width": 3.5},
marker={"size": 11, "color": IMPRINT[0]},
name="Senior Developer",
hovertemplate="<b>Senior Developer</b><br>%{theta}: %{r}<extra></extra>",
)
)
fig.add_trace(
go.Scatterpolar(
r=junior_closed,
theta=categories_closed,
fill="toself",
fillcolor=FILL_JUNIOR,
line={"color": IMPRINT[1], "width": 2.5},
marker={"size": 11, "color": IMPRINT[1], "line": {"width": 1, "color": INK}},
name="Junior Developer",
hovertemplate="<b>Junior Developer</b><br>%{theta}: %{r}<extra></extra>",
)
)
# Distinctive plotly-native callout: a starred point + inline text label, placed
# directly in polar coordinates (no paper-space annotation math needed) to draw
# the eye to the one axis where Junior overtakes Senior.
fig.add_trace(
go.Scatterpolar(
r=[junior_values[2]],
theta=[categories[2]],
mode="markers+text",
marker={"size": 20, "symbol": "star", "color": IMPRINT[1], "line": {"width": 1.5, "color": INK}},
text=["Junior leads"],
textposition="middle left",
textfont={"size": 13, "color": INK},
showlegend=False,
hoverinfo="skip",
)
)
fig.update_layout(
autosize=False,
width=600,
height=600,
title={
"text": "radar-basic · python · plotly · anyplot.ai",
"font": {"size": 20, "color": INK},
"x": 0.5,
"xanchor": "center",
},
polar={
"bgcolor": PAGE_BG,
"domain": {"x": [0.08, 0.92], "y": [0.12, 0.88]},
"radialaxis": {
"visible": True,
"range": [0, 100],
"tickvals": [20, 40, 60, 80, 100],
"tickfont": {"size": 13, "color": INK_SOFT},
"gridcolor": GRID,
"linecolor": INK_SOFT,
# Offset into the gap between the "Technical Skills" and "Teamwork"
# spokes so the tick values don't collide with any axis label.
"angle": 0,
},
"angularaxis": {
"rotation": 90,
"direction": "clockwise",
"tickfont": {"size": 16, "color": INK},
"gridcolor": GRID,
"linecolor": INK_SOFT,
},
},
paper_bgcolor=PAGE_BG,
font={"color": INK},
showlegend=True,
legend={
"orientation": "h",
"font": {"size": 13, "color": INK_SOFT},
"bgcolor": ELEVATED_BG,
"bordercolor": INK_SOFT,
"borderwidth": 1,
"x": 0.5,
"y": 0.02,
"xanchor": "center",
"yanchor": "top",
},
margin={"l": 70, "r": 70, "t": 90, "b": 70},
)
# Square format — ideal for symmetric polar charts. Canonical 2400×2400 px.
fig.write_image(f"plot-{THEME}.png", width=600, height=600, scale=4)
fig.write_html(f"plot-{THEME}.html", include_plotlyjs="cdn")
Part of Basic Radar Chart on anyplot.ai.