lessPython 0.3.0__tar.gz → 0.3.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {lesspython-0.3.0/src/lessPython.egg-info → lesspython-0.3.1}/PKG-INFO +8 -1
- {lesspython-0.3.0 → lesspython-0.3.1}/README.md +7 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/pyproject.toml +1 -1
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/ANOVA.py +70 -11
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/Chart.py +49 -4
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/Correlation.py +39 -10
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/Flows.py +3 -3
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/Logit.py +14 -10
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/Regression.py +22 -18
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/X.py +3 -2
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/XY.py +528 -91
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/bc_items_plotly.py +2 -2
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/bc_plotly.py +6 -5
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/bubble_plotly.py +16 -15
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/corCFA.py +7 -3
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/corProp.py +7 -3
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/corReflect.py +7 -3
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/corReorder.py +7 -3
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/corScree.py +10 -6
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/dn_plotly.py +9 -9
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/dot_plotly.py +9 -8
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/freq_poly_plotly.py +6 -6
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/hier_plotly.py +5 -5
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/hs_plotly.py +7 -7
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/pie_plotly.py +1 -1
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/pivot.py +39 -9
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/plotly_utils.py +90 -26
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/plt_add.py +2 -7
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/plt_contour.py +6 -6
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/plt_contour_facet.py +3 -3
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/plt_mat_plotly.py +11 -10
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/plt_plotly.py +34 -18
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/plt_smooth.py +4 -4
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/prob_norm.py +5 -1
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/prob_tcut.py +5 -1
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/prob_znorm.py +5 -1
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/profile_plotly.py +5 -4
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/radar_plotly.py +4 -3
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/simCImean.py +5 -1
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/simCLT.py +5 -1
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/simFlips.py +5 -1
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/simMeans.py +5 -1
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/style.py +8 -1
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/sunflower_plotly.py +6 -5
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/ttest.py +13 -9
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/utils.py +103 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/vbs_plotly.py +23 -22
- {lesspython-0.3.0 → lesspython-0.3.1/src/lessPython.egg-info}/PKG-INFO +8 -1
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPython.egg-info/SOURCES.txt +3 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_anova.py +10 -1
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_chart.py +10 -0
- lesspython-0.3.1/tests/test_file_output.py +77 -0
- lesspython-0.3.1/tests/test_lessr_457_oct.py +171 -0
- lesspython-0.3.1/tests/test_plot_fixes.py +231 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_xy.py +5 -2
- {lesspython-0.3.0 → lesspython-0.3.1}/LICENSE +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/setup.cfg +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/Prop_test.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/VariableLabels.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/__init__.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/_themes.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/anova_rmd.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/corEFA.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/corPrint.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/corRead.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/data/Anova_1way.csv +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/data/Anova_2way.csv +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/data/Anova_rb.csv +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/data/Anova_rbf.csv +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/data/Anova_sp.csv +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/data/BodyMeas.csv +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/data/Cars93.csv +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/data/Employee.csv +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/data/Employee_lbl.csv +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/data/FreqTable99.csv +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/data/Jackets.csv +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/data/Learn.csv +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/data/Mach4.csv +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/data/Mach4_lbl.csv +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/data/Reading.csv +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/data/StockPrice.csv +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/data/WeightLoss.csv +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/datasets.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/date_infer.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/details.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/getColors.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/logit_rmd.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/order_by.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/plt_forecast.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/plt_time.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/rcolors.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/reg_rmd.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/rename.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/reshape.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/showColors.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/stats_out.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPy/x_console.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPython.egg-info/dependency_links.txt +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPython.egg-info/requires.txt +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/src/lessPython.egg-info/top_level.txt +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_bc_plotly.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_bubble_plotly.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_by_colors.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_chart_colors.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_chart_items.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_chart_ordered_fill.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_chart_stats.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_corcfa.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_corefa.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_corprint.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_corprop.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_corread.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_correflect.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_correlation.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_correorder.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_corscree.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_datasets.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_date_infer.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_details.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_dot_plotly.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_flows.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_getcolors.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_getcolors_r_palettes.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_hier_plotly.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_logit.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_order_by.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_pie_plotly.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_pivot.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_prob_norm.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_prob_tcut.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_prob_znorm.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_profile.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_prop_test.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_radar_plotly.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_regression.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_rename.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_reshape.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_showcolors.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_simcimean.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_simclt.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_simflips.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_simmeans.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_stats_out.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_style.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_ttest.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_variablelabels.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_vbs_plotly.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_x.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_x_console.py +0 -0
- {lesspython-0.3.0 → lesspython-0.3.1}/tests/test_xy_console.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: lessPython
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.1
|
|
4
4
|
Summary: Python port of R's lessR: analytic-view visualizations, statistical models, and data utilities, rendered with plotly
|
|
5
5
|
Author-email: "David W. Gerbing" <gerbing@pdx.edu>
|
|
6
6
|
License-Expression: GPL-2.0-or-later
|
|
@@ -119,6 +119,13 @@ when the analysis runs, even when the result is assigned, as
|
|
|
119
119
|
`r = lp.Regression(...)`. From a script, show one with
|
|
120
120
|
`r.plots["scatter"].show()`.
|
|
121
121
|
|
|
122
|
+
Every function that draws also takes `pdf_file=` and `png_file=`
|
|
123
|
+
(needs the png extra, `pip install "lessPython[png]"`, then
|
|
124
|
+
`plotly_get_chrome -y` once). A name such as `png_file="reg"`
|
|
125
|
+
names the file, or with several figures is the stem of each
|
|
126
|
+
name (`reg_scatter_matrix.png`), as lessR's `pdf_file=`. On Colab
|
|
127
|
+
the files also download to your computer.
|
|
128
|
+
|
|
122
129
|
## Development install
|
|
123
130
|
|
|
124
131
|
```
|
|
@@ -82,6 +82,13 @@ when the analysis runs, even when the result is assigned, as
|
|
|
82
82
|
`r = lp.Regression(...)`. From a script, show one with
|
|
83
83
|
`r.plots["scatter"].show()`.
|
|
84
84
|
|
|
85
|
+
Every function that draws also takes `pdf_file=` and `png_file=`
|
|
86
|
+
(needs the png extra, `pip install "lessPython[png]"`, then
|
|
87
|
+
`plotly_get_chrome -y` once). A name such as `png_file="reg"`
|
|
88
|
+
names the file, or with several figures is the stem of each
|
|
89
|
+
name (`reg_scatter_matrix.png`), as lessR's `pdf_file=`. On Colab
|
|
90
|
+
the files also download to your computer.
|
|
91
|
+
|
|
85
92
|
## Development install
|
|
86
93
|
|
|
87
94
|
```
|
|
@@ -12,7 +12,7 @@ build-backend = "setuptools.build_meta"
|
|
|
12
12
|
|
|
13
13
|
[project]
|
|
14
14
|
name = "lessPython"
|
|
15
|
-
version = "0.3.
|
|
15
|
+
version = "0.3.1"
|
|
16
16
|
description = "Python port of R's lessR: analytic-view visualizations, statistical models, and data utilities, rendered with plotly"
|
|
17
17
|
authors = [{ name = "David W. Gerbing", email = "gerbing@pdx.edu" }]
|
|
18
18
|
readme = "README.md"
|
|
@@ -22,10 +22,10 @@ import pandas as pd
|
|
|
22
22
|
import plotly.graph_objects as go
|
|
23
23
|
|
|
24
24
|
from .plotly_utils import (
|
|
25
|
-
BASE_COLORS, axis_cat, axis_format, axis_num, make_trans,
|
|
25
|
+
as_plotly_color, BASE_COLORS, axis_cat, axis_format, axis_num, make_trans,
|
|
26
26
|
plot_border, plotly_style, to_hex, x_grid)
|
|
27
27
|
from .Regression import _getdigits, _prntbl
|
|
28
|
-
from .utils import fmt, get_column, get_option, pretty, show_plots
|
|
28
|
+
from .utils import fmt, get_column, get_option, pretty, file_output, show_plots
|
|
29
29
|
|
|
30
30
|
|
|
31
31
|
class ANOVAResults:
|
|
@@ -380,6 +380,8 @@ def _oneway(fit, yv, gv, y_name, x_name, levels, n_keep, d,
|
|
|
380
380
|
lines += _prntbl(tukey, d).split("\n")
|
|
381
381
|
|
|
382
382
|
plots = {}
|
|
383
|
+
if graphics and tukey is not None:
|
|
384
|
+
plots["tukey"] = _tukey_plot(tukey, x_name, d)
|
|
383
385
|
if graphics:
|
|
384
386
|
plots["means"] = _anova_means_plot(
|
|
385
387
|
yv, gv, y_name, x_name, levels, jitter_x, d)
|
|
@@ -394,6 +396,59 @@ def _oneway(fit, yv, gv, y_name, x_name, levels, n_keep, d,
|
|
|
394
396
|
tukey=tukey, plots=plots))
|
|
395
397
|
|
|
396
398
|
|
|
399
|
+
def _tukey_plot(tukey, x_name, d):
|
|
400
|
+
"""Each pairwise difference of means with its 95% family-wise
|
|
401
|
+
interval, the first comparison at the top, and a dashed
|
|
402
|
+
reference line at 0. ~ .ANOVAz1 plot(TukeyHSD())"""
|
|
403
|
+
style = plotly_style()
|
|
404
|
+
k = len(tukey)
|
|
405
|
+
ypos = list(range(k, 0, -1))
|
|
406
|
+
col = as_plotly_color(get_option("pt_color", "#324E5C"))
|
|
407
|
+
fig = go.Figure()
|
|
408
|
+
for yp, (lbl, r) in zip(ypos, tukey.iterrows()):
|
|
409
|
+
fig.add_trace(go.Scatter(
|
|
410
|
+
x=[r["lwr"], r["upr"]], y=[yp, yp], mode="lines",
|
|
411
|
+
line=dict(color=col, width=2), hoverinfo="skip",
|
|
412
|
+
showlegend=False))
|
|
413
|
+
fig.add_trace(go.Scatter(
|
|
414
|
+
x=tukey["diff"], y=ypos, mode="markers",
|
|
415
|
+
marker=dict(symbol="circle", size=9, color=col),
|
|
416
|
+
customdata=np.column_stack([tukey["lwr"], tukey["upr"],
|
|
417
|
+
tukey["p adj"]]),
|
|
418
|
+
text=list(tukey.index),
|
|
419
|
+
hovertemplate=("%{text}<br>diff: %{x:." + str(d) + "f}"
|
|
420
|
+
"<br>95% CI: %{customdata[0]:." + str(d)
|
|
421
|
+
+ "f} to %{customdata[1]:." + str(d) + "f}"
|
|
422
|
+
"<br>p adj: %{customdata[2]:.3f}"
|
|
423
|
+
"<extra></extra>"),
|
|
424
|
+
showlegend=False))
|
|
425
|
+
axT1 = pretty(min(0.0, float(tukey["lwr"].min())),
|
|
426
|
+
max(0.0, float(tukey["upr"].max())))
|
|
427
|
+
ax_x = axis_num(f"Differences in mean levels of {x_name}", axT1,
|
|
428
|
+
axis_format(axT1, d))
|
|
429
|
+
ax_x.update(showgrid=True,
|
|
430
|
+
gridcolor=as_plotly_color(style["grid_col"]),
|
|
431
|
+
gridwidth=1, griddash="dot",
|
|
432
|
+
range=[axT1[0], axT1[-1]], zeroline=False)
|
|
433
|
+
ax_y = axis_cat("")
|
|
434
|
+
ax_y.update(tickmode="array", tickvals=ypos,
|
|
435
|
+
ticktext=list(tukey.index), range=[0.5, k + 0.5])
|
|
436
|
+
zero = dict(type="line", xref="x", yref="paper", x0=0, x1=0,
|
|
437
|
+
y0=0, y1=1, layer="below",
|
|
438
|
+
line=dict(color=as_plotly_color("gray50"), width=1,
|
|
439
|
+
dash="dash"))
|
|
440
|
+
fig.update_layout(
|
|
441
|
+
xaxis=ax_x, yaxis=ax_y, shapes=[zero] + list(plot_border()),
|
|
442
|
+
template=None,
|
|
443
|
+
plot_bgcolor=as_plotly_color(style["panel_fill"]),
|
|
444
|
+
paper_bgcolor=as_plotly_color(style["window_fill"]),
|
|
445
|
+
title=dict(text="95% family-wise confidence level",
|
|
446
|
+
x=0.5, xanchor="center",
|
|
447
|
+
font=dict(size=round(
|
|
448
|
+
16 * get_option("main_size", 1)))))
|
|
449
|
+
return fig
|
|
450
|
+
|
|
451
|
+
|
|
397
452
|
def _anova_means_plot(yv, gv, y_name, x_name, levels, jitter_x,
|
|
398
453
|
d):
|
|
399
454
|
"""Scatterplot of the response by factor level, jittered
|
|
@@ -410,18 +465,18 @@ def _anova_means_plot(yv, gv, y_name, x_name, levels, jitter_x,
|
|
|
410
465
|
x=xn, y=yv, mode="markers",
|
|
411
466
|
marker=dict(symbol="circle", size=6,
|
|
412
467
|
color=make_trans(pt, 0.85), opacity=1,
|
|
413
|
-
line=dict(color=
|
|
468
|
+
line=dict(color=as_plotly_color(pt), width=1)),
|
|
414
469
|
hoverinfo="y", showlegend=False))
|
|
415
470
|
means = [yv[gv == lv].mean() for lv in levels]
|
|
416
471
|
for i, mval in enumerate(means):
|
|
417
472
|
fig.add_shape(type="line", xref="x", yref="y",
|
|
418
473
|
x0=-0.5, x1=len(levels) - 0.5,
|
|
419
474
|
y0=mval, y1=mval, layer="below",
|
|
420
|
-
line=dict(color=
|
|
475
|
+
line=dict(color=as_plotly_color("gray70"), width=1))
|
|
421
476
|
fig.add_trace(go.Scatter(
|
|
422
477
|
x=list(range(len(levels))), y=means, mode="markers",
|
|
423
478
|
marker=dict(symbol="diamond", size=13,
|
|
424
|
-
color=
|
|
479
|
+
color=as_plotly_color(get_option("fit_color",
|
|
425
480
|
"#5C4032"))),
|
|
426
481
|
hoverinfo="x+y", showlegend=False))
|
|
427
482
|
axT2 = pretty(float(yv.min()), float(yv.max()))
|
|
@@ -431,13 +486,13 @@ def _anova_means_plot(yv, gv, y_name, x_name, levels, jitter_x,
|
|
|
431
486
|
ticktext=levels, range=[-0.5, len(levels) - 0.5])
|
|
432
487
|
ax_y = axis_num(y_name, axT2, axis_format(axT2, d))
|
|
433
488
|
ax_y.update(showgrid=True,
|
|
434
|
-
gridcolor=
|
|
489
|
+
gridcolor=as_plotly_color(style["grid_col"]),
|
|
435
490
|
gridwidth=1, griddash="dot")
|
|
436
491
|
fig.update_layout(
|
|
437
492
|
xaxis=ax_x, yaxis=ax_y, shapes=fig.layout.shapes
|
|
438
493
|
+ tuple(plot_border()), template=None,
|
|
439
|
-
plot_bgcolor=
|
|
440
|
-
paper_bgcolor=
|
|
494
|
+
plot_bgcolor=as_plotly_color(style["panel_fill"]),
|
|
495
|
+
paper_bgcolor=as_plotly_color(style["window_fill"]),
|
|
441
496
|
title=dict(text="Scatterplot with Cell Means",
|
|
442
497
|
x=0.5, xanchor="center",
|
|
443
498
|
font=dict(size=round(
|
|
@@ -644,13 +699,13 @@ def _cat_line_fig(title, x_name, y_name, levels_x, series, d,
|
|
|
644
699
|
range=[-0.4, len(levels_x) - 0.6])
|
|
645
700
|
ax_y = axis_num(y_name, axT2, axis_format(axT2, d))
|
|
646
701
|
ax_y.update(showgrid=True,
|
|
647
|
-
gridcolor=
|
|
702
|
+
gridcolor=as_plotly_color(style["grid_col"]),
|
|
648
703
|
gridwidth=1, griddash="dot")
|
|
649
704
|
fig.update_layout(
|
|
650
705
|
xaxis=ax_x, yaxis=ax_y, shapes=plot_border(),
|
|
651
706
|
template=None, legend=dict(title=dict(text=legend_title)),
|
|
652
|
-
plot_bgcolor=
|
|
653
|
-
paper_bgcolor=
|
|
707
|
+
plot_bgcolor=as_plotly_color(style["panel_fill"]),
|
|
708
|
+
paper_bgcolor=as_plotly_color(style["window_fill"]),
|
|
654
709
|
title=dict(text=title, x=0.5, xanchor="center",
|
|
655
710
|
font=dict(size=round(
|
|
656
711
|
16 * get_option("main_size", 1)))))
|
|
@@ -678,3 +733,7 @@ def _blocks_plot(x1v, yvals, x2v, y_name, f1, f2, l1, l2, d,
|
|
|
678
733
|
sub = dp[dp["b"] == b].set_index("a")["y"]
|
|
679
734
|
series.append((b, [sub.get(a, np.nan) for a in l1]))
|
|
680
735
|
return _cat_line_fig(title, f1, y_name, l1, series, d, f2)
|
|
736
|
+
|
|
737
|
+
|
|
738
|
+
# pdf_file= and png_file= write the figures, as lessR's pdf_file=
|
|
739
|
+
ANOVA = file_output(ANOVA)
|
|
@@ -402,7 +402,8 @@ def _chart_per_variable(data, items, cols, fill, xlab, main, quiet):
|
|
|
402
402
|
R analog: bc.data.frame()"""
|
|
403
403
|
from plotly.subplots import make_subplots
|
|
404
404
|
import plotly.graph_objects as go
|
|
405
|
-
from .plotly_utils import (
|
|
405
|
+
from .plotly_utils import (
|
|
406
|
+
as_plotly_color, BASE_COLORS, auto_text_color,
|
|
406
407
|
axis_format, plotly_style, to_hex)
|
|
407
408
|
from .stats_out import _counts_1d
|
|
408
409
|
show = not resolve_quiet(quiet)
|
|
@@ -466,8 +467,8 @@ def _chart_per_variable(data, items, cols, fill, xlab, main, quiet):
|
|
|
466
467
|
quiet)
|
|
467
468
|
fig.update_layout(
|
|
468
469
|
template=None, height=140 + 260 * n_row,
|
|
469
|
-
plot_bgcolor=
|
|
470
|
-
paper_bgcolor=
|
|
470
|
+
plot_bgcolor=as_plotly_color(st["panel_fill"]),
|
|
471
|
+
paper_bgcolor=as_plotly_color(st["window_fill"]),
|
|
471
472
|
title=(dict(text=main, x=0.5) if main else None))
|
|
472
473
|
return fig
|
|
473
474
|
|
|
@@ -1916,6 +1917,26 @@ def Chart(x, y=None, data=None, filter=None, by=None, facet=None,
|
|
|
1916
1917
|
facet_name=facet_ttl, y_name=y_name, stat=stat)
|
|
1917
1918
|
elif main == "":
|
|
1918
1919
|
main = None
|
|
1920
|
+
# a palette name in fill names the palette, not a color, as
|
|
1921
|
+
# for the bar chart. A sequential palette shades each slice
|
|
1922
|
+
# by its value off the palette's ramp, larger darker, as
|
|
1923
|
+
# for the treemap. R analog: Chart.R pie palette branch
|
|
1924
|
+
if isinstance(fill, str) and fill in _palette_names():
|
|
1925
|
+
from .hier_plotly import _HIER_SEQ
|
|
1926
|
+
slices = list(tbl.columns if isinstance(tbl, pd.DataFrame)
|
|
1927
|
+
else tbl.index)
|
|
1928
|
+
vals = (tbl.sum(axis=0) if isinstance(tbl, pd.DataFrame)
|
|
1929
|
+
else tbl).to_numpy(dtype=float)
|
|
1930
|
+
if (fill.lower() in _HIER_SEQ and len(slices) > 1
|
|
1931
|
+
and np.ptp(vals) > 0):
|
|
1932
|
+
from .getColors import getColors
|
|
1933
|
+
ramp = [c[:7] for c in getColors(fill.lower(), n=256,
|
|
1934
|
+
quiet=True)]
|
|
1935
|
+
pos = (vals - vals.min()) / np.ptp(vals)
|
|
1936
|
+
fill = [ramp[i] for i in
|
|
1937
|
+
np.round(pos * (len(ramp) - 1)).astype(int)]
|
|
1938
|
+
else:
|
|
1939
|
+
fill = _color_range(fill, len(slices))
|
|
1919
1940
|
return pie_plotly(
|
|
1920
1941
|
tbl,
|
|
1921
1942
|
x_name=x, y_name=y_name, by_name=by, main=main,
|
|
@@ -1984,6 +2005,30 @@ def Chart(x, y=None, data=None, filter=None, by=None, facet=None,
|
|
|
1984
2005
|
return fig
|
|
1985
2006
|
|
|
1986
2007
|
|
|
2008
|
+
def _with_height(func):
|
|
2009
|
+
"""height= in inches, as lessR's Chart(height=), converted at
|
|
2010
|
+
96 pixels per inch, so pdf_file= also writes that height.
|
|
2011
|
+
None keeps the figure's own height."""
|
|
2012
|
+
import functools
|
|
2013
|
+
|
|
2014
|
+
@functools.wraps(func)
|
|
2015
|
+
def wrapper(*args, height=None, **kwargs):
|
|
2016
|
+
if height is not None and (isinstance(height, bool) or
|
|
2017
|
+
not isinstance(height, (int, float))
|
|
2018
|
+
or height <= 0):
|
|
2019
|
+
raise ValueError(
|
|
2020
|
+
f"height is in inches, a positive number such as "
|
|
2021
|
+
f"height=4, not {height!r}")
|
|
2022
|
+
fig = func(*args, **kwargs)
|
|
2023
|
+
if height is not None and hasattr(fig, "layout"):
|
|
2024
|
+
fig.update_layout(height=round(96 * height))
|
|
2025
|
+
return fig
|
|
2026
|
+
|
|
2027
|
+
return wrapper
|
|
2028
|
+
|
|
2029
|
+
|
|
1987
2030
|
# font_size= scales all text of the returned figure
|
|
1988
2031
|
from .style import with_theme as _with_theme # noqa: E402
|
|
1989
|
-
|
|
2032
|
+
from .utils import file_output # noqa: E402
|
|
2033
|
+
Chart = file_output(_with_height(font_scaled(attach_stats(
|
|
2034
|
+
_with_theme(Chart, own_param=True)))))
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
import numpy as np
|
|
13
13
|
import pandas as pd
|
|
14
14
|
|
|
15
|
-
from .utils import fmt, get_column, get_option, show_plots
|
|
15
|
+
from .utils import fmt, get_column, get_option, file_output, show_plots
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
class CorrelationResults:
|
|
@@ -110,6 +110,7 @@ def _two_var(x, y, x_name, y_name, method, brief):
|
|
|
110
110
|
r, p = sps.pearsonr(xk, yk)
|
|
111
111
|
df = n - 2
|
|
112
112
|
t = r * np.sqrt(df / (1 - r ** 2))
|
|
113
|
+
stat_nm = "t"
|
|
113
114
|
p = 2 * sps.t.sf(abs(t), df)
|
|
114
115
|
z = np.arctanh(r)
|
|
115
116
|
sig = 1 / np.sqrt(n - 3)
|
|
@@ -119,17 +120,41 @@ def _two_var(x, y, x_name, y_name, method, brief):
|
|
|
119
120
|
sym, sym_pop = "r", "Correlation"
|
|
120
121
|
cov = float(np.cov(xk, yk)[0, 1])
|
|
121
122
|
elif method == "spearman":
|
|
123
|
+
# the statistic cor.test() reports: S, the sum of the squared
|
|
124
|
+
# rank differences, with no df. R analog: cr.main.R
|
|
125
|
+
# names(ct$statistic)
|
|
122
126
|
res = sps.spearmanr(xk, yk)
|
|
123
127
|
r, p = float(res.statistic), float(res.pvalue)
|
|
124
|
-
t, df =
|
|
125
|
-
(n - 2) / (1 - r ** 2)), n - 2
|
|
128
|
+
t, df, stat_nm = (n ** 3 - n) * (1 - r) / 6, None, "S"
|
|
126
129
|
method_txt = "Spearman's rank correlation rho"
|
|
127
130
|
sym = sym_pop = "rho"
|
|
128
131
|
else:
|
|
132
|
+
# cor.test(): T, the count of concordant pairs, with its exact
|
|
133
|
+
# p-value for n < 50 and no ties, else z with the variance
|
|
134
|
+
# corrected for ties
|
|
129
135
|
res = sps.kendalltau(xk, yk)
|
|
130
|
-
r
|
|
131
|
-
|
|
136
|
+
r = float(res.statistic)
|
|
137
|
+
_, xt = np.unique(xk, return_counts=True)
|
|
138
|
+
_, yt = np.unique(yk, return_counts=True)
|
|
139
|
+
ties = (xt > 1).any() or (yt > 1).any()
|
|
132
140
|
df = None
|
|
141
|
+
if n < 50 and not ties:
|
|
142
|
+
t, stat_nm = (r + 1) * n * (n - 1) / 4, "T"
|
|
143
|
+
p = float(sps.kendalltau(xk, yk, method="exact").pvalue)
|
|
144
|
+
else:
|
|
145
|
+
T0 = n * (n - 1) / 2
|
|
146
|
+
S = r * np.sqrt((T0 - (xt * (xt - 1)).sum() / 2)
|
|
147
|
+
* (T0 - (yt * (yt - 1)).sum() / 2))
|
|
148
|
+
v0 = n * (n - 1) * (2 * n + 5)
|
|
149
|
+
vt = (xt * (xt - 1) * (2 * xt + 5)).sum()
|
|
150
|
+
vu = (yt * (yt - 1) * (2 * yt + 5)).sum()
|
|
151
|
+
v1 = (xt * (xt - 1)).sum() * (yt * (yt - 1)).sum()
|
|
152
|
+
v2 = ((xt * (xt - 1) * (xt - 2)).sum()
|
|
153
|
+
* (yt * (yt - 1) * (yt - 2)).sum())
|
|
154
|
+
var_S = ((v0 - vt - vu) / 18 + v1 / (2 * n * (n - 1))
|
|
155
|
+
+ v2 / (9 * n * (n - 1) * (n - 2)))
|
|
156
|
+
t, stat_nm = S / np.sqrt(var_S), "z"
|
|
157
|
+
p = float(2 * sps.norm.sf(abs(t)))
|
|
133
158
|
method_txt = "Kendall's rank correlation tau"
|
|
134
159
|
sym = sym_pop = "tau"
|
|
135
160
|
|
|
@@ -152,9 +177,9 @@ def _two_var(x, y, x_name, y_name, method, brief):
|
|
|
152
177
|
else:
|
|
153
178
|
L.append(f"Sample Correlation: {sym} = {fmt(r, 3)}")
|
|
154
179
|
L.append("")
|
|
155
|
-
dfs = "
|
|
156
|
-
L.append(f"Hypothesis Test of 0 {sym_pop}:
|
|
157
|
-
f"
|
|
180
|
+
dfs = "" if df is None else f", df = {df}"
|
|
181
|
+
L.append(f"Hypothesis Test of 0 {sym_pop}: {stat_nm} = "
|
|
182
|
+
f"{fmt(t, 3)}{dfs}, p-value = {fmt(p, 3)}")
|
|
158
183
|
if method == "pearson":
|
|
159
184
|
L.append("95% Confidence Interval for Correlation: "
|
|
160
185
|
f"{fmt(lb, 3)} to {fmt(ub, 3)}")
|
|
@@ -228,7 +253,7 @@ def _matrix(df, miss, show, method, digits_d, heat_map, main):
|
|
|
228
253
|
def _heatmap(df, main):
|
|
229
254
|
import plotly.graph_objects as go
|
|
230
255
|
|
|
231
|
-
from .plotly_utils import plotly_style, to_hex
|
|
256
|
+
from .plotly_utils import as_plotly_color, plotly_style, to_hex
|
|
232
257
|
labels = list(df.columns)
|
|
233
258
|
Z = df.to_numpy(dtype=float).copy()
|
|
234
259
|
np.fill_diagonal(Z, np.nan)
|
|
@@ -239,9 +264,13 @@ def _heatmap(df, main):
|
|
|
239
264
|
colorbar=dict(title="r")))
|
|
240
265
|
fig.update_yaxes(autorange="reversed")
|
|
241
266
|
fig.update_layout(
|
|
242
|
-
template=None, paper_bgcolor=
|
|
267
|
+
template=None, paper_bgcolor=as_plotly_color(style["window_fill"]),
|
|
243
268
|
title=dict(text=main or "Correlations", x=0.5,
|
|
244
269
|
xanchor="center",
|
|
245
270
|
font=dict(size=round(
|
|
246
271
|
16 * get_option("main_size", 1)))))
|
|
247
272
|
return fig
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
# pdf_file= and png_file= write the figures, as lessR's pdf_file=
|
|
276
|
+
Correlation = file_output(Correlation)
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
import numpy as np
|
|
10
10
|
import pandas as pd
|
|
11
11
|
|
|
12
|
-
from .plotly_utils import BASE_COLORS, make_trans, to_hex
|
|
12
|
+
from .plotly_utils import as_plotly_color, BASE_COLORS, make_trans, to_hex
|
|
13
13
|
from .utils import get_column, get_option
|
|
14
14
|
|
|
15
15
|
|
|
@@ -96,7 +96,7 @@ def Flows(value, stage1, stage2, stage3=None, data=None,
|
|
|
96
96
|
node=dict(
|
|
97
97
|
label=nodes, color=node_color, x=node_x, y=node_y,
|
|
98
98
|
pad=12, thickness=16,
|
|
99
|
-
line=dict(color=
|
|
99
|
+
line=dict(color=as_plotly_color(border_gray), width=1),
|
|
100
100
|
hovertemplate="%{label}<extra></extra>"),
|
|
101
101
|
link=dict(
|
|
102
102
|
source=src, target=tgt, value=val, color=lcol,
|
|
@@ -116,5 +116,5 @@ def Flows(value, stage1, stage2, stage3=None, data=None,
|
|
|
116
116
|
r=30, b=30, l=30),
|
|
117
117
|
font=dict(size=round(15 * labels_size)),
|
|
118
118
|
template=None,
|
|
119
|
-
paper_bgcolor=
|
|
119
|
+
paper_bgcolor=as_plotly_color(get_option("window_fill", "white")))
|
|
120
120
|
return fig
|
|
@@ -36,13 +36,13 @@ import pandas as pd
|
|
|
36
36
|
import plotly.graph_objects as go
|
|
37
37
|
|
|
38
38
|
from .plotly_utils import (
|
|
39
|
-
axis_format, axis_num, make_trans, plot_border,
|
|
39
|
+
as_plotly_color, axis_format, axis_num, make_trans, plot_border,
|
|
40
40
|
plotly_style, to_hex, x_grid)
|
|
41
41
|
from .plt_mat_plotly import scatter_matrix
|
|
42
42
|
from .logit_rmd import logit_rmd
|
|
43
43
|
from .Regression import (
|
|
44
44
|
_expand_indicators, _parse_formula, _prntbl)
|
|
45
|
-
from .utils import fmt, get_column, get_option, pretty, show_plots
|
|
45
|
+
from .utils import fmt, get_column, get_option, pretty, file_output, show_plots
|
|
46
46
|
|
|
47
47
|
|
|
48
48
|
class LogitResults:
|
|
@@ -564,13 +564,13 @@ def _logit_plot(xv, y01, mu, levels, y_name, x_name, pc,
|
|
|
564
564
|
color=make_trans(pt_fill,
|
|
565
565
|
1 - transparency),
|
|
566
566
|
opacity=1,
|
|
567
|
-
line=dict(color=
|
|
567
|
+
line=dict(color=as_plotly_color(pt_fill),
|
|
568
568
|
width=1)),
|
|
569
569
|
hoverinfo="x+y", showlegend=False))
|
|
570
570
|
od = np.argsort(xv, kind="stable")
|
|
571
571
|
fig.add_trace(go.Scatter(
|
|
572
572
|
x=xv[od], y=mu[od], mode="lines",
|
|
573
|
-
line=dict(color=
|
|
573
|
+
line=dict(color=as_plotly_color(pt_fill), width=2),
|
|
574
574
|
hoverinfo="skip", showlegend=False))
|
|
575
575
|
axT1 = pretty(float(xv.min()), float(xv.max()))
|
|
576
576
|
axT2 = [0, 0.2, 0.4, 0.6, 0.8, 1]
|
|
@@ -579,7 +579,7 @@ def _logit_plot(xv, y01, mu, levels, y_name, x_name, pc,
|
|
|
579
579
|
ax_y = axis_num(y_lab, axT2,
|
|
580
580
|
[f"{v:g}" for v in axT2])
|
|
581
581
|
ax_y.update(range=[-0.10, 1.10], showgrid=True,
|
|
582
|
-
gridcolor=
|
|
582
|
+
gridcolor=as_plotly_color(style_opts["grid_col"]),
|
|
583
583
|
gridwidth=1, griddash="dot")
|
|
584
584
|
shapes = x_grid(axT1) + plot_border()
|
|
585
585
|
if pc is not None: # threshold crosshairs
|
|
@@ -588,13 +588,13 @@ def _logit_plot(xv, y01, mu, levels, y_name, x_name, pc,
|
|
|
588
588
|
shapes.append(dict(
|
|
589
589
|
type="line", xref="paper", yref="y",
|
|
590
590
|
x0=0, x1=1, y0=pc, y1=pc,
|
|
591
|
-
line=dict(color=
|
|
591
|
+
line=dict(color=as_plotly_color("gray35"), width=0.75,
|
|
592
592
|
dash="dash")))
|
|
593
593
|
if float(xv.min()) <= x_cut <= float(xv.max()):
|
|
594
594
|
shapes.append(dict(
|
|
595
595
|
type="line", xref="x", yref="paper",
|
|
596
596
|
x0=x_cut, x1=x_cut, y0=0, y1=1,
|
|
597
|
-
line=dict(color=
|
|
597
|
+
line=dict(color=as_plotly_color("gray35"), width=0.75,
|
|
598
598
|
dash="dash")))
|
|
599
599
|
anns = []
|
|
600
600
|
if levels is not None: # right-axis level labels
|
|
@@ -605,11 +605,15 @@ def _logit_plot(xv, y01, mu, levels, y_name, x_name, pc,
|
|
|
605
605
|
xanchor="left",
|
|
606
606
|
font=dict(size=round(
|
|
607
607
|
14 * get_option("axis_size", 0.9)),
|
|
608
|
-
color=
|
|
608
|
+
color=as_plotly_color(get_option(
|
|
609
609
|
"axis_color", "black")))))
|
|
610
610
|
fig.update_layout(
|
|
611
611
|
xaxis=ax_x, yaxis=ax_y, shapes=shapes,
|
|
612
612
|
annotations=anns, template=None,
|
|
613
|
-
plot_bgcolor=
|
|
614
|
-
paper_bgcolor=
|
|
613
|
+
plot_bgcolor=as_plotly_color(style_opts["panel_fill"]),
|
|
614
|
+
paper_bgcolor=as_plotly_color(style_opts["window_fill"]))
|
|
615
615
|
return fig
|
|
616
|
+
|
|
617
|
+
|
|
618
|
+
# pdf_file= and png_file= write the figures, as lessR's pdf_file=
|
|
619
|
+
Logit = file_output(Logit)
|
|
@@ -51,7 +51,7 @@ from .plotly_utils import (
|
|
|
51
51
|
make_trans, plot_border, plotly_style, to_hex, x_grid)
|
|
52
52
|
from .utils import (
|
|
53
53
|
category_order, fmt, get_column, get_option, pretty,
|
|
54
|
-
show_plots)
|
|
54
|
+
file_output, show_plots)
|
|
55
55
|
from .X import _breaks_from_args
|
|
56
56
|
|
|
57
57
|
|
|
@@ -1228,13 +1228,13 @@ def _moderation_plot(fit, Xd, y_name, mod_info, d):
|
|
|
1228
1228
|
ax_x = axis_num(x_name, axT1, axis_format(axT1, d))
|
|
1229
1229
|
ax_y = axis_num(y_name, axT2, axis_format(axT2, d))
|
|
1230
1230
|
ax_y.update(showgrid=True,
|
|
1231
|
-
gridcolor=
|
|
1231
|
+
gridcolor=as_plotly_color(style_opts["grid_col"]),
|
|
1232
1232
|
gridwidth=1, griddash="dot")
|
|
1233
1233
|
fig.update_layout(
|
|
1234
1234
|
xaxis=ax_x, yaxis=ax_y,
|
|
1235
1235
|
shapes=x_grid(axT1) + plot_border(), template=None,
|
|
1236
|
-
plot_bgcolor=
|
|
1237
|
-
paper_bgcolor=
|
|
1236
|
+
plot_bgcolor=as_plotly_color(style_opts["panel_fill"]),
|
|
1237
|
+
paper_bgcolor=as_plotly_color(style_opts["window_fill"]),
|
|
1238
1238
|
legend=dict(title=dict(text=w_name)),
|
|
1239
1239
|
title=dict(text="Moderator Variable Interaction Plot",
|
|
1240
1240
|
x=0.5, xanchor="center",
|
|
@@ -1331,13 +1331,13 @@ def _reg_ancova_plot(fit, Xd, yv, y_name, info, d):
|
|
|
1331
1331
|
ax_x = axis_num(cov, axT1, axis_format(axT1, d))
|
|
1332
1332
|
ax_y = axis_num(y_name, axT2, axis_format(axT2, d))
|
|
1333
1333
|
ax_y.update(showgrid=True,
|
|
1334
|
-
gridcolor=
|
|
1334
|
+
gridcolor=as_plotly_color(style_opts["grid_col"]),
|
|
1335
1335
|
gridwidth=1, griddash="dot")
|
|
1336
1336
|
fig.update_layout(
|
|
1337
1337
|
xaxis=ax_x, yaxis=ax_y,
|
|
1338
1338
|
shapes=x_grid(axT1) + plot_border(), template=None,
|
|
1339
|
-
plot_bgcolor=
|
|
1340
|
-
paper_bgcolor=
|
|
1339
|
+
plot_bgcolor=as_plotly_color(style_opts["panel_fill"]),
|
|
1340
|
+
paper_bgcolor=as_plotly_color(style_opts["window_fill"]),
|
|
1341
1341
|
legend=dict(title=dict(text=fac)),
|
|
1342
1342
|
title=dict(text="Scatterplot and Least-Squares Lines",
|
|
1343
1343
|
x=0.5, xanchor="center",
|
|
@@ -1384,11 +1384,11 @@ def _reg_scatter(xv, yv, x_name, y_name, fit, smapi, digits_d,
|
|
|
1384
1384
|
sizemode="diameter",
|
|
1385
1385
|
color=make_trans(pt_fill, 0.9),
|
|
1386
1386
|
opacity=1,
|
|
1387
|
-
line=dict(color=
|
|
1387
|
+
line=dict(color=as_plotly_color(pt_fill), width=1)),
|
|
1388
1388
|
hoverinfo="x+y", showlegend=False))
|
|
1389
1389
|
fig.add_trace(go.Scatter(
|
|
1390
1390
|
x=xs, y=sf["mean"].to_numpy(), mode="lines",
|
|
1391
|
-
line=dict(color=
|
|
1391
|
+
line=dict(color=as_plotly_color(get_option("fit_color",
|
|
1392
1392
|
"#5C4032")),
|
|
1393
1393
|
width=get_option("fit_lwd", 2)),
|
|
1394
1394
|
hoverinfo="skip", showlegend=False))
|
|
@@ -1405,7 +1405,7 @@ def _reg_scatter(xv, yv, x_name, y_name, fit, smapi, digits_d,
|
|
|
1405
1405
|
ax_y = axis_num(y_name, axT2,
|
|
1406
1406
|
axis_format(axT2, digits_d))
|
|
1407
1407
|
ax_y.update(showgrid=True,
|
|
1408
|
-
gridcolor=
|
|
1408
|
+
gridcolor=as_plotly_color(style_opts["grid_col"]),
|
|
1409
1409
|
gridwidth=1, griddash="dot")
|
|
1410
1410
|
title = ("Reg Line, Confidence & Prediction Intervals"
|
|
1411
1411
|
if with_bands
|
|
@@ -1413,8 +1413,8 @@ def _reg_scatter(xv, yv, x_name, y_name, fit, smapi, digits_d,
|
|
|
1413
1413
|
fig.update_layout(
|
|
1414
1414
|
xaxis=ax_x, yaxis=ax_y,
|
|
1415
1415
|
shapes=x_grid(axT1) + plot_border(), template=None,
|
|
1416
|
-
plot_bgcolor=
|
|
1417
|
-
paper_bgcolor=
|
|
1416
|
+
plot_bgcolor=as_plotly_color(style_opts["panel_fill"]),
|
|
1417
|
+
paper_bgcolor=as_plotly_color(style_opts["window_fill"]),
|
|
1418
1418
|
title=dict(text=title, x=0.5, xanchor="center",
|
|
1419
1419
|
font=dict(size=round(
|
|
1420
1420
|
16 * get_option("main_size", 1)))))
|
|
@@ -1444,14 +1444,14 @@ def _reg_resfit(fitted, resid, cooks, cooks_cut, labels,
|
|
|
1444
1444
|
sizemode="diameter",
|
|
1445
1445
|
color=make_trans(pt_fill, 0.9),
|
|
1446
1446
|
opacity=1,
|
|
1447
|
-
line=dict(color=
|
|
1447
|
+
line=dict(color=as_plotly_color(pt_fill), width=0.5)),
|
|
1448
1448
|
hoverinfo="x+y", showlegend=False))
|
|
1449
1449
|
flag = np.where(cooks >= cut)[0]
|
|
1450
1450
|
for i in flag:
|
|
1451
1451
|
fig.add_annotation(
|
|
1452
1452
|
x=float(fitted[i]), y=float(resid[i]),
|
|
1453
1453
|
text=str(labels[i]), showarrow=False, yshift=12,
|
|
1454
|
-
font=dict(size=11, color=
|
|
1454
|
+
font=dict(size=11, color=as_plotly_color("gray30")))
|
|
1455
1455
|
axT1 = pretty(float(fitted.min()), float(fitted.max()))
|
|
1456
1456
|
axT2 = pretty(float(resid.min()), float(resid.max()))
|
|
1457
1457
|
ax_x = axis_num("Fitted Values", axT1,
|
|
@@ -1459,18 +1459,18 @@ def _reg_resfit(fitted, resid, cooks, cooks_cut, labels,
|
|
|
1459
1459
|
ax_y = axis_num("Residuals", axT2,
|
|
1460
1460
|
axis_format(axT2, digits_d))
|
|
1461
1461
|
ax_y.update(showgrid=True,
|
|
1462
|
-
gridcolor=
|
|
1462
|
+
gridcolor=as_plotly_color(style_opts["grid_col"]),
|
|
1463
1463
|
gridwidth=1, griddash="dot")
|
|
1464
1464
|
shapes = x_grid(axT1) + plot_border()
|
|
1465
1465
|
shapes.append(dict( # zero residual line
|
|
1466
1466
|
type="line", xref="paper", yref="y",
|
|
1467
1467
|
x0=0, x1=1, y0=0, y1=0,
|
|
1468
|
-
line=dict(color=
|
|
1468
|
+
line=dict(color=as_plotly_color("gray50"), width=1,
|
|
1469
1469
|
dash="dash")))
|
|
1470
1470
|
fig.update_layout(
|
|
1471
1471
|
xaxis=ax_x, yaxis=ax_y, shapes=shapes, template=None,
|
|
1472
|
-
plot_bgcolor=
|
|
1473
|
-
paper_bgcolor=
|
|
1472
|
+
plot_bgcolor=as_plotly_color(style_opts["panel_fill"]),
|
|
1473
|
+
paper_bgcolor=as_plotly_color(style_opts["window_fill"]),
|
|
1474
1474
|
title=dict(
|
|
1475
1475
|
text=("Residuals vs Fitted Values<br>"
|
|
1476
1476
|
f"<sup>{sub}</sup>"),
|
|
@@ -1491,3 +1491,7 @@ def _reg_dn_residual(resid):
|
|
|
1491
1491
|
show_histogram=True, hist_edges=edges,
|
|
1492
1492
|
main="Distribution of Residuals")
|
|
1493
1493
|
return fig
|
|
1494
|
+
|
|
1495
|
+
|
|
1496
|
+
# pdf_file= and png_file= write the figures, as lessR's pdf_file=
|
|
1497
|
+
Regression = file_output(Regression)
|
|
@@ -659,5 +659,6 @@ def _per_variable(func):
|
|
|
659
659
|
# font_size= scales all text of the returned figure
|
|
660
660
|
from .stats_out import attach_stats as _attach_stats # noqa: E402
|
|
661
661
|
from .style import with_theme as _with_theme # noqa: E402
|
|
662
|
-
|
|
663
|
-
|
|
662
|
+
from .utils import file_output # noqa: E402
|
|
663
|
+
X = file_output(_per_variable(font_scaled(_attach_stats(
|
|
664
|
+
_with_theme(X), capture=True))))
|