from plotnine import (
aes,
annotate,
coord_equal,
element_rect,
element_text,
facet_wrap,
geom_point,
geom_segment,
geom_text,
geom_tile,
ggplot,
lims,
scale_shape_identity,
theme,
theme_void,
)
import polars as pl
import numpy as np
Scatter Plot Shapes
scatter plot
List the shapes and prepare dataframe with what is required to display them.
= (
filled_shapes "o", # circle
"^", # triangle up
"s", # square
"D", # Diamond
"v", # triangle down
"*", # star
"p", # pentagon
"8", # octagon
"<", # triangle left
"h", # hexagon1
">", # triangle right
"H", # hexagon1
"d", # thin diamond
)
= (
unfilled_shapes "+", # plus
"x", # x
".", # point
"1", # tri_down
"2", # tri_up
"3", # tri_left
"4", # tri_right
",", # pixel
"_", # hline
"|", # vline
0, # tickleft
1, # tickright
2, # tickup
3, # tickdown
4, # caretleft
5, # caretright
6, # caretup
7, # caretdown
)
= len(filled_shapes)
n1 = len(unfilled_shapes)
n2 = 10
ncols = filled_shapes + unfilled_shapes
shapes
= pl.DataFrame({
df "x": np.hstack([np.arange(n1) % ncols, np.arange(n2) % ncols]),
"y": 4 - 1.5 * np.hstack([np.arange(n1) // ncols, np.arange(n2) // ncols]),
"shape": pl.Series(shapes, dtype=object),
"shape_kind": np.repeat(["Filled Shapes", "Unfilled Shapes"], (n1, n2))
})
df
shape: (31, 4)
x | y | shape | shape_kind |
---|---|---|---|
i64 | f64 | object | str |
0 | 4.0 | o | "Filled Shapes" |
1 | 4.0 | ^ | "Filled Shapes" |
2 | 4.0 | s | "Filled Shapes" |
3 | 4.0 | D | "Filled Shapes" |
4 | 4.0 | v | "Filled Shapes" |
… | … | … | … |
3 | 2.5 | 3 | "Unfilled Shapes" |
4 | 2.5 | 4 | "Unfilled Shapes" |
5 | 2.5 | 5 | "Unfilled Shapes" |
6 | 2.5 | 6 | "Unfilled Shapes" |
7 | 2.5 | 7 | "Unfilled Shapes" |
def double_quote_strings(series):
return [
'"{}"'.format(s) if isinstance(s, str) else "{}".format(s)
for s in series
]
("x", "y"))
ggplot(df, aes(
# Background
+ geom_tile(aes(width=0.9, height=0.9), fill="#F8F8F8")
# Cross-grid to help see the centering of the shapes
+ geom_segment(aes(x="x-0.45", xend="x+0.45", yend="y"), color="Crimson", alpha=0.05)
+ geom_segment(aes(xend="x", y="y-0.45", yend="y+0.45"), color="Crimson", alpha=0.05)
# The shape
+ geom_point(aes(shape="shape"), fill="#E5C8D6", size=8)
# Specification value for the shape
+ geom_text(
="y+.5", label="double_quote_strings(shape)"),
aes(y="darkblue",
color="bottom",
va
)
# Separate the shapes by their kind
+ facet_wrap("shape_kind", ncol=1)
# Make things pretty
+ lims(y=(2, 5))
+ scale_shape_identity()
+ coord_equal()
+ theme_void()
+ theme(
=element_rect(fill="white"),
plot_background=element_text(size=12)
strip_text
) )