Skip to content

Commit c01705d

Browse files
feat(plotly): implement scatter-text (#3490)
## Implementation: `scatter-text` - plotly Implements the **plotly** version of `scatter-text`. **File:** `plots/scatter-text/implementations/plotly.py` **Parent Issue:** #3482 --- :robot: *[impl-generate workflow](https://github.com/MarkusNeusinger/pyplots/actions/runs/20854874896)* --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
1 parent 0960958 commit c01705d

File tree

2 files changed

+444
-0
lines changed

2 files changed

+444
-0
lines changed
Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
""" pyplots.ai
2+
scatter-text: Scatter Plot with Text Labels Instead of Points
3+
Library: plotly 6.5.1 | Python 3.13.11
4+
Quality: 91/100 | Created: 2026-01-09
5+
"""
6+
7+
import numpy as np
8+
import plotly.graph_objects as go
9+
10+
11+
# Data - Programming languages positioned by paradigm characteristics
12+
np.random.seed(42)
13+
14+
# Language names as labels
15+
labels = [
16+
"Python",
17+
"JavaScript",
18+
"Java",
19+
"C++",
20+
"Ruby",
21+
"Go",
22+
"Rust",
23+
"Kotlin",
24+
"Swift",
25+
"TypeScript",
26+
"Scala",
27+
"Haskell",
28+
"Elixir",
29+
"Clojure",
30+
"F#",
31+
"R",
32+
"Julia",
33+
"MATLAB",
34+
"Perl",
35+
"PHP",
36+
"C#",
37+
"Dart",
38+
"Lua",
39+
"Erlang",
40+
"OCaml",
41+
"Fortran",
42+
"COBOL",
43+
"Assembly",
44+
"Lisp",
45+
"Prolog",
46+
]
47+
48+
# Position based on: x = Level of abstraction, y = Type safety
49+
# Coordinates carefully placed to avoid all text overlaps
50+
x = np.array(
51+
[
52+
8.5, # Python
53+
5.5, # JavaScript - shifted further left
54+
6.0, # Java
55+
3.0, # C++
56+
8.0, # Ruby
57+
5.5, # Go
58+
4.0, # Rust
59+
5.0, # Kotlin - shifted significantly left
60+
7.0, # Swift
61+
7.5, # TypeScript
62+
6.5, # Scala - shifted left
63+
9.0, # Haskell
64+
8.5, # Elixir
65+
9.8, # Clojure - shifted to far right edge
66+
8.0, # F#
67+
9.5, # R - shifted right
68+
7.5, # Julia
69+
6.5, # MATLAB - shifted left
70+
8.5, # Perl - shifted significantly right
71+
7.0, # PHP
72+
6.0, # C#
73+
8.0, # Dart - shifted right, away from Kotlin
74+
6.0, # Lua - shifted left
75+
9.2, # Erlang - shifted right
76+
8.5, # OCaml
77+
2.0, # Fortran - shifted further left
78+
5.0, # COBOL - shifted significantly right
79+
1.0, # Assembly
80+
9.5, # Lisp - shifted right
81+
7.5, # Prolog - shifted significantly left
82+
]
83+
)
84+
85+
y = np.array(
86+
[
87+
3.0, # Python
88+
1.5, # JavaScript - shifted down
89+
8.0, # Java
90+
6.0, # C++
91+
1.5, # Ruby - shifted down
92+
7.0, # Go
93+
9.0, # Rust
94+
8.5, # Kotlin - shifted up
95+
9.0, # Swift - shifted up
96+
7.0, # TypeScript - shifted down
97+
9.0, # Scala - shifted up
98+
9.5, # Haskell
99+
5.5, # Elixir - shifted down
100+
4.5, # Clojure - shifted down significantly
101+
8.5, # F#
102+
3.0, # R
103+
4.5, # Julia
104+
3.0, # MATLAB
105+
2.5, # Perl
106+
1.5, # PHP - shifted down
107+
8.5, # C# - shifted up
108+
6.0, # Dart - shifted down, away from Kotlin
109+
4.0, # Lua - shifted up
110+
6.5, # Erlang
111+
9.5, # OCaml - shifted up
112+
3.5, # Fortran - shifted down
113+
6.5, # COBOL - shifted up, away from Fortran
114+
2.5, # Assembly - shifted down
115+
5.0, # Lisp - shifted up
116+
8.0, # Prolog - shifted up significantly
117+
]
118+
)
119+
120+
# Color by category (functional, OOP, multi-paradigm, systems)
121+
categories = [
122+
"Multi-paradigm",
123+
"Multi-paradigm",
124+
"OOP",
125+
"Systems",
126+
"OOP",
127+
"Systems",
128+
"Systems",
129+
"OOP",
130+
"OOP",
131+
"Multi-paradigm",
132+
"Functional",
133+
"Functional",
134+
"Functional",
135+
"Functional",
136+
"Functional",
137+
"Statistical",
138+
"Scientific",
139+
"Scientific",
140+
"Scripting",
141+
"Scripting",
142+
"OOP",
143+
"OOP",
144+
"Scripting",
145+
"Functional",
146+
"Functional",
147+
"Scientific",
148+
"Legacy",
149+
"Systems",
150+
"Functional",
151+
"Functional",
152+
]
153+
154+
# Color mapping (improved distinction between categories)
155+
color_map = {
156+
"Multi-paradigm": "#1E88E5", # Bright Blue
157+
"OOP": "#FFC107", # Amber Yellow
158+
"Systems": "#D32F2F", # Red
159+
"Functional": "#43A047", # Green
160+
"Statistical": "#8E24AA", # Deep Purple (more distinct from blue)
161+
"Scientific": "#00ACC1", # Cyan (more distinct from blue)
162+
"Scripting": "#FB8C00", # Orange
163+
"Legacy": "#757575", # Gray
164+
}
165+
166+
colors = [color_map[cat] for cat in categories]
167+
168+
# Create figure with text labels as data points
169+
fig = go.Figure()
170+
171+
# Add text labels grouped by category for legend
172+
for category in color_map:
173+
mask = [c == category for c in categories]
174+
if any(mask):
175+
x_cat = [x[i] for i in range(len(x)) if mask[i]]
176+
y_cat = [y[i] for i in range(len(y)) if mask[i]]
177+
labels_cat = [labels[i] for i in range(len(labels)) if mask[i]]
178+
# Create hover text with detailed information
179+
hover_cat = [
180+
f"<b>{labels[i]}</b><br>Paradigm: {category}<br>Abstraction: {x[i]:.1f}<br>Type Safety: {y[i]:.1f}"
181+
for i in range(len(labels))
182+
if mask[i]
183+
]
184+
185+
fig.add_trace(
186+
go.Scatter(
187+
x=x_cat,
188+
y=y_cat,
189+
mode="text",
190+
text=labels_cat,
191+
textfont=dict(size=18, color=color_map[category], family="Arial Black"),
192+
textposition="middle center",
193+
name=category,
194+
showlegend=True,
195+
hovertext=hover_cat,
196+
hoverinfo="text",
197+
)
198+
)
199+
200+
# Update layout
201+
fig.update_layout(
202+
title=dict(text="scatter-text · plotly · pyplots.ai", font=dict(size=32), x=0.5, xanchor="center"),
203+
xaxis=dict(
204+
title=dict(text="Level of Abstraction (0-10 scale)", font=dict(size=24)),
205+
tickfont=dict(size=18),
206+
range=[0, 10.5],
207+
gridcolor="rgba(0,0,0,0.1)",
208+
gridwidth=1,
209+
),
210+
yaxis=dict(
211+
title=dict(text="Type Safety (0-10 scale)", font=dict(size=24)),
212+
tickfont=dict(size=18),
213+
range=[0, 10.5],
214+
gridcolor="rgba(0,0,0,0.1)",
215+
gridwidth=1,
216+
),
217+
template="plotly_white",
218+
legend=dict(
219+
title=dict(text="Paradigm", font=dict(size=18)),
220+
font=dict(size=16),
221+
x=1.02,
222+
y=0.98,
223+
xanchor="left",
224+
yanchor="top",
225+
itemsizing="constant",
226+
),
227+
margin=dict(l=80, r=180, t=100, b=80),
228+
)
229+
230+
# Save as PNG and HTML
231+
fig.write_image("plot.png", width=1600, height=900, scale=3)
232+
fig.write_html("plot.html")

0 commit comments

Comments
 (0)