Skip to content
This repository was archived by the owner on Jun 3, 2024. It is now read-only.

Commit 594ce1f

Browse files
init
0 parents  commit 594ce1f

File tree

1 file changed

+298
-0
lines changed

1 file changed

+298
-0
lines changed

Diff for: px.py

+298
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,298 @@
1+
import plotly.graph_objs as go
2+
3+
from collections import namedtuple
4+
5+
6+
default_color_seq = ["#3366cc", "#dc3912", "#ff9900", "#109618",
7+
"#990099", "#0099c6", "#dd4477", "#66aa00",
8+
"#b82e2e", "#316395", "#994499", "#22aa99",
9+
"#aaaa11", "#6633cc", "#e67300", "#8b0707",
10+
"#651067", "#329262", "#5574a6", "#3b3eac"]
11+
default_symbol_seq = ["circle", "triangle-down", "square", "x", "cross"]
12+
default_dash_seq = ["solid", "dot", "dash",
13+
"longdash", "dashdot", "longdashdot"]
14+
Mapping = namedtuple('Mapping', ['grouper', 'val_map', 'sequence', 'updater'])
15+
16+
17+
def make_mapping(variable, parent, args):
18+
return Mapping(
19+
grouper=args[variable],
20+
val_map=args[variable+"_map"].copy(),
21+
sequence=args[variable+"_sequence"],
22+
updater=lambda x: {parent: {variable: x}},
23+
)
24+
25+
26+
def make_figure(df, constructor, trace_kwargs_by_group, mappings):
27+
fig = go.FigureWidget(
28+
{"layout": {'template': 'plotly', 'hovermode': 'closest'}})
29+
30+
def one_group(x): return ""
31+
grouper = [x.grouper or one_group for x in mappings] or [one_group]
32+
for group_name, group in df.groupby(grouper):
33+
if len(grouper) == 1:
34+
group_name = [group_name]
35+
mapping_str = []
36+
for col, val in zip(grouper, group_name):
37+
if col != one_group:
38+
s = "%s=%s" % (col, val)
39+
if s not in mapping_str:
40+
mapping_str.append(s)
41+
trace = constructor(name=", ".join(mapping_str))
42+
for i, m in enumerate(mappings):
43+
val = group_name[i]
44+
if val not in m.val_map:
45+
m.val_map[val] = m.sequence[len(m.val_map) % len(m.sequence)]
46+
trace.update(m.updater(m.val_map[val]))
47+
trace.update(trace_kwargs_by_group(group))
48+
fig.add_trace(trace)
49+
return fig
50+
51+
52+
def cartesian_axes(fig, args):
53+
fig.layout.xaxis.title = args["x"]
54+
fig.layout.yaxis.title = args["y"]
55+
if args["log_x"]:
56+
fig.layout.xaxis.type = "log"
57+
if args["log_y"]:
58+
fig.layout.yaxis.type = "log"
59+
60+
61+
def scatter(df, x, y, color=None, symbol=None, size=None, name=None,
62+
color_map={}, symbol_map={},
63+
color_sequence=default_color_seq,
64+
symbol_sequence=default_symbol_seq,
65+
log_x=False, log_y=False):
66+
if size:
67+
sizeref = df[size].max() / (45*45)
68+
fig = make_figure(
69+
df, go.Scatter,
70+
lambda g: dict(mode='markers', x=g[x], y=g[y],
71+
hovertext=name and g[name],
72+
marker=size and dict(
73+
size=g[size], sizemode="area", sizeref=sizeref)
74+
),
75+
[
76+
make_mapping("color", "marker", locals()),
77+
make_mapping("symbol", "marker", locals())
78+
]
79+
)
80+
cartesian_axes(fig, locals())
81+
return fig
82+
83+
84+
def density_heatmap(df, x, y, log_x=False, log_y=False):
85+
fig = make_figure(
86+
df, go.Histogram2d,
87+
lambda g: dict(x=g[x], y=g[y]),
88+
[]
89+
)
90+
cartesian_axes(fig, locals())
91+
return fig
92+
93+
94+
def density_contour(df, x, y, log_x=False, log_y=False):
95+
fig = make_figure(
96+
df, go.Histogram2dContour,
97+
lambda g: dict(x=g[x], y=g[y]),
98+
[]
99+
)
100+
cartesian_axes(fig, locals())
101+
return fig
102+
103+
104+
def line(df, x, y, color=None, dash=None,
105+
color_map={}, dash_map={},
106+
color_sequence=default_color_seq,
107+
dash_sequence=default_dash_seq, log_x=False, log_y=False):
108+
fig = make_figure(
109+
df, go.Scatter,
110+
lambda g: dict(mode='lines', x=g[x], y=g[y]),
111+
[
112+
make_mapping("color", "marker", locals()),
113+
make_mapping("dash", "line", locals())
114+
]
115+
)
116+
cartesian_axes(fig, locals())
117+
return fig
118+
119+
120+
def bar(df, x, y, color=None, color_map={}, color_sequence=default_color_seq,
121+
orientation='v', normalization="", mode="relative", log_x=False, log_y=False):
122+
fig = make_figure(
123+
df, go.Bar,
124+
lambda g: dict(x=g[x], y=g[y], orientation=orientation),
125+
[make_mapping("color", "marker", locals())]
126+
)
127+
cartesian_axes(fig, locals())
128+
fig.layout.barnorm = normalization
129+
fig.layout.barmode = mode
130+
return fig
131+
132+
133+
def histogram(df, x, y, color=None, color_map={}, color_sequence=default_color_seq,
134+
orientation='v', mode="stack", normalization=None, log_x=False, log_y=False):
135+
fig = make_figure(
136+
df, go.Histogram,
137+
lambda g: dict(x=g[x], y=g[y], orientation=orientation,
138+
histnorm=normalization),
139+
[make_mapping("color", "marker", locals())]
140+
)
141+
cartesian_axes(fig, locals())
142+
fig.layout.barmode = mode
143+
return fig
144+
145+
146+
def violin(df, x, y, color=None, color_map={}, color_sequence=default_color_seq,
147+
orientation='v', mode="group", log_x=False, log_y=False):
148+
fig = make_figure(
149+
df, go.Violin,
150+
lambda g: dict(x=g[x], y=g[y], orientation=orientation),
151+
[make_mapping("color", "marker", locals())]
152+
)
153+
cartesian_axes(fig, locals())
154+
fig.layout.violinmode = mode
155+
return fig
156+
157+
158+
def box(df, x, y, color=None, color_map={}, color_sequence=default_color_seq,
159+
orientation='v', mode="group", log_x=False, log_y=False):
160+
fig = make_figure(
161+
df, go.Box,
162+
lambda g: dict(x=g[x], y=g[y], orientation=orientation),
163+
[make_mapping("color", "marker", locals())]
164+
)
165+
cartesian_axes(fig, locals())
166+
fig.layout.boxmode = mode
167+
return fig
168+
169+
170+
def scatter_ternary(df, a, b, c, color=None, symbol=None, size=None,
171+
color_map={}, symbol_map={},
172+
color_sequence=default_color_seq,
173+
symbol_sequence=default_symbol_seq):
174+
if size:
175+
sizeref = df[size].max() / (45*45)
176+
fig = make_figure(
177+
df, go.Scatterternary,
178+
lambda g: dict(mode='markers', a=g[a], b=g[b], c=g[c],
179+
marker=size and dict(
180+
size=g[size], sizemode="area", sizeref=sizeref)
181+
),
182+
[
183+
make_mapping("color", "marker", locals()),
184+
make_mapping("symbol", "marker", locals())
185+
]
186+
)
187+
fig.layout.ternary.aaxis.title = a
188+
fig.layout.ternary.baxis.title = b
189+
fig.layout.ternary.caxis.title = c
190+
return fig
191+
192+
193+
def line_ternary(df, a, b, c, color=None, dash=None,
194+
color_map={}, dash_map={},
195+
color_sequence=default_color_seq,
196+
dash_sequence=default_dash_seq):
197+
fig = make_figure(
198+
df, go.Scatter,
199+
lambda g: dict(mode='lines', a=g[a], b=g[b], c=g[c]),
200+
[
201+
make_mapping("color", "marker", locals()),
202+
make_mapping("dash", "line", locals())
203+
]
204+
)
205+
fig.layout.ternary.aaxis.title = a
206+
fig.layout.ternary.baxis.title = b
207+
fig.layout.ternary.caxis.title = c
208+
return fig
209+
210+
211+
def scatter_polar(df, r, theta, color=None, symbol=None, size=None,
212+
color_map={}, symbol_map={},
213+
color_sequence=default_color_seq,
214+
symbol_sequence=default_symbol_seq):
215+
if size:
216+
sizeref = df[size].max() / (45*45)
217+
fig = make_figure(
218+
df, go.Scatterpolar,
219+
lambda g: dict(mode='markers', r=g[r], theta=g[theta],
220+
marker=size and dict(
221+
size=g[size], sizemode="area", sizeref=sizeref)
222+
),
223+
[
224+
make_mapping("color", "marker", locals()),
225+
make_mapping("symbol", "marker", locals())
226+
]
227+
)
228+
return fig
229+
230+
231+
def line_polar(df, r, theta, color=None, dash=None,
232+
color_map={}, dash_map={},
233+
color_sequence=default_color_seq,
234+
dash_sequence=default_dash_seq):
235+
fig = make_figure(
236+
df, go.Scatter,
237+
lambda g: dict(mode='lines', r=g[r], theta=g[theta]),
238+
[
239+
make_mapping("color", "marker", locals()),
240+
make_mapping("dash", "line", locals())
241+
]
242+
)
243+
return fig
244+
245+
246+
def bar_polar(df, r, theta, color=None, color_map={}, color_sequence=default_color_seq,
247+
normalization="", mode="relative"):
248+
fig = make_figure(
249+
df, go.Barpolar,
250+
lambda g: dict(r=g[r], theta=g[theta]),
251+
[
252+
make_mapping("color", "marker", locals())
253+
]
254+
)
255+
fig.layout.barnorm = normalization
256+
fig.layout.barmode = mode
257+
return fig
258+
259+
260+
def splom(df, dimensions=None, color=None, symbol=None,
261+
color_map={}, symbol_map={},
262+
color_sequence=default_color_seq,
263+
symbol_sequence=default_symbol_seq):
264+
fig = make_figure(
265+
df, go.Splom,
266+
lambda g: dict(dimensions=[
267+
dict(label=name, values=column.values)
268+
for name, column in g.iteritems()
269+
if (
270+
(dimensions and name in dimensions) or
271+
(not dimensions and column.dtype in ["int64", "float64"])
272+
)
273+
]),
274+
[
275+
make_mapping("color", "marker", locals()),
276+
make_mapping("symbol", "marker", locals())
277+
]
278+
)
279+
return fig
280+
281+
# TODO canonical examples ... needed now!
282+
# TODO test with none, all, any mappings
283+
# TODO test each plot
284+
# TODO test defaults
285+
# TODO histogram weights and calcs
286+
# TODO various box and violin options
287+
# TODO log scales in SPLOM and generally in facets
288+
# TODO check on dates
289+
# TODO facets
290+
# TODO marginals
291+
# TODO validate inputs
292+
# TODO name / hover labels
293+
# TODO opacity
294+
# TODO continuous color
295+
# TODO color splits in densities
296+
# TODO groupby ignores NaN ... ?
297+
# TODO suppress plotly.py errors... don't show our programming errors?
298+
# TODO parcoords, parcats

0 commit comments

Comments
 (0)