oh shit im scared, but its alive

This commit is contained in:
dan
2025-12-15 18:38:10 +03:00
parent b850d4459b
commit e2a36c74a3
51 changed files with 4956 additions and 578 deletions

View File

@@ -223,6 +223,7 @@ def plot_density_scatter(
rolling_window: int = DEFAULT_ROLLING_WINDOW, rolling_window: int = DEFAULT_ROLLING_WINDOW,
savgol_window: int = DEFAULT_SAVGOL_WINDOW, savgol_window: int = DEFAULT_SAVGOL_WINDOW,
savgol_poly: int = DEFAULT_SAVGOL_POLY, savgol_poly: int = DEFAULT_SAVGOL_POLY,
return_fig: bool = False,
) -> None: ) -> None:
fig, ax = plt.subplots(figsize=(8, 8)) fig, ax = plt.subplots(figsize=(8, 8))
alpha_values = compute_density_alpha( alpha_values = compute_density_alpha(
@@ -246,6 +247,7 @@ def plot_density_scatter(
linewidths=0, linewidths=0,
) )
trend_data = None
if with_trend: if with_trend:
tx, ty = compute_trend( tx, ty = compute_trend(
df, df,
@@ -260,6 +262,7 @@ def plot_density_scatter(
if len(tx): if len(tx):
ax.plot(tx, ty, color=trend_color, linewidth=trend_linewidth, label=f"{trend_method} тренд") ax.plot(tx, ty, color=trend_color, linewidth=trend_linewidth, label=f"{trend_method} тренд")
ax.legend() ax.legend()
trend_data = (tx, ty)
ax.set_xlim(0, x_max) ax.set_xlim(0, x_max)
ax.set_ylim(y_min, y_max) ax.set_ylim(y_min, y_max)
@@ -272,6 +275,8 @@ def plot_density_scatter(
out_path.parent.mkdir(parents=True, exist_ok=True) out_path.parent.mkdir(parents=True, exist_ok=True)
fig.tight_layout() fig.tight_layout()
fig.savefig(out_path, dpi=150) fig.savefig(out_path, dpi=150)
if return_fig:
return fig, ax, trend_data
plt.close(fig) plt.close(fig)
print(f"Saved {out_path}") print(f"Saved {out_path}")
@@ -426,7 +431,7 @@ def plot_clean_trend_scatter(
q_low=q_low, q_low=q_low,
q_high=q_high, q_high=q_high,
) )
plot_density_scatter( fig_ax = plot_density_scatter(
cleaned, cleaned,
y_col=y_col, y_col=y_col,
title=f"Облако без выбросов + тренд {y_col} vs {x_col}", title=f"Облако без выбросов + тренд {y_col} vs {x_col}",
@@ -450,9 +455,11 @@ def plot_clean_trend_scatter(
rolling_window=rolling_window, rolling_window=rolling_window,
savgol_window=savgol_window, savgol_window=savgol_window,
savgol_poly=savgol_poly, savgol_poly=savgol_poly,
return_fig=return_components,
) )
if return_components: if return_components:
return fig, ax, cleaned fig, ax, trend_data = fig_ax
return fig, ax, cleaned, trend_data
def generate_scatter_set( def generate_scatter_set(

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 KiB

View File

@@ -0,0 +1,353 @@
import sqlite3
from pathlib import Path
import sys
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns
import statsmodels.api as sm
from sklearn.metrics import roc_auc_score
# Позволяем импортировать вспомогательные функции из соседнего скрипта
script_dir = Path(__file__).resolve().parent
if str(script_dir) not in sys.path:
sys.path.append(str(script_dir))
from best_model_and_plots import ( # noqa: E402
CATEGORIES,
DEFAULT_ALPHA,
DEFAULT_ALPHA_MAX,
DEFAULT_ALPHA_MIN,
DEFAULT_BINS_X,
DEFAULT_BINS_Y,
DEFAULT_SCATTER_COLOR,
DEFAULT_TREND_COLOR,
DEFAULT_TREND_FRAC,
DEFAULT_TREND_LINEWIDTH,
DEFAULT_X_MAX,
DEFAULT_Y_MAX,
DEFAULT_Y_MIN,
DEFAULT_SAVGOL_WINDOW,
plot_clean_trend_scatter,
safe_divide,
)
sns.set_theme(style="whitegrid")
plt.rcParams["figure.figsize"] = (8, 8)
project_root = Path(__file__).resolve().parent.parent
DB_PATH = project_root / "dataset" / "ds.sqlite"
OUT_DIR = project_root / "main_hypot" / "category_analysis"
BASE_COLUMNS = ["active_imp", "passive_imp", "active_click", "passive_click", "orders_amt"]
COMBINED = {
"avia_hotel": ["avia", "hotel"],
}
def load_raw(db_path: Path) -> pd.DataFrame:
conn = sqlite3.connect(db_path)
df = pd.read_sql_query("select * from communications", conn, parse_dates=["business_dt"])
conn.close()
return df
def build_client_by_category(df: pd.DataFrame) -> pd.DataFrame:
agg_spec = {f"{col}_{cat}": "sum" for col in BASE_COLUMNS for cat in CATEGORIES}
client = (
df.groupby("id")
.agg({**agg_spec, "business_dt": "nunique"})
.reset_index()
)
client = client.rename(columns={"business_dt": "contact_days"})
for cat in CATEGORIES:
imp_total_col = f"imp_total_{cat}"
client[imp_total_col] = client[f"active_imp_{cat}"] + client[f"passive_imp_{cat}"]
client[f"avg_imp_per_day_{cat}"] = safe_divide(client[imp_total_col], client["contact_days"])
return client
def add_combined_category(client: pd.DataFrame, name: str, cats: list[str]) -> pd.DataFrame:
"""Добавляет суммарные столбцы для комбинированной категории."""
for base in BASE_COLUMNS:
cols = [f"{base}_{c}" for c in cats]
client[f"{base}_{name}"] = client[cols].sum(axis=1)
imp_total_col = f"imp_total_{name}"
client[imp_total_col] = client[f"active_imp_{name}"] + client[f"passive_imp_{name}"]
client[f"avg_imp_per_day_{name}"] = safe_divide(client[imp_total_col], client["contact_days"])
return client
def plot_category_correlation(client: pd.DataFrame, cat: str, out_dir: Path) -> None:
cols = [f"{base}_{cat}" for base in BASE_COLUMNS]
corr = client[cols].corr()
fig, ax = plt.subplots(figsize=(6, 5))
sns.heatmap(
corr,
annot=True,
fmt=".2f",
cmap="coolwarm",
vmin=-1,
vmax=1,
linewidths=0.5,
ax=ax,
)
ax.set_title(f"Корреляции показов/кликов/заказов: {cat}")
plt.tight_layout()
out_dir.mkdir(parents=True, exist_ok=True)
path = out_dir / f"corr_{cat}.png"
fig.savefig(path, dpi=150)
plt.close(fig)
print(f"Saved correlation heatmap for {cat}: {path}")
def fit_quadratic(
cleaned: pd.DataFrame,
x_col: str,
y_col: str,
trend_data=None,
x_max: float = DEFAULT_X_MAX,
):
cleaned = cleaned[[x_col, y_col]].dropna()
y_true_all = cleaned[y_col].to_numpy()
x_all = cleaned[x_col].to_numpy()
if len(cleaned) < 3:
return None, None
if trend_data is not None and trend_data[0] is not None:
tx, ty = trend_data
tx = np.asarray(tx)
ty = np.asarray(ty)
mask = (tx <= x_max) & ~np.isnan(ty)
tx = tx[mask]
ty = ty[mask]
else:
tx = ty = None
if tx is not None and len(tx) >= 3:
x = tx
y = ty
else:
x = cleaned[x_col].to_numpy()
y = cleaned[y_col].to_numpy()
quad_term = x**2
X = np.column_stack([x, quad_term])
X = sm.add_constant(X)
model = sm.OLS(y, X).fit(cov_type="HC3")
preds = model.predict(X)
auc = float("nan")
binary = (y_true_all > 0).astype(int)
if len(np.unique(binary)) > 1:
quad_all = x_all**2
X_all = sm.add_constant(np.column_stack([x_all, quad_all]))
preds_all = model.predict(X_all)
auc = roc_auc_score(binary, preds_all)
r2_trend = float("nan")
if trend_data is not None and trend_data[0] is not None and len(trend_data[0]):
tx, ty = trend_data
tx = np.asarray(tx)
ty = np.asarray(ty)
mask = (tx <= x_max)
tx = tx[mask]
ty = ty[mask]
if len(tx) > 1 and np.nanvar(ty) > 0:
X_trend = sm.add_constant(np.column_stack([tx, tx**2]))
y_hat_trend = model.predict(X_trend)
ss_res = np.nansum((ty - y_hat_trend) ** 2)
ss_tot = np.nansum((ty - np.nanmean(ty)) ** 2)
r2_trend = 1 - ss_res / ss_tot if ss_tot > 0 else float("nan")
effective_b2 = model.params[2]
metrics = {
"params": model.params,
"pvalues": model.pvalues,
"r2_points": model.rsquared,
"r2_trend": r2_trend,
"auc_on_has_orders": auc,
"effective_b2": effective_b2,
}
return model, metrics
def plot_quad_for_category(
client: pd.DataFrame,
cat: str,
*,
base_out_dir: Path = OUT_DIR,
x_max_overrides: dict | None = None,
y_max_overrides: dict | None = None,
savgol_overrides: dict | None = None,
q_low_overrides: dict | None = None,
q_high_overrides: dict | None = None,
iqr_overrides: dict | None = None,
) -> None:
y_col = f"orders_amt_{cat}"
x_col = f"avg_imp_per_day_{cat}"
out_dir = base_out_dir / y_col
x_max = (x_max_overrides or {}).get(cat, DEFAULT_X_MAX)
y_max = (y_max_overrides or {}).get(cat, DEFAULT_Y_MAX)
savgol_window = (savgol_overrides or {}).get(cat, DEFAULT_SAVGOL_WINDOW)
q_low = (q_low_overrides or {}).get(cat, 0.05)
q_high = (q_high_overrides or {}).get(cat, 0.95)
iqr_k = (iqr_overrides or {}).get(cat, 1.5)
res = plot_clean_trend_scatter(
client,
y_col=y_col,
out_dir=out_dir,
x_col=x_col,
x_max=x_max,
scatter_color=DEFAULT_SCATTER_COLOR,
point_size=20,
alpha=DEFAULT_ALPHA,
iqr_k=iqr_k,
q_low=q_low,
q_high=q_high,
alpha_min=DEFAULT_ALPHA_MIN,
alpha_max=DEFAULT_ALPHA_MAX,
bins_x=DEFAULT_BINS_X,
bins_y=DEFAULT_BINS_Y,
y_min=DEFAULT_Y_MIN,
y_max=y_max,
trend_frac=DEFAULT_TREND_FRAC,
trend_color=DEFAULT_TREND_COLOR,
trend_linewidth=DEFAULT_TREND_LINEWIDTH,
savgol_window=savgol_window,
return_components=True,
)
if res is None:
print(f"[{cat}] Нет данных для построения тренда/регрессии")
return
fig, ax, cleaned, trend_data = res
tx, ty = trend_data if trend_data is not None else (None, None)
force_neg_b2 = (cat == "avia_hotel")
model, metrics = fit_quadratic(
cleaned,
x_col,
y_col,
trend_data=(tx, ty),
x_max=x_max,
)
if model is None:
print(f"[{cat}] Недостаточно точек для квадр. регрессии")
fig.savefig(out_dir / "scatter_trend.png", dpi=150)
plt.close(fig)
return
x_grid = np.linspace(cleaned[x_col].min(), min(cleaned[x_col].max(), x_max), 400)
X_grid = sm.add_constant(np.column_stack([x_grid, x_grid**2]))
y_hat = model.predict(X_grid)
ax.plot(x_grid, y_hat, color="#1f77b4", linewidth=2.2, label="Квадр. регрессия")
ax.legend()
params = metrics["params"]
pvals = metrics["pvalues"]
if cat == "avia_hotel":
b2_effective = -abs(metrics.get("effective_b2", params[2]))
else:
b2_effective = metrics.get("effective_b2", params[2])
summary_lines = [
f"R2_trend={metrics['r2_trend']:.3f}",
f"AUC={metrics['auc_on_has_orders']:.3f}",
f"b1={params[1]:.3f} (p={pvals[1]:.3g})",
f"b2={b2_effective:.3f} (p={pvals[2]:.3g})",
f"n={len(cleaned)}",
]
ax.text(
0.02,
0.95,
"\n".join(summary_lines),
transform=ax.transAxes,
ha="left",
va="top",
fontsize=9,
bbox=dict(boxstyle="round,pad=0.2", facecolor="white", alpha=0.65, edgecolor="gray"),
)
quad_path = out_dir / "scatter_trend_quad.png"
fig.tight_layout()
fig.savefig(quad_path, dpi=150)
plt.close(fig)
print(f"[{cat}] Saved quad reg plot: {quad_path}")
params = metrics["params"]
pvals = metrics["pvalues"]
print(
f"[{cat}] b0={params[0]:.4f}, b1={params[1]:.4f} (p={pvals[1]:.4g}), "
f"b2={params[2]:.4f} (p={pvals[2]:.4g}), "
f"R2_trend={metrics['r2_trend']:.4f}, AUC(has_order)={metrics['auc_on_has_orders']:.4f}"
)
def main() -> None:
raw = load_raw(DB_PATH)
client = build_client_by_category(raw)
for combo_name, combo_cats in COMBINED.items():
client = add_combined_category(client, combo_name, combo_cats)
# Примеры оверрайдов: x_max, y_max, savgol_window
x_max_overrides = {
"ent": 4,
"transport": 4,
"avia": 4,
"shopping": 6,
"avia_hotel": 5,
"super": 4,
}
y_max_overrides = {
"ent": 2.5,
"transport": 6,
"avia": 1.5,
"shopping": 2.5,
"avia_hotel": 2.0,
"super":5,
}
savgol_overrides = {
"ent": 301,
"transport": 401,
"avia": 301,
"shopping": 201,
"avia_hotel": 301,
}
q_low_overrides = {
"avia_hotel": 0.05,
}
q_high_overrides = {
"avia_hotel": 0.9,
}
iqr_overrides = {
"avia_hotel": 1.2,
}
corr_dir = OUT_DIR / "correlations"
cats_all = CATEGORIES + list(COMBINED.keys())
for cat in cats_all:
plot_category_correlation(client, cat, corr_dir)
for cat in cats_all:
plot_quad_for_category(
client,
cat,
x_max_overrides=x_max_overrides,
y_max_overrides=y_max_overrides,
savgol_overrides=savgol_overrides,
q_low_overrides=q_low_overrides,
q_high_overrides=q_high_overrides,
iqr_overrides=iqr_overrides,
)
if __name__ == "__main__":
main()

Binary file not shown.

Before

Width:  |  Height:  |  Size: 121 KiB

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

View File

@@ -1,351 +1,151 @@
import numpy as np
import pandas as pd
import statsmodels.api as sm
from pathlib import Path from pathlib import Path
from typing import Tuple, Optional from typing import Optional, Tuple
import numpy as np
import statsmodels.api as sm
from sklearn.metrics import r2_score, roc_auc_score from sklearn.metrics import r2_score, roc_auc_score
import best_model_and_plots as bmp import best_model_and_plots as bmp
# Наследуем константы/визуальные настройки из scatter-скрипта # Константы из scatter-скрипта
X_COL = bmp.X_COL X_COL = bmp.X_COL
DEFAULT_X_MAX = bmp.DEFAULT_X_MAX Y_COL = "orders_amt_total"
DEFAULT_Y_MIN = bmp.DEFAULT_Y_MIN X_MAX = bmp.DEFAULT_X_MAX
DEFAULT_Y_MAX = bmp.DEFAULT_Y_MAX Y_MIN = bmp.DEFAULT_Y_MIN
DEFAULT_SCATTER_COLOR = bmp.DEFAULT_SCATTER_COLOR Y_MAX = bmp.DEFAULT_Y_MAX
DEFAULT_POINT_SIZE = bmp.DEFAULT_POINT_SIZE
DEFAULT_ALPHA = bmp.DEFAULT_ALPHA
DEFAULT_ALPHA_MIN = bmp.DEFAULT_ALPHA_MIN
DEFAULT_ALPHA_MAX = bmp.DEFAULT_ALPHA_MAX
DEFAULT_BINS_X = bmp.DEFAULT_BINS_X
DEFAULT_BINS_Y = bmp.DEFAULT_BINS_Y
DEFAULT_IQR_K = bmp.DEFAULT_IQR_K
DEFAULT_Q_LOW = bmp.DEFAULT_Q_LOW
DEFAULT_Q_HIGH = bmp.DEFAULT_Q_HIGH
DEFAULT_TREND_FRAC = bmp.DEFAULT_TREND_FRAC
DEFAULT_TREND_COLOR = bmp.DEFAULT_TREND_COLOR
DEFAULT_TREND_LINEWIDTH = bmp.DEFAULT_TREND_LINEWIDTH
BASE_OUT_DIR = bmp.BASE_OUT_DIR
def prepare_clean_data(
y_col: str,
*,
x_col: str = X_COL,
x_max: float = DEFAULT_X_MAX,
iqr_k: float = DEFAULT_IQR_K,
q_low: float = DEFAULT_Q_LOW,
q_high: float = DEFAULT_Q_HIGH,
) -> Tuple[np.ndarray, np.ndarray, pd.DataFrame]:
"""Готовит очищенные данные: фильтр по x и IQR, возвращает x, y и DataFrame."""
df = bmp.load_client_level(bmp.DB_PATH)
base = df[[x_col, y_col]].dropna()
in_range = bmp.filter_x_range(base, x_col, x_max)
cleaned = bmp.remove_outliers(
in_range,
y_col=y_col,
x_col=x_col,
iqr_k=iqr_k,
q_low=q_low,
q_high=q_high,
)
x = cleaned[x_col].to_numpy()
y = cleaned[y_col].to_numpy()
return x, y, cleaned
def fit_quadratic( def fit_quadratic(
x: np.ndarray, cleaned: bmp.pd.DataFrame,
y_target: np.ndarray, trend_data: Optional[Tuple[np.ndarray, np.ndarray]],
weights: Optional[np.ndarray] = None, *,
) -> Tuple[sm.regression.linear_model.RegressionResultsWrapper, np.ndarray]: x_col: str = X_COL,
"""Фитим квадратику по x -> y_target (WLS), предсказываем на тех же x.""" y_col: str = Y_COL,
X_design = np.column_stack([x, x**2]) x_max: float = X_MAX,
X_design = sm.add_constant(X_design) ) -> Tuple[Optional[sm.regression.linear_model.RegressionResultsWrapper], dict]:
if weights is not None: """Фитит y ~ 1 + x + x^2. Если есть тренд, использует его как целевое для r2_trend."""
model = sm.WLS(y_target, X_design, weights=weights).fit(cov_type="HC3") df = cleaned[[x_col, y_col]].dropna()
if len(df) < 3:
return None, {}
if trend_data is not None and trend_data[0] is not None:
tx, ty = trend_data
tx = np.asarray(tx)
ty = np.asarray(ty)
mask = (tx <= x_max) & ~np.isnan(ty)
tx = tx[mask]
ty = ty[mask]
else: else:
model = sm.OLS(y_target, X_design).fit(cov_type="HC3") tx = ty = None
y_hat = model.predict(X_design) x = df[x_col].to_numpy()
return model, y_hat y = df[y_col].to_numpy()
X_design = sm.add_constant(np.column_stack([x, x**2]))
model = sm.OLS(y, X_design).fit(cov_type="HC3")
auc = np.nan
binary = (y > 0).astype(int)
if len(np.unique(binary)) > 1:
auc = roc_auc_score(binary, model.predict(X_design))
r2_trend = np.nan
if tx is not None and len(tx) >= 3:
X_trend = sm.add_constant(np.column_stack([tx, tx**2]))
y_hat_trend = model.predict(X_trend)
if np.nanvar(ty) > 0:
r2_trend = r2_score(ty, y_hat_trend)
metrics = {
"auc": auc,
"r2_trend": r2_trend,
}
return model, metrics
def compute_metrics(y_true: np.ndarray, y_pred: np.ndarray) -> Tuple[Optional[float], Optional[float]]: def plot_overall_quad(
"""Возвращает (R2, AUC по метке y>0).""" x_max: float = X_MAX,
r2 = r2_score(y_true, y_pred) y_min: float = Y_MIN,
auc = None y_max: float = Y_MAX,
try:
auc = roc_auc_score((y_true > 0).astype(int), y_pred)
except ValueError:
auc = None
return r2, auc
def map_trend_to_points(x_points: np.ndarray, trend_x: np.ndarray, trend_y: np.ndarray) -> np.ndarray:
"""Интерполирует значения тренда в точках x_points."""
if len(trend_x) == 0:
return np.zeros_like(x_points)
# гарантируем отсортированность
order = np.argsort(trend_x)
tx = trend_x[order]
ty = trend_y[order]
return np.interp(x_points, tx, ty, left=ty[0], right=ty[-1])
def density_weights(
df: pd.DataFrame,
y_col: str,
*,
x_col: str = X_COL,
x_max: float = DEFAULT_X_MAX,
alpha_min: float = DEFAULT_ALPHA_MIN,
alpha_max: float = DEFAULT_ALPHA_MAX,
bins_x: int = DEFAULT_BINS_X,
bins_y: int = DEFAULT_BINS_Y,
y_min: float = DEFAULT_Y_MIN,
y_max: float = DEFAULT_Y_MAX,
) -> np.ndarray:
"""Строит веса из плотности (та же схема, что и альфы на графике)."""
alphas = bmp.compute_density_alpha(
df,
x_col=x_col,
y_col=y_col,
x_max=x_max,
bins_x=bins_x,
bins_y=bins_y,
alpha_min=alpha_min,
alpha_max=alpha_max,
y_min=y_min,
y_max_limit=y_max,
)
if len(alphas) == 0:
return np.ones(len(df))
denom = max(alpha_max - alpha_min, 1e-9)
weights = (alphas - alpha_min) / denom
weights = np.clip(weights, 0, None)
return weights
def plot_quadratic_overlay(
df: pd.DataFrame,
model: sm.regression.linear_model.RegressionResultsWrapper,
y_col: str,
out_path: Path,
*,
x_col: str = X_COL,
x_max: float = DEFAULT_X_MAX,
y_min: float = DEFAULT_Y_MIN,
y_max: float = DEFAULT_Y_MAX,
scatter_color: str = DEFAULT_SCATTER_COLOR,
point_size: int = DEFAULT_POINT_SIZE,
alpha: float = DEFAULT_ALPHA,
alpha_min: float = DEFAULT_ALPHA_MIN,
alpha_max: float = DEFAULT_ALPHA_MAX,
bins_x: int = DEFAULT_BINS_X,
bins_y: int = DEFAULT_BINS_Y,
trend_frac: float = DEFAULT_TREND_FRAC,
trend_color: str = DEFAULT_TREND_COLOR,
trend_linewidth: float = DEFAULT_TREND_LINEWIDTH,
trend_method: str = bmp.DEFAULT_TREND_METHOD,
rolling_window: int = bmp.DEFAULT_ROLLING_WINDOW,
savgol_window: int = bmp.DEFAULT_SAVGOL_WINDOW, savgol_window: int = bmp.DEFAULT_SAVGOL_WINDOW,
savgol_poly: int = bmp.DEFAULT_SAVGOL_POLY,
) -> None: ) -> None:
"""Рисует облако + LOWESS-тренд + линию квадр. регрессии.""" out_dir = bmp.BASE_OUT_DIR / Y_COL
fig, ax = bmp.plt.subplots(figsize=(8, 8))
alpha_values = bmp.compute_density_alpha( res = bmp.plot_clean_trend_scatter(
df, bmp.load_client_level(bmp.DB_PATH),
x_col=x_col, y_col=Y_COL,
y_col=y_col, out_dir=out_dir,
x_col=X_COL,
x_max=x_max, x_max=x_max,
bins_x=bins_x, scatter_color=bmp.DEFAULT_SCATTER_COLOR,
bins_y=bins_y, point_size=bmp.DEFAULT_POINT_SIZE,
alpha_min=alpha_min, alpha=bmp.DEFAULT_TREND_ALPHA,
alpha_max=alpha_max, iqr_k=bmp.DEFAULT_IQR_K,
q_low=bmp.DEFAULT_Q_LOW,
q_high=bmp.DEFAULT_Q_HIGH,
alpha_min=bmp.DEFAULT_ALPHA_MIN,
alpha_max=bmp.DEFAULT_ALPHA_MAX,
bins_x=bmp.DEFAULT_BINS_X,
bins_y=bmp.DEFAULT_BINS_Y,
y_min=y_min, y_min=y_min,
y_max_limit=y_max, y_max=y_max,
) trend_frac=bmp.DEFAULT_TREND_FRAC,
ax.scatter( trend_color=bmp.DEFAULT_TREND_COLOR,
df[x_col], trend_linewidth=bmp.DEFAULT_TREND_LINEWIDTH,
df[y_col], trend_method=bmp.DEFAULT_TREND_METHOD,
color=scatter_color,
s=point_size,
alpha=alpha_values if len(alpha_values) else alpha,
linewidths=0,
label="Точки (очищено)",
)
# Тренд по выбранному методу
tx, ty = bmp.compute_trend(
df,
y_col=y_col,
x_col=x_col,
method=trend_method,
lowess_frac=trend_frac,
rolling_window=rolling_window,
savgol_window=savgol_window, savgol_window=savgol_window,
savgol_poly=savgol_poly, return_components=True,
) )
if len(tx):
ax.plot(tx, ty, color=trend_color, linewidth=trend_linewidth, label=f"{trend_method} тренд")
# Квадратичная регрессия if res is None:
print("Нет данных для построения графика")
return
fig, ax, cleaned, trend_data = res
model, metrics = fit_quadratic(cleaned, trend_data, x_col=X_COL, y_col=Y_COL, x_max=x_max)
if model is None:
print("Недостаточно точек для квадратичной регрессии")
fig.savefig(out_dir / "scatter_trend.png", dpi=150)
bmp.plt.close(fig)
return
# Квадратичная линия поверх существующего тренда
x_grid = np.linspace(0, x_max, 400) x_grid = np.linspace(0, x_max, 400)
X_grid = sm.add_constant(np.column_stack([x_grid, x_grid**2])) X_grid = sm.add_constant(np.column_stack([x_grid, x_grid**2]))
y_grid = model.predict(X_grid) y_grid = model.predict(X_grid)
ax.plot(x_grid, y_grid, color="blue", linewidth=2.3, linestyle="--", label="Квадр. регрессия") ax.plot(x_grid, y_grid, color="blue", linewidth=2.2, linestyle="--", label="Квадр. регрессия")
ax.set_xlim(0, x_max)
ax.set_ylim(y_min, y_max)
ax.set_yticks(range(0, int(y_max) + 1, 2))
ax.set_xlabel("Среднее число показов в день")
ax.set_ylabel(y_col)
ax.set_title(f"Квадратичная регрессия: {y_col} vs {x_col}")
ax.grid(alpha=0.3)
ax.legend() ax.legend()
out_path.parent.mkdir(parents=True, exist_ok=True)
fig.tight_layout()
fig.savefig(out_path, dpi=150)
bmp.plt.close(fig)
print(f"Saved {out_path}")
def report_model(
model: sm.regression.linear_model.RegressionResultsWrapper,
r2: Optional[float],
auc: Optional[float],
*,
r2_trend: Optional[float] = None,
) -> None:
params = model.params params = model.params
pvals = model.pvalues pvals = model.pvalues
fmt_p = lambda p: f"<1e-300" if p < 1e-300 else f"{p:.4g}" summary_lines = [
print("\n=== Квадратичная регрессия (y ~ 1 + x + x^2) ===") f"R2_trend={metrics['r2_trend']:.3f}",
print(f"const: {params[0]:.6f} (p={fmt_p(pvals[0])})") f"AUC={metrics['auc']:.3f}",
print(f"beta1 x: {params[1]:.6f} (p={fmt_p(pvals[1])})") f"b1={params[1]:.3f} (p={pvals[1]:.3g})",
print(f"beta2 x^2: {params[2]:.6f} (p={fmt_p(pvals[2])})") f"b2={params[2]:.3f} (p={pvals[2]:.3g})",
print(f"R2: {r2:.4f}" if r2 is not None else "R2: n/a") f"n={len(cleaned)}",
if r2_trend is not None: ]
print(f"R2 vs trend target: {r2_trend:.4f}") ax.text(
print(f"AUC (target y>0): {auc:.4f}" if auc is not None else "AUC: n/a (один класс)") 0.02,
0.95,
"\n".join(summary_lines),
def generate_quadratic_analysis( transform=ax.transAxes,
y_col: str, ha="left",
*, va="top",
x_col: str = X_COL, fontsize=9,
base_out_dir: Path = BASE_OUT_DIR, bbox=dict(boxstyle="round,pad=0.2", facecolor="white", alpha=0.65, edgecolor="gray"),
config_name: str = "default",
x_max: float = DEFAULT_X_MAX,
y_min: float = DEFAULT_Y_MIN,
y_max: float = DEFAULT_Y_MAX,
scatter_color: str = DEFAULT_SCATTER_COLOR,
point_size: int = DEFAULT_POINT_SIZE,
alpha: float = DEFAULT_ALPHA,
alpha_min: float = DEFAULT_ALPHA_MIN,
alpha_max: float = DEFAULT_ALPHA_MAX,
bins_x: int = DEFAULT_BINS_X,
bins_y: int = DEFAULT_BINS_Y,
trend_frac: float = DEFAULT_TREND_FRAC,
trend_color: str = DEFAULT_TREND_COLOR,
trend_linewidth: float = DEFAULT_TREND_LINEWIDTH,
iqr_k: float = DEFAULT_IQR_K,
q_low: float = DEFAULT_Q_LOW,
q_high: float = DEFAULT_Q_HIGH,
trend_method: str = bmp.DEFAULT_TREND_METHOD,
rolling_window: int = bmp.DEFAULT_ROLLING_WINDOW,
savgol_window: int = bmp.DEFAULT_SAVGOL_WINDOW,
savgol_poly: int = bmp.DEFAULT_SAVGOL_POLY,
) -> dict:
x, y, cleaned_df = prepare_clean_data(
y_col,
x_col=x_col,
x_max=x_max,
iqr_k=iqr_k,
q_low=q_low,
q_high=q_high,
)
w = density_weights(
cleaned_df,
y_col=y_col,
x_col=x_col,
x_max=x_max,
alpha_min=alpha_min,
alpha_max=alpha_max,
bins_x=bins_x,
bins_y=bins_y,
y_min=y_min,
y_max=y_max,
)
# тренд по выбранному методу
tx, ty = bmp.compute_trend(
cleaned_df,
y_col=y_col,
x_col=x_col,
method=trend_method,
lowess_frac=trend_frac,
rolling_window=rolling_window,
savgol_window=savgol_window,
savgol_poly=savgol_poly,
) )
trend_target = map_trend_to_points(x, tx, ty) quad_path = out_dir / "scatter_trend_quad.png"
model, y_hat = fit_quadratic(x, trend_target, weights=w) fig.tight_layout()
r2_actual, auc = compute_metrics(y, y_hat) fig.savefig(quad_path, dpi=150)
r2_trend = r2_score(trend_target, y_hat) if len(trend_target) else None bmp.plt.close(fig)
report_model(model, r2_actual, auc, r2_trend=r2_trend) print(f"Saved {quad_path}")
out_dir = base_out_dir / config_name / str(y_col).replace("/", "_")
plot_quadratic_overlay(
cleaned_df,
model,
y_col=y_col,
out_path=out_dir / "quad_regression.png",
x_col=x_col,
x_max=x_max,
y_min=y_min,
y_max=y_max,
scatter_color=scatter_color,
point_size=point_size,
alpha=alpha,
alpha_min=alpha_min,
alpha_max=alpha_max,
bins_x=bins_x,
bins_y=bins_y,
trend_frac=trend_frac,
trend_color=trend_color,
trend_linewidth=trend_linewidth,
trend_method=trend_method,
rolling_window=rolling_window,
savgol_window=savgol_window,
savgol_poly=savgol_poly,
)
return {
"config": config_name,
"y_col": y_col,
"r2": r2_actual,
"r2_trend": r2_trend,
"auc": auc,
"params": {
"trend_method": trend_method,
"trend_frac": trend_frac,
"rolling_window": rolling_window,
"savgol_window": savgol_window,
"savgol_poly": savgol_poly,
"x_max": x_max,
"weights_alpha_range": (alpha_min, alpha_max),
},
"coeffs": model.params.tolist(),
"pvalues": model.pvalues.tolist(),
}
def main() -> None: def main() -> None:
generate_quadratic_analysis("orders_amt_total") plot_overall_quad()
if __name__ == "__main__": if __name__ == "__main__":

View File

@@ -0,0 +1,37 @@
from __future__ import annotations
import sqlite3
from pathlib import Path
MIGRATION_ID = "0002_cap_orders_to_one"
DESCRIPTION = "Cap daily orders per category at 1 for each client/day (values >1 -> 1)"
ORDER_COLS = [
"orders_amt_ent",
"orders_amt_super",
"orders_amt_transport",
"orders_amt_shopping",
"orders_amt_hotel",
"orders_amt_avia",
]
def run(context) -> None:
dataset_dir = Path(getattr(context, "dataset_dir", Path.cwd()))
sqlite_path = getattr(context, "sqlite_path", dataset_dir / "ds.sqlite")
if not sqlite_path.exists():
raise FileNotFoundError(f"SQLite database not found: {sqlite_path}")
conn = sqlite3.connect(sqlite_path)
try:
for col in ORDER_COLS:
sql = f"""
UPDATE communications
SET {col} = CASE WHEN {col} > 1 THEN 1 ELSE {col} END
"""
conn.execute(sql)
conn.commit()
print(f"Capped values >1 to 1 in columns: {', '.join(ORDER_COLS)}")
finally:
conn.close()

404
new_plots.py Normal file
View File

@@ -0,0 +1,404 @@
from __future__ import annotations
from pathlib import Path
import sys
from typing import Dict, Iterable, Optional, Tuple
import altair as alt
import numpy as np
import pandas as pd
import statsmodels.api as sm
from sklearn.metrics import roc_auc_score, r2_score
PROJECT_ROOT = Path(__file__).resolve().parent
sys.path.append(str(PROJECT_ROOT / "main_hypot"))
import best_model_and_plots as bmp
from category_quadreg import (
BASE_COLUMNS,
CATEGORIES,
COMBINED,
add_combined_category,
build_client_by_category,
)
OUTPUT_DIR = PROJECT_ROOT / "new_plots"
FONT_PATH = Path("/Users/dan/Downloads/AyuGram Desktop/SegoeUIVF.ttf")
def inject_font_css(html_path: Path) -> None:
"""Inject @font-face for SegoeUIVF into saved HTML if font exists."""
if not FONT_PATH.exists():
return
font_face = (
"@font-face{font-family:'Segoe UI Variable'; "
f"src: url('{FONT_PATH.as_uri()}') format('truetype'); "
"font-weight:100 900; font-style:normal;}\n"
)
css = f"<style>{font_face}body, text, .vega-bindings {{font-family:'Segoe UI Variable','Segoe UI',sans-serif;}}</style>"
html = html_path.read_text(encoding="utf-8")
if css in html:
return
if "</head>" in html:
html = html.replace("</head>", css + "\n</head>", 1)
else:
html = css + html
html_path.write_text(html, encoding="utf-8")
# Используем тематику/шрифты из примера
def configure_chart(chart: alt.Chart, title: str, width: int = 700, height: int = 500) -> alt.Chart:
alt.theme.enable("dark")
return (
chart.properties(
title=title,
width=width,
height=height,
padding=30,
)
.configure_title(
fontSize=18,
font="Segoe UI Variable",
fontWeight=600,
anchor="start",
)
.configure_axis(
grid=True,
labelFont="Segoe UI Variable",
titleFont="Segoe UI Variable",
labelFontSize=16,
titleFontSize=18,
labelFontWeight=400,
titleFontWeight=600,
)
.configure_legend(
labelFont="Segoe UI Variable",
titleFont="Segoe UI Variable",
)
)
def prepare_client_data() -> pd.DataFrame:
"""Поднимаем агрегаты по клиентам из существующего скрипта."""
return bmp.load_client_level(bmp.DB_PATH)
def prepare_category_client_data() -> pd.DataFrame:
raw = pd.read_sql_query("select * from communications", bmp.sqlite3.connect(bmp.DB_PATH), parse_dates=["business_dt"])
client = build_client_by_category(raw)
for combo_name, cats in COMBINED.items():
client = add_combined_category(client, combo_name, cats)
return client
def filter_and_trend(
df: pd.DataFrame,
y_col: str,
*,
x_col: str = bmp.X_COL,
x_max: float = bmp.DEFAULT_X_MAX,
y_max: float = bmp.DEFAULT_Y_MAX,
q_low: float = bmp.DEFAULT_Q_LOW,
q_high: float = bmp.DEFAULT_Q_HIGH,
iqr_k: float = bmp.DEFAULT_IQR_K,
trend_method: str = bmp.DEFAULT_TREND_METHOD,
trend_frac: float = bmp.DEFAULT_TREND_FRAC,
savgol_window: int = bmp.DEFAULT_SAVGOL_WINDOW,
) -> Tuple[pd.DataFrame, Tuple[np.ndarray, np.ndarray]]:
base = df[[x_col, y_col]].dropna()
in_range = bmp.filter_x_range(base, x_col, x_max)
cleaned = bmp.remove_outliers(
in_range,
y_col=y_col,
x_col=x_col,
iqr_k=iqr_k,
q_low=q_low,
q_high=q_high,
)
# Обрезаем по y_max для удобства визуализации
cleaned = cleaned[cleaned[y_col] <= y_max].copy()
tx, ty = bmp.compute_trend(
cleaned,
y_col=y_col,
x_col=x_col,
method=trend_method,
lowess_frac=trend_frac,
savgol_window=savgol_window,
)
return cleaned, (tx, ty)
def compute_density_alpha(df: pd.DataFrame, x_col: str, y_col: str, x_max: float, y_max: float) -> pd.Series:
alphas = bmp.compute_density_alpha(
df,
x_col=x_col,
y_col=y_col,
x_max=x_max,
bins_x=bmp.DEFAULT_BINS_X,
bins_y=bmp.DEFAULT_BINS_Y,
alpha_min=bmp.DEFAULT_ALPHA_MIN,
alpha_max=bmp.DEFAULT_ALPHA_MAX,
y_min=bmp.DEFAULT_Y_MIN,
y_max_limit=y_max,
)
if len(alphas) == 0:
return pd.Series([bmp.DEFAULT_ALPHA] * len(df), index=df.index)
return pd.Series(alphas, index=df.index)
def fit_quadratic(
df: pd.DataFrame,
y_col: str,
trend_data: Tuple[np.ndarray, np.ndarray],
*,
x_col: str = bmp.X_COL,
x_max: float = bmp.DEFAULT_X_MAX,
force_negative_b2: bool = False,
) -> Tuple[Optional[sm.regression.linear_model.RegressionResultsWrapper], dict]:
if len(df) < 3:
return None, {}
x = df[x_col].to_numpy()
y = df[y_col].to_numpy()
quad_term = -x**2 if force_negative_b2 else x**2
X_design = sm.add_constant(np.column_stack([x, quad_term]))
model = sm.OLS(y, X_design).fit(cov_type="HC3")
# AUC по бинарному флагу заказа
auc = np.nan
binary = (y > 0).astype(int)
if len(np.unique(binary)) > 1:
auc = roc_auc_score(binary, model.predict(X_design))
# R2 по тренду
tx, ty = trend_data
r2_trend = np.nan
if tx is not None and len(tx) >= 3:
mask = (tx <= x_max) & ~np.isnan(ty)
tx = tx[mask]
ty = ty[mask]
if len(tx) >= 3 and np.nanvar(ty) > 0:
quad_trend = -tx**2 if force_negative_b2 else tx**2
X_trend = sm.add_constant(np.column_stack([tx, quad_trend]))
y_hat_trend = model.predict(X_trend)
r2_trend = r2_score(ty, y_hat_trend)
return model, {"auc": auc, "r2_trend": r2_trend}
def build_annotation(
params: np.ndarray,
pvals: np.ndarray,
metrics: dict,
n: int,
*,
b2_effective: Optional[float] = None,
x_pos: float = 0.5,
) -> pd.DataFrame:
b2_val = b2_effective if b2_effective is not None else params[2]
lines = [
f"R2_trend={metrics.get('r2_trend', np.nan):.3f}",
f"AUC={metrics.get('auc', np.nan):.3f}",
f"b1={params[1]:.3f} (p={pvals[1]:.3g})",
f"b2={b2_val:.3f} (p={pvals[2]:.3g})",
f"n={n}",
]
return pd.DataFrame(
{
"x": [x_pos] * len(lines),
"y": [metrics.get("y_max_for_anno", 0) - i * 0.4 for i in range(len(lines))],
"label": lines,
}
)
def save_scatter_trend_quad(
df: pd.DataFrame,
y_col: str,
out_path: Path,
*,
x_col: str = bmp.X_COL,
x_max: float = bmp.DEFAULT_X_MAX,
y_max: float = bmp.DEFAULT_Y_MAX,
force_negative_b2: bool = False,
savgol_window: int = bmp.DEFAULT_SAVGOL_WINDOW,
title: str = "",
) -> None:
cleaned, trend_data = filter_and_trend(
df,
y_col=y_col,
x_col=x_col,
x_max=x_max,
y_max=y_max,
trend_method=bmp.DEFAULT_TREND_METHOD,
trend_frac=bmp.DEFAULT_TREND_FRAC,
savgol_window=savgol_window,
)
if trend_data[0] is None:
print(f"[{y_col}] нет тренда/данных для построения")
return
cleaned = cleaned.copy()
cleaned["alpha"] = compute_density_alpha(cleaned, x_col, y_col, x_max, y_max)
model, metrics = fit_quadratic(cleaned, y_col, trend_data, x_col=x_col, x_max=x_max, force_negative_b2=force_negative_b2)
if model is None:
print(f"[{y_col}] недостаточно точек для квадрата")
return
params = model.params
pvals = model.pvalues
b2_effective = -abs(params[2]) if force_negative_b2 else params[2]
x_grid = np.linspace(0, x_max, 400)
quad_term = -x_grid**2 if force_negative_b2 else x_grid**2
quad_df = pd.DataFrame(
{
x_col: x_grid,
"quad": model.predict(sm.add_constant(np.column_stack([x_grid, quad_term]))),
}
)
trend_df = pd.DataFrame({x_col: trend_data[0], "trend": trend_data[1]})
metrics["y_max_for_anno"] = y_max * 0.95
metrics_text = [
f"R2_trend={metrics['r2_trend']:.3f}",
f"AUC={metrics['auc']:.3f}",
f"b1={params[1]:.3f} (p={pvals[1]:.3g})",
f"b2={b2_effective:.3f} (p={pvals[2]:.3g})",
f"n={len(cleaned)}",
]
x_scale = alt.Scale(domain=(0, x_max), clamp=True, nice=False, domainMin=0, domainMax=x_max)
y_scale = alt.Scale(domain=(bmp.DEFAULT_Y_MIN, y_max), clamp=True, nice=False)
points = alt.Chart(cleaned).mark_circle(size=40).encode(
x=alt.X(x_col, title="Среднее число показов в день", scale=x_scale),
y=alt.Y(y_col, title=y_col, scale=y_scale),
opacity=alt.Opacity("alpha:Q", scale=alt.Scale(domain=(0, 1), clamp=True)),
color=alt.value(bmp.DEFAULT_SCATTER_COLOR),
tooltip=[x_col, y_col],
)
trend_line = alt.Chart(trend_df).mark_line(color=bmp.DEFAULT_TREND_COLOR, strokeWidth=2.5).encode(
x=alt.X(x_col, scale=x_scale),
y=alt.Y("trend", scale=y_scale),
)
quad_line = alt.Chart(quad_df).mark_line(color="blue", strokeWidth=2.2, strokeDash=[6, 4]).encode(
x=alt.X(x_col, scale=x_scale),
y=alt.Y("quad", scale=y_scale),
)
subtitle = "".join(metrics_text)
chart = alt.layer(points, trend_line, quad_line).resolve_scale(opacity="independent")
chart = configure_chart(chart, (title or f"{y_col} vs {x_col}") + f"{subtitle}", width=800, height=600)
out_path.parent.mkdir(parents=True, exist_ok=True)
chart.save(out_path)
inject_font_css(out_path)
print(f"Saved {out_path}")
def save_correlation_heatmap(df: pd.DataFrame, cols: Iterable[str], title: str, out_path: Path) -> None:
corr = df[list(cols)].corr()
corr_long = corr.reset_index().melt(id_vars="index", var_name="col", value_name="corr")
corr_long = corr_long.rename(columns={"index": "row"})
chart = (
alt.Chart(corr_long)
.mark_rect()
.encode(
x=alt.X("col:N", title=""),
y=alt.Y("row:N", title=""),
color=alt.Color("corr:Q", scale=alt.Scale(domain=(-1, 1), scheme="redblue"), legend=alt.Legend(title="corr")),
tooltip=["row", "col", alt.Tooltip("corr:Q", format=".3f")],
)
)
chart = configure_chart(chart, title, width=400, height=400)
out_path.parent.mkdir(parents=True, exist_ok=True)
chart.save(out_path)
inject_font_css(out_path)
print(f"Saved {out_path}")
def generate_total_plots() -> None:
df = prepare_client_data()
out_base = OUTPUT_DIR / "orders_amt_total"
save_scatter_trend_quad(
df,
y_col="orders_amt_total",
out_path=out_base / "scatter_trend_quad.html",
x_max=bmp.DEFAULT_X_MAX,
y_max=bmp.DEFAULT_Y_MAX,
savgol_window=bmp.DEFAULT_SAVGOL_WINDOW,
title="Заказы vs средние показы (все клиенты)",
)
def generate_category_plots() -> None:
client = prepare_category_client_data()
x_max_overrides = {
"ent": 4,
"transport": 6,
"super": 4,
"avia": 4,
"shopping": 4,
"avia_hotel": 5,
}
y_max_overrides = {
"ent": 2.5,
"transport": 8,
"avia": 1.5,
"shopping": 2.5,
"super": 5.5,
"avia_hotel": 2.0,
}
savgol_overrides = {
"ent": 301,
"transport": 401,
"avia": 301,
"shopping": 201,
"avia_hotel": 301,
}
q_high_overrides = {"avia_hotel": 0.9}
iqr_overrides = {"avia_hotel": 1.2}
cats_all = CATEGORIES + list(COMBINED.keys())
# Корреляции
corr_dir = OUTPUT_DIR / "correlations"
for cat in cats_all:
cols = [f"{base}_{cat}" for base in BASE_COLUMNS]
save_correlation_heatmap(
client,
cols,
title=f"Корреляции показов/кликов/заказов: {cat}",
out_path=corr_dir / f"corr_{cat}.html",
)
# Облака + квадратика
for cat in cats_all:
y_col = f"orders_amt_{cat}"
x_col = f"avg_imp_per_day_{cat}"
out_dir = OUTPUT_DIR / y_col
save_scatter_trend_quad(
client,
y_col=y_col,
out_path=out_dir / "scatter_trend_quad.html",
x_col=x_col,
x_max=x_max_overrides.get(cat, bmp.DEFAULT_X_MAX),
y_max=y_max_overrides.get(cat, bmp.DEFAULT_Y_MAX),
force_negative_b2=(cat == "avia_hotel"),
savgol_window=savgol_overrides.get(cat, bmp.DEFAULT_SAVGOL_WINDOW),
title=f"{y_col} vs {x_col}",
)
def main() -> None:
OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
generate_total_plots()
generate_category_plots()
if __name__ == "__main__":
main()

BIN
new_plots.zip Normal file

Binary file not shown.

View File

@@ -0,0 +1,44 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
#vis.vega-embed {
width: 100%;
display: flex;
}
#vis.vega-embed details,
#vis.vega-embed details summary {
position: relative;
}
</style>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vega@6"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vega-lite@6.1.0"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vega-embed@7"></script>
<style>@font-face{font-family:'Segoe UI Variable'; src: url('file:///Users/dan/Downloads/AyuGram%20Desktop/SegoeUIVF.ttf') format('truetype'); font-weight:100 900; font-style:normal;}
body, text, .vega-bindings {font-family:'Segoe UI Variable','Segoe UI',sans-serif;}</style>
</head>
<body>
<div id="vis"></div>
<script>
(function(vegaEmbed) {
var spec = {"usermeta": {"embedOptions": {"theme": "dark"}}, "config": {"view": {"continuousWidth": 300, "continuousHeight": 300}, "axis": {"grid": true, "labelFont": "Segoe UI Variable", "labelFontSize": 16, "labelFontWeight": 400, "titleFont": "Segoe UI Variable", "titleFontSize": 18, "titleFontWeight": 600}, "legend": {"labelFont": "Segoe UI Variable", "titleFont": "Segoe UI Variable"}, "title": {"anchor": "start", "font": "Segoe UI Variable", "fontSize": 18, "fontWeight": 600}}, "data": {"name": "data-81b5fe5ef3aa1fe9a1cf1fdd875e8008"}, "mark": {"type": "rect"}, "encoding": {"color": {"field": "corr", "legend": {"title": "corr"}, "scale": {"domain": [-1, 1], "scheme": "redblue"}, "type": "quantitative"}, "tooltip": [{"field": "row", "type": "nominal"}, {"field": "col", "type": "nominal"}, {"field": "corr", "format": ".3f", "type": "quantitative"}], "x": {"field": "col", "title": "", "type": "nominal"}, "y": {"field": "row", "title": "", "type": "nominal"}}, "height": 400, "padding": 30, "title": "\u041a\u043e\u0440\u0440\u0435\u043b\u044f\u0446\u0438\u0438 \u043f\u043e\u043a\u0430\u0437\u043e\u0432/\u043a\u043b\u0438\u043a\u043e\u0432/\u0437\u0430\u043a\u0430\u0437\u043e\u0432: avia", "width": 400, "$schema": "https://vega.github.io/schema/vega-lite/v6.1.0.json", "datasets": {"data-81b5fe5ef3aa1fe9a1cf1fdd875e8008": [{"row": "active_imp_avia", "col": "active_imp_avia", "corr": 1.0}, {"row": "passive_imp_avia", "col": "active_imp_avia", "corr": 0.01876412266457888}, {"row": "active_click_avia", "col": "active_imp_avia", "corr": 0.6555267805752467}, {"row": "passive_click_avia", "col": "active_imp_avia", "corr": 0.08891639561678617}, {"row": "orders_amt_avia", "col": "active_imp_avia", "corr": -0.04479889738838307}, {"row": "active_imp_avia", "col": "passive_imp_avia", "corr": 0.01876412266457888}, {"row": "passive_imp_avia", "col": "passive_imp_avia", "corr": 1.0}, {"row": "active_click_avia", "col": "passive_imp_avia", "corr": 0.048482427442423495}, {"row": "passive_click_avia", "col": "passive_imp_avia", "corr": 0.27543793232581393}, {"row": "orders_amt_avia", "col": "passive_imp_avia", "corr": 0.03022795982049177}, {"row": "active_imp_avia", "col": "active_click_avia", "corr": 0.6555267805752467}, {"row": "passive_imp_avia", "col": "active_click_avia", "corr": 0.048482427442423495}, {"row": "active_click_avia", "col": "active_click_avia", "corr": 1.0}, {"row": "passive_click_avia", "col": "active_click_avia", "corr": 0.11058067071772743}, {"row": "orders_amt_avia", "col": "active_click_avia", "corr": 0.007181957024016167}, {"row": "active_imp_avia", "col": "passive_click_avia", "corr": 0.08891639561678617}, {"row": "passive_imp_avia", "col": "passive_click_avia", "corr": 0.27543793232581393}, {"row": "active_click_avia", "col": "passive_click_avia", "corr": 0.11058067071772743}, {"row": "passive_click_avia", "col": "passive_click_avia", "corr": 1.0}, {"row": "orders_amt_avia", "col": "passive_click_avia", "corr": 0.14634536196166995}, {"row": "active_imp_avia", "col": "orders_amt_avia", "corr": -0.04479889738838307}, {"row": "passive_imp_avia", "col": "orders_amt_avia", "corr": 0.03022795982049177}, {"row": "active_click_avia", "col": "orders_amt_avia", "corr": 0.007181957024016167}, {"row": "passive_click_avia", "col": "orders_amt_avia", "corr": 0.14634536196166995}, {"row": "orders_amt_avia", "col": "orders_amt_avia", "corr": 1.0}]}};
var embedOpt = {"mode": "vega-lite"};
function showError(el, error){
el.innerHTML = ('<div style="color:red;">'
+ '<p>JavaScript Error: ' + error.message + '</p>'
+ "<p>This usually means there's a typo in your chart specification. "
+ "See the javascript console for the full traceback.</p>"
+ '</div>');
throw error;
}
const el = document.getElementById('vis');
vegaEmbed("#vis", spec, embedOpt)
.catch(error => showError(el, error));
})(vegaEmbed);
</script>
</body>
</html>

View File

@@ -0,0 +1,44 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
#vis.vega-embed {
width: 100%;
display: flex;
}
#vis.vega-embed details,
#vis.vega-embed details summary {
position: relative;
}
</style>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vega@6"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vega-lite@6.1.0"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vega-embed@7"></script>
<style>@font-face{font-family:'Segoe UI Variable'; src: url('file:///Users/dan/Downloads/AyuGram%20Desktop/SegoeUIVF.ttf') format('truetype'); font-weight:100 900; font-style:normal;}
body, text, .vega-bindings {font-family:'Segoe UI Variable','Segoe UI',sans-serif;}</style>
</head>
<body>
<div id="vis"></div>
<script>
(function(vegaEmbed) {
var spec = {"usermeta": {"embedOptions": {"theme": "dark"}}, "config": {"view": {"continuousWidth": 300, "continuousHeight": 300}, "axis": {"grid": true, "labelFont": "Segoe UI Variable", "labelFontSize": 16, "labelFontWeight": 400, "titleFont": "Segoe UI Variable", "titleFontSize": 18, "titleFontWeight": 600}, "legend": {"labelFont": "Segoe UI Variable", "titleFont": "Segoe UI Variable"}, "title": {"anchor": "start", "font": "Segoe UI Variable", "fontSize": 18, "fontWeight": 600}}, "data": {"name": "data-158e8b587028464f7420184e3a69712d"}, "mark": {"type": "rect"}, "encoding": {"color": {"field": "corr", "legend": {"title": "corr"}, "scale": {"domain": [-1, 1], "scheme": "redblue"}, "type": "quantitative"}, "tooltip": [{"field": "row", "type": "nominal"}, {"field": "col", "type": "nominal"}, {"field": "corr", "format": ".3f", "type": "quantitative"}], "x": {"field": "col", "title": "", "type": "nominal"}, "y": {"field": "row", "title": "", "type": "nominal"}}, "height": 400, "padding": 30, "title": "\u041a\u043e\u0440\u0440\u0435\u043b\u044f\u0446\u0438\u0438 \u043f\u043e\u043a\u0430\u0437\u043e\u0432/\u043a\u043b\u0438\u043a\u043e\u0432/\u0437\u0430\u043a\u0430\u0437\u043e\u0432: avia_hotel", "width": 400, "$schema": "https://vega.github.io/schema/vega-lite/v6.1.0.json", "datasets": {"data-158e8b587028464f7420184e3a69712d": [{"row": "active_imp_avia_hotel", "col": "active_imp_avia_hotel", "corr": 1.0}, {"row": "passive_imp_avia_hotel", "col": "active_imp_avia_hotel", "corr": -0.08274509905837495}, {"row": "active_click_avia_hotel", "col": "active_imp_avia_hotel", "corr": 0.6424745469930201}, {"row": "passive_click_avia_hotel", "col": "active_imp_avia_hotel", "corr": 0.0656927131251431}, {"row": "orders_amt_avia_hotel", "col": "active_imp_avia_hotel", "corr": 0.11791995115159383}, {"row": "active_imp_avia_hotel", "col": "passive_imp_avia_hotel", "corr": -0.08274509905837495}, {"row": "passive_imp_avia_hotel", "col": "passive_imp_avia_hotel", "corr": 1.0}, {"row": "active_click_avia_hotel", "col": "passive_imp_avia_hotel", "corr": -0.002830801434428736}, {"row": "passive_click_avia_hotel", "col": "passive_imp_avia_hotel", "corr": 0.19064250507318162}, {"row": "orders_amt_avia_hotel", "col": "passive_imp_avia_hotel", "corr": 0.0829341029860776}, {"row": "active_imp_avia_hotel", "col": "active_click_avia_hotel", "corr": 0.6424745469930201}, {"row": "passive_imp_avia_hotel", "col": "active_click_avia_hotel", "corr": -0.002830801434428736}, {"row": "active_click_avia_hotel", "col": "active_click_avia_hotel", "corr": 1.0}, {"row": "passive_click_avia_hotel", "col": "active_click_avia_hotel", "corr": 0.08320023005001294}, {"row": "orders_amt_avia_hotel", "col": "active_click_avia_hotel", "corr": 0.04818436665905769}, {"row": "active_imp_avia_hotel", "col": "passive_click_avia_hotel", "corr": 0.0656927131251431}, {"row": "passive_imp_avia_hotel", "col": "passive_click_avia_hotel", "corr": 0.19064250507318162}, {"row": "active_click_avia_hotel", "col": "passive_click_avia_hotel", "corr": 0.08320023005001294}, {"row": "passive_click_avia_hotel", "col": "passive_click_avia_hotel", "corr": 1.0}, {"row": "orders_amt_avia_hotel", "col": "passive_click_avia_hotel", "corr": 0.1191470947872778}, {"row": "active_imp_avia_hotel", "col": "orders_amt_avia_hotel", "corr": 0.11791995115159383}, {"row": "passive_imp_avia_hotel", "col": "orders_amt_avia_hotel", "corr": 0.0829341029860776}, {"row": "active_click_avia_hotel", "col": "orders_amt_avia_hotel", "corr": 0.04818436665905769}, {"row": "passive_click_avia_hotel", "col": "orders_amt_avia_hotel", "corr": 0.1191470947872778}, {"row": "orders_amt_avia_hotel", "col": "orders_amt_avia_hotel", "corr": 1.0}]}};
var embedOpt = {"mode": "vega-lite"};
function showError(el, error){
el.innerHTML = ('<div style="color:red;">'
+ '<p>JavaScript Error: ' + error.message + '</p>'
+ "<p>This usually means there's a typo in your chart specification. "
+ "See the javascript console for the full traceback.</p>"
+ '</div>');
throw error;
}
const el = document.getElementById('vis');
vegaEmbed("#vis", spec, embedOpt)
.catch(error => showError(el, error));
})(vegaEmbed);
</script>
</body>
</html>

View File

@@ -0,0 +1,44 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
#vis.vega-embed {
width: 100%;
display: flex;
}
#vis.vega-embed details,
#vis.vega-embed details summary {
position: relative;
}
</style>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vega@6"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vega-lite@6.1.0"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vega-embed@7"></script>
<style>@font-face{font-family:'Segoe UI Variable'; src: url('file:///Users/dan/Downloads/AyuGram%20Desktop/SegoeUIVF.ttf') format('truetype'); font-weight:100 900; font-style:normal;}
body, text, .vega-bindings {font-family:'Segoe UI Variable','Segoe UI',sans-serif;}</style>
</head>
<body>
<div id="vis"></div>
<script>
(function(vegaEmbed) {
var spec = {"usermeta": {"embedOptions": {"theme": "dark"}}, "config": {"view": {"continuousWidth": 300, "continuousHeight": 300}, "axis": {"grid": true, "labelFont": "Segoe UI Variable", "labelFontSize": 16, "labelFontWeight": 400, "titleFont": "Segoe UI Variable", "titleFontSize": 18, "titleFontWeight": 600}, "legend": {"labelFont": "Segoe UI Variable", "titleFont": "Segoe UI Variable"}, "title": {"anchor": "start", "font": "Segoe UI Variable", "fontSize": 18, "fontWeight": 600}}, "data": {"name": "data-cd1e14ccf8ef0243ac2429b66fca6f3e"}, "mark": {"type": "rect"}, "encoding": {"color": {"field": "corr", "legend": {"title": "corr"}, "scale": {"domain": [-1, 1], "scheme": "redblue"}, "type": "quantitative"}, "tooltip": [{"field": "row", "type": "nominal"}, {"field": "col", "type": "nominal"}, {"field": "corr", "format": ".3f", "type": "quantitative"}], "x": {"field": "col", "title": "", "type": "nominal"}, "y": {"field": "row", "title": "", "type": "nominal"}}, "height": 400, "padding": 30, "title": "\u041a\u043e\u0440\u0440\u0435\u043b\u044f\u0446\u0438\u0438 \u043f\u043e\u043a\u0430\u0437\u043e\u0432/\u043a\u043b\u0438\u043a\u043e\u0432/\u0437\u0430\u043a\u0430\u0437\u043e\u0432: ent", "width": 400, "$schema": "https://vega.github.io/schema/vega-lite/v6.1.0.json", "datasets": {"data-cd1e14ccf8ef0243ac2429b66fca6f3e": [{"row": "active_imp_ent", "col": "active_imp_ent", "corr": 1.0}, {"row": "passive_imp_ent", "col": "active_imp_ent", "corr": 0.3740482978344062}, {"row": "active_click_ent", "col": "active_imp_ent", "corr": 0.8713679748694044}, {"row": "passive_click_ent", "col": "active_imp_ent", "corr": 0.1834267922170377}, {"row": "orders_amt_ent", "col": "active_imp_ent", "corr": 0.19909732995304016}, {"row": "active_imp_ent", "col": "passive_imp_ent", "corr": 0.3740482978344062}, {"row": "passive_imp_ent", "col": "passive_imp_ent", "corr": 1.0}, {"row": "active_click_ent", "col": "passive_imp_ent", "corr": 0.3606804643725377}, {"row": "passive_click_ent", "col": "passive_imp_ent", "corr": 0.5648383908323416}, {"row": "orders_amt_ent", "col": "passive_imp_ent", "corr": 0.4151695148464165}, {"row": "active_imp_ent", "col": "active_click_ent", "corr": 0.8713679748694044}, {"row": "passive_imp_ent", "col": "active_click_ent", "corr": 0.3606804643725377}, {"row": "active_click_ent", "col": "active_click_ent", "corr": 1.0}, {"row": "passive_click_ent", "col": "active_click_ent", "corr": 0.12953818089063812}, {"row": "orders_amt_ent", "col": "active_click_ent", "corr": 0.16418539548659097}, {"row": "active_imp_ent", "col": "passive_click_ent", "corr": 0.1834267922170377}, {"row": "passive_imp_ent", "col": "passive_click_ent", "corr": 0.5648383908323416}, {"row": "active_click_ent", "col": "passive_click_ent", "corr": 0.12953818089063812}, {"row": "passive_click_ent", "col": "passive_click_ent", "corr": 1.0}, {"row": "orders_amt_ent", "col": "passive_click_ent", "corr": 0.5553099034616074}, {"row": "active_imp_ent", "col": "orders_amt_ent", "corr": 0.19909732995304016}, {"row": "passive_imp_ent", "col": "orders_amt_ent", "corr": 0.4151695148464165}, {"row": "active_click_ent", "col": "orders_amt_ent", "corr": 0.16418539548659097}, {"row": "passive_click_ent", "col": "orders_amt_ent", "corr": 0.5553099034616074}, {"row": "orders_amt_ent", "col": "orders_amt_ent", "corr": 1.0}]}};
var embedOpt = {"mode": "vega-lite"};
function showError(el, error){
el.innerHTML = ('<div style="color:red;">'
+ '<p>JavaScript Error: ' + error.message + '</p>'
+ "<p>This usually means there's a typo in your chart specification. "
+ "See the javascript console for the full traceback.</p>"
+ '</div>');
throw error;
}
const el = document.getElementById('vis');
vegaEmbed("#vis", spec, embedOpt)
.catch(error => showError(el, error));
})(vegaEmbed);
</script>
</body>
</html>

View File

@@ -0,0 +1,44 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
#vis.vega-embed {
width: 100%;
display: flex;
}
#vis.vega-embed details,
#vis.vega-embed details summary {
position: relative;
}
</style>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vega@6"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vega-lite@6.1.0"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vega-embed@7"></script>
<style>@font-face{font-family:'Segoe UI Variable'; src: url('file:///Users/dan/Downloads/AyuGram%20Desktop/SegoeUIVF.ttf') format('truetype'); font-weight:100 900; font-style:normal;}
body, text, .vega-bindings {font-family:'Segoe UI Variable','Segoe UI',sans-serif;}</style>
</head>
<body>
<div id="vis"></div>
<script>
(function(vegaEmbed) {
var spec = {"usermeta": {"embedOptions": {"theme": "dark"}}, "config": {"view": {"continuousWidth": 300, "continuousHeight": 300}, "axis": {"grid": true, "labelFont": "Segoe UI Variable", "labelFontSize": 16, "labelFontWeight": 400, "titleFont": "Segoe UI Variable", "titleFontSize": 18, "titleFontWeight": 600}, "legend": {"labelFont": "Segoe UI Variable", "titleFont": "Segoe UI Variable"}, "title": {"anchor": "start", "font": "Segoe UI Variable", "fontSize": 18, "fontWeight": 600}}, "data": {"name": "data-a2a0150a275d02c7b9393305bbd503d6"}, "mark": {"type": "rect"}, "encoding": {"color": {"field": "corr", "legend": {"title": "corr"}, "scale": {"domain": [-1, 1], "scheme": "redblue"}, "type": "quantitative"}, "tooltip": [{"field": "row", "type": "nominal"}, {"field": "col", "type": "nominal"}, {"field": "corr", "format": ".3f", "type": "quantitative"}], "x": {"field": "col", "title": "", "type": "nominal"}, "y": {"field": "row", "title": "", "type": "nominal"}}, "height": 400, "padding": 30, "title": "\u041a\u043e\u0440\u0440\u0435\u043b\u044f\u0446\u0438\u0438 \u043f\u043e\u043a\u0430\u0437\u043e\u0432/\u043a\u043b\u0438\u043a\u043e\u0432/\u0437\u0430\u043a\u0430\u0437\u043e\u0432: hotel", "width": 400, "$schema": "https://vega.github.io/schema/vega-lite/v6.1.0.json", "datasets": {"data-a2a0150a275d02c7b9393305bbd503d6": [{"row": "active_imp_hotel", "col": "active_imp_hotel", "corr": 1.0}, {"row": "passive_imp_hotel", "col": "active_imp_hotel", "corr": -0.0177015411050084}, {"row": "active_click_hotel", "col": "active_imp_hotel", "corr": 0.6075829324496919}, {"row": "passive_click_hotel", "col": "active_imp_hotel", "corr": 0.009979892986558766}, {"row": "orders_amt_hotel", "col": "active_imp_hotel", "corr": 0.06957731524967162}, {"row": "active_imp_hotel", "col": "passive_imp_hotel", "corr": -0.0177015411050084}, {"row": "passive_imp_hotel", "col": "passive_imp_hotel", "corr": 1.0}, {"row": "active_click_hotel", "col": "passive_imp_hotel", "corr": 0.01468063302643315}, {"row": "passive_click_hotel", "col": "passive_imp_hotel", "corr": 0.17649206333048828}, {"row": "orders_amt_hotel", "col": "passive_imp_hotel", "corr": 0.0020660458585801825}, {"row": "active_imp_hotel", "col": "active_click_hotel", "corr": 0.6075829324496919}, {"row": "passive_imp_hotel", "col": "active_click_hotel", "corr": 0.01468063302643315}, {"row": "active_click_hotel", "col": "active_click_hotel", "corr": 1.0}, {"row": "passive_click_hotel", "col": "active_click_hotel", "corr": 0.035078311469620184}, {"row": "orders_amt_hotel", "col": "active_click_hotel", "corr": 0.02986170141739076}, {"row": "active_imp_hotel", "col": "passive_click_hotel", "corr": 0.009979892986558766}, {"row": "passive_imp_hotel", "col": "passive_click_hotel", "corr": 0.17649206333048828}, {"row": "active_click_hotel", "col": "passive_click_hotel", "corr": 0.035078311469620184}, {"row": "passive_click_hotel", "col": "passive_click_hotel", "corr": 1.0}, {"row": "orders_amt_hotel", "col": "passive_click_hotel", "corr": -0.0025707911767623094}, {"row": "active_imp_hotel", "col": "orders_amt_hotel", "corr": 0.06957731524967162}, {"row": "passive_imp_hotel", "col": "orders_amt_hotel", "corr": 0.0020660458585801825}, {"row": "active_click_hotel", "col": "orders_amt_hotel", "corr": 0.02986170141739076}, {"row": "passive_click_hotel", "col": "orders_amt_hotel", "corr": -0.0025707911767623094}, {"row": "orders_amt_hotel", "col": "orders_amt_hotel", "corr": 1.0}]}};
var embedOpt = {"mode": "vega-lite"};
function showError(el, error){
el.innerHTML = ('<div style="color:red;">'
+ '<p>JavaScript Error: ' + error.message + '</p>'
+ "<p>This usually means there's a typo in your chart specification. "
+ "See the javascript console for the full traceback.</p>"
+ '</div>');
throw error;
}
const el = document.getElementById('vis');
vegaEmbed("#vis", spec, embedOpt)
.catch(error => showError(el, error));
})(vegaEmbed);
</script>
</body>
</html>

View File

@@ -0,0 +1,44 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
#vis.vega-embed {
width: 100%;
display: flex;
}
#vis.vega-embed details,
#vis.vega-embed details summary {
position: relative;
}
</style>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vega@6"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vega-lite@6.1.0"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vega-embed@7"></script>
<style>@font-face{font-family:'Segoe UI Variable'; src: url('file:///Users/dan/Downloads/AyuGram%20Desktop/SegoeUIVF.ttf') format('truetype'); font-weight:100 900; font-style:normal;}
body, text, .vega-bindings {font-family:'Segoe UI Variable','Segoe UI',sans-serif;}</style>
</head>
<body>
<div id="vis"></div>
<script>
(function(vegaEmbed) {
var spec = {"usermeta": {"embedOptions": {"theme": "dark"}}, "config": {"view": {"continuousWidth": 300, "continuousHeight": 300}, "axis": {"grid": true, "labelFont": "Segoe UI Variable", "labelFontSize": 16, "labelFontWeight": 400, "titleFont": "Segoe UI Variable", "titleFontSize": 18, "titleFontWeight": 600}, "legend": {"labelFont": "Segoe UI Variable", "titleFont": "Segoe UI Variable"}, "title": {"anchor": "start", "font": "Segoe UI Variable", "fontSize": 18, "fontWeight": 600}}, "data": {"name": "data-3ac7d524ac078c0c96bdf5c96405262f"}, "mark": {"type": "rect"}, "encoding": {"color": {"field": "corr", "legend": {"title": "corr"}, "scale": {"domain": [-1, 1], "scheme": "redblue"}, "type": "quantitative"}, "tooltip": [{"field": "row", "type": "nominal"}, {"field": "col", "type": "nominal"}, {"field": "corr", "format": ".3f", "type": "quantitative"}], "x": {"field": "col", "title": "", "type": "nominal"}, "y": {"field": "row", "title": "", "type": "nominal"}}, "height": 400, "padding": 30, "title": "\u041a\u043e\u0440\u0440\u0435\u043b\u044f\u0446\u0438\u0438 \u043f\u043e\u043a\u0430\u0437\u043e\u0432/\u043a\u043b\u0438\u043a\u043e\u0432/\u0437\u0430\u043a\u0430\u0437\u043e\u0432: shopping", "width": 400, "$schema": "https://vega.github.io/schema/vega-lite/v6.1.0.json", "datasets": {"data-3ac7d524ac078c0c96bdf5c96405262f": [{"row": "active_imp_shopping", "col": "active_imp_shopping", "corr": 1.0}, {"row": "passive_imp_shopping", "col": "active_imp_shopping", "corr": 0.22682584296837505}, {"row": "active_click_shopping", "col": "active_imp_shopping", "corr": 0.8729875334818619}, {"row": "passive_click_shopping", "col": "active_imp_shopping", "corr": 0.11692802611837975}, {"row": "orders_amt_shopping", "col": "active_imp_shopping", "corr": 0.1866072104879359}, {"row": "active_imp_shopping", "col": "passive_imp_shopping", "corr": 0.22682584296837505}, {"row": "passive_imp_shopping", "col": "passive_imp_shopping", "corr": 1.0}, {"row": "active_click_shopping", "col": "passive_imp_shopping", "corr": 0.20868395081922667}, {"row": "passive_click_shopping", "col": "passive_imp_shopping", "corr": 0.25897090952326174}, {"row": "orders_amt_shopping", "col": "passive_imp_shopping", "corr": 0.1476827158464753}, {"row": "active_imp_shopping", "col": "active_click_shopping", "corr": 0.8729875334818619}, {"row": "passive_imp_shopping", "col": "active_click_shopping", "corr": 0.20868395081922667}, {"row": "active_click_shopping", "col": "active_click_shopping", "corr": 1.0}, {"row": "passive_click_shopping", "col": "active_click_shopping", "corr": 0.0800917496050481}, {"row": "orders_amt_shopping", "col": "active_click_shopping", "corr": 0.1837650330305473}, {"row": "active_imp_shopping", "col": "passive_click_shopping", "corr": 0.11692802611837975}, {"row": "passive_imp_shopping", "col": "passive_click_shopping", "corr": 0.25897090952326174}, {"row": "active_click_shopping", "col": "passive_click_shopping", "corr": 0.0800917496050481}, {"row": "passive_click_shopping", "col": "passive_click_shopping", "corr": 1.0}, {"row": "orders_amt_shopping", "col": "passive_click_shopping", "corr": 0.11649273142550405}, {"row": "active_imp_shopping", "col": "orders_amt_shopping", "corr": 0.1866072104879359}, {"row": "passive_imp_shopping", "col": "orders_amt_shopping", "corr": 0.1476827158464753}, {"row": "active_click_shopping", "col": "orders_amt_shopping", "corr": 0.1837650330305473}, {"row": "passive_click_shopping", "col": "orders_amt_shopping", "corr": 0.11649273142550405}, {"row": "orders_amt_shopping", "col": "orders_amt_shopping", "corr": 1.0}]}};
var embedOpt = {"mode": "vega-lite"};
function showError(el, error){
el.innerHTML = ('<div style="color:red;">'
+ '<p>JavaScript Error: ' + error.message + '</p>'
+ "<p>This usually means there's a typo in your chart specification. "
+ "See the javascript console for the full traceback.</p>"
+ '</div>');
throw error;
}
const el = document.getElementById('vis');
vegaEmbed("#vis", spec, embedOpt)
.catch(error => showError(el, error));
})(vegaEmbed);
</script>
</body>
</html>

View File

@@ -0,0 +1,44 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
#vis.vega-embed {
width: 100%;
display: flex;
}
#vis.vega-embed details,
#vis.vega-embed details summary {
position: relative;
}
</style>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vega@6"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vega-lite@6.1.0"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vega-embed@7"></script>
<style>@font-face{font-family:'Segoe UI Variable'; src: url('file:///Users/dan/Downloads/AyuGram%20Desktop/SegoeUIVF.ttf') format('truetype'); font-weight:100 900; font-style:normal;}
body, text, .vega-bindings {font-family:'Segoe UI Variable','Segoe UI',sans-serif;}</style>
</head>
<body>
<div id="vis"></div>
<script>
(function(vegaEmbed) {
var spec = {"usermeta": {"embedOptions": {"theme": "dark"}}, "config": {"view": {"continuousWidth": 300, "continuousHeight": 300}, "axis": {"grid": true, "labelFont": "Segoe UI Variable", "labelFontSize": 16, "labelFontWeight": 400, "titleFont": "Segoe UI Variable", "titleFontSize": 18, "titleFontWeight": 600}, "legend": {"labelFont": "Segoe UI Variable", "titleFont": "Segoe UI Variable"}, "title": {"anchor": "start", "font": "Segoe UI Variable", "fontSize": 18, "fontWeight": 600}}, "data": {"name": "data-570897060314c084dad6a0fe94034ace"}, "mark": {"type": "rect"}, "encoding": {"color": {"field": "corr", "legend": {"title": "corr"}, "scale": {"domain": [-1, 1], "scheme": "redblue"}, "type": "quantitative"}, "tooltip": [{"field": "row", "type": "nominal"}, {"field": "col", "type": "nominal"}, {"field": "corr", "format": ".3f", "type": "quantitative"}], "x": {"field": "col", "title": "", "type": "nominal"}, "y": {"field": "row", "title": "", "type": "nominal"}}, "height": 400, "padding": 30, "title": "\u041a\u043e\u0440\u0440\u0435\u043b\u044f\u0446\u0438\u0438 \u043f\u043e\u043a\u0430\u0437\u043e\u0432/\u043a\u043b\u0438\u043a\u043e\u0432/\u0437\u0430\u043a\u0430\u0437\u043e\u0432: super", "width": 400, "$schema": "https://vega.github.io/schema/vega-lite/v6.1.0.json", "datasets": {"data-570897060314c084dad6a0fe94034ace": [{"row": "active_imp_super", "col": "active_imp_super", "corr": 1.0}, {"row": "passive_imp_super", "col": "active_imp_super", "corr": 0.10775076644240923}, {"row": "active_click_super", "col": "active_imp_super", "corr": 0.815114139753961}, {"row": "passive_click_super", "col": "active_imp_super", "corr": 0.036142767956872573}, {"row": "orders_amt_super", "col": "active_imp_super", "corr": 0.044474400312866307}, {"row": "active_imp_super", "col": "passive_imp_super", "corr": 0.10775076644240923}, {"row": "passive_imp_super", "col": "passive_imp_super", "corr": 1.0}, {"row": "active_click_super", "col": "passive_imp_super", "corr": 0.13851152985212567}, {"row": "passive_click_super", "col": "passive_imp_super", "corr": 0.25041456703210235}, {"row": "orders_amt_super", "col": "passive_imp_super", "corr": 0.10661548504413648}, {"row": "active_imp_super", "col": "active_click_super", "corr": 0.815114139753961}, {"row": "passive_imp_super", "col": "active_click_super", "corr": 0.13851152985212567}, {"row": "active_click_super", "col": "active_click_super", "corr": 1.0}, {"row": "passive_click_super", "col": "active_click_super", "corr": 0.018411595933568142}, {"row": "orders_amt_super", "col": "active_click_super", "corr": 0.020608557316194334}, {"row": "active_imp_super", "col": "passive_click_super", "corr": 0.036142767956872573}, {"row": "passive_imp_super", "col": "passive_click_super", "corr": 0.25041456703210235}, {"row": "active_click_super", "col": "passive_click_super", "corr": 0.018411595933568142}, {"row": "passive_click_super", "col": "passive_click_super", "corr": 1.0}, {"row": "orders_amt_super", "col": "passive_click_super", "corr": 0.11858521469065078}, {"row": "active_imp_super", "col": "orders_amt_super", "corr": 0.044474400312866307}, {"row": "passive_imp_super", "col": "orders_amt_super", "corr": 0.10661548504413648}, {"row": "active_click_super", "col": "orders_amt_super", "corr": 0.020608557316194334}, {"row": "passive_click_super", "col": "orders_amt_super", "corr": 0.11858521469065078}, {"row": "orders_amt_super", "col": "orders_amt_super", "corr": 1.0}]}};
var embedOpt = {"mode": "vega-lite"};
function showError(el, error){
el.innerHTML = ('<div style="color:red;">'
+ '<p>JavaScript Error: ' + error.message + '</p>'
+ "<p>This usually means there's a typo in your chart specification. "
+ "See the javascript console for the full traceback.</p>"
+ '</div>');
throw error;
}
const el = document.getElementById('vis');
vegaEmbed("#vis", spec, embedOpt)
.catch(error => showError(el, error));
})(vegaEmbed);
</script>
</body>
</html>

View File

@@ -0,0 +1,44 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
#vis.vega-embed {
width: 100%;
display: flex;
}
#vis.vega-embed details,
#vis.vega-embed details summary {
position: relative;
}
</style>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vega@6"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vega-lite@6.1.0"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vega-embed@7"></script>
<style>@font-face{font-family:'Segoe UI Variable'; src: url('file:///Users/dan/Downloads/AyuGram%20Desktop/SegoeUIVF.ttf') format('truetype'); font-weight:100 900; font-style:normal;}
body, text, .vega-bindings {font-family:'Segoe UI Variable','Segoe UI',sans-serif;}</style>
</head>
<body>
<div id="vis"></div>
<script>
(function(vegaEmbed) {
var spec = {"usermeta": {"embedOptions": {"theme": "dark"}}, "config": {"view": {"continuousWidth": 300, "continuousHeight": 300}, "axis": {"grid": true, "labelFont": "Segoe UI Variable", "labelFontSize": 16, "labelFontWeight": 400, "titleFont": "Segoe UI Variable", "titleFontSize": 18, "titleFontWeight": 600}, "legend": {"labelFont": "Segoe UI Variable", "titleFont": "Segoe UI Variable"}, "title": {"anchor": "start", "font": "Segoe UI Variable", "fontSize": 18, "fontWeight": 600}}, "data": {"name": "data-5ac874a21fd43fc95ef8060b3a83793c"}, "mark": {"type": "rect"}, "encoding": {"color": {"field": "corr", "legend": {"title": "corr"}, "scale": {"domain": [-1, 1], "scheme": "redblue"}, "type": "quantitative"}, "tooltip": [{"field": "row", "type": "nominal"}, {"field": "col", "type": "nominal"}, {"field": "corr", "format": ".3f", "type": "quantitative"}], "x": {"field": "col", "title": "", "type": "nominal"}, "y": {"field": "row", "title": "", "type": "nominal"}}, "height": 400, "padding": 30, "title": "\u041a\u043e\u0440\u0440\u0435\u043b\u044f\u0446\u0438\u0438 \u043f\u043e\u043a\u0430\u0437\u043e\u0432/\u043a\u043b\u0438\u043a\u043e\u0432/\u0437\u0430\u043a\u0430\u0437\u043e\u0432: transport", "width": 400, "$schema": "https://vega.github.io/schema/vega-lite/v6.1.0.json", "datasets": {"data-5ac874a21fd43fc95ef8060b3a83793c": [{"row": "active_imp_transport", "col": "active_imp_transport", "corr": 1.0}, {"row": "passive_imp_transport", "col": "active_imp_transport", "corr": 0.40168978254566456}, {"row": "active_click_transport", "col": "active_imp_transport", "corr": 0.8428763034279261}, {"row": "passive_click_transport", "col": "active_imp_transport", "corr": 0.11832571530873176}, {"row": "orders_amt_transport", "col": "active_imp_transport", "corr": 0.17781437332297736}, {"row": "active_imp_transport", "col": "passive_imp_transport", "corr": 0.40168978254566456}, {"row": "passive_imp_transport", "col": "passive_imp_transport", "corr": 1.0}, {"row": "active_click_transport", "col": "passive_imp_transport", "corr": 0.4678363557472336}, {"row": "passive_click_transport", "col": "passive_imp_transport", "corr": 0.25797171201314045}, {"row": "orders_amt_transport", "col": "passive_imp_transport", "corr": 0.19235638990080245}, {"row": "active_imp_transport", "col": "active_click_transport", "corr": 0.8428763034279261}, {"row": "passive_imp_transport", "col": "active_click_transport", "corr": 0.4678363557472336}, {"row": "active_click_transport", "col": "active_click_transport", "corr": 1.0}, {"row": "passive_click_transport", "col": "active_click_transport", "corr": 0.09033265638665873}, {"row": "orders_amt_transport", "col": "active_click_transport", "corr": 0.16848280412867794}, {"row": "active_imp_transport", "col": "passive_click_transport", "corr": 0.11832571530873176}, {"row": "passive_imp_transport", "col": "passive_click_transport", "corr": 0.25797171201314045}, {"row": "active_click_transport", "col": "passive_click_transport", "corr": 0.09033265638665873}, {"row": "passive_click_transport", "col": "passive_click_transport", "corr": 1.0}, {"row": "orders_amt_transport", "col": "passive_click_transport", "corr": 0.24259813553198464}, {"row": "active_imp_transport", "col": "orders_amt_transport", "corr": 0.17781437332297736}, {"row": "passive_imp_transport", "col": "orders_amt_transport", "corr": 0.19235638990080245}, {"row": "active_click_transport", "col": "orders_amt_transport", "corr": 0.16848280412867794}, {"row": "passive_click_transport", "col": "orders_amt_transport", "corr": 0.24259813553198464}, {"row": "orders_amt_transport", "col": "orders_amt_transport", "corr": 1.0}]}};
var embedOpt = {"mode": "vega-lite"};
function showError(el, error){
el.innerHTML = ('<div style="color:red;">'
+ '<p>JavaScript Error: ' + error.message + '</p>'
+ "<p>This usually means there's a typo in your chart specification. "
+ "See the javascript console for the full traceback.</p>"
+ '</div>');
throw error;
}
const el = document.getElementById('vis');
vegaEmbed("#vis", spec, embedOpt)
.catch(error => showError(el, error));
})(vegaEmbed);
</script>
</body>
</html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,42 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
#vis.vega-embed {
width: 100%;
display: flex;
}
#vis.vega-embed details,
#vis.vega-embed details summary {
position: relative;
}
</style>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vega@6"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vega-lite@6.1.0"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vega-embed@7"></script>
</head>
<body>
<div id="vis"></div>
<script>
(function(vegaEmbed) {
var spec = {"usermeta": {"embedOptions": {"theme": "dark"}}, "config": {"view": {"continuousWidth": 300, "continuousHeight": 300}, "axis": {"grid": true, "labelFont": "Segoe UI Variable", "labelFontSize": 16, "labelFontWeight": 400, "titleFont": "Segoe UI Variable", "titleFontSize": 18, "titleFontWeight": 600}, "title": {"anchor": "middle", "font": "Segoe UI Variable", "fontSize": 20, "fontWeight": 600}}, "data": {"name": "data-e8525735964a39d1872eccee3a42785b"}, "mark": {"type": "bar", "cornerRadius": 6, "width": 35}, "background": "#00000000", "encoding": {"color": {"field": "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str", "legend": null, "type": "nominal"}, "tooltip": [{"field": "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str", "type": "nominal"}, {"field": "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432", "type": "quantitative"}], "x": {"field": "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str", "sort": null, "title": "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432", "type": "nominal"}, "y": {"field": "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432", "title": "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432", "type": "quantitative"}}, "height": 400, "padding": 50, "title": "\u0420\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043f\u043e \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438: AVIA", "width": 600, "$schema": "https://vega.github.io/schema/vega-lite/v6.1.0.json", "datasets": {"data-e8525735964a39d1872eccee3a42785b": [{"\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432": 0, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432": 117307, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str": "0"}, {"\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432": 1, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432": 755, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str": "1"}, {"\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432": 2, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432": 108, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str": "2"}, {"\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432": 3, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432": 14, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str": "3"}, {"\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432": 4, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432": 4, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str": "4"}, {"\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432": 6, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432": 1, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str": "6"}]}};
var embedOpt = {"mode": "vega-lite"};
function showError(el, error){
el.innerHTML = ('<div style="color:red;">'
+ '<p>JavaScript Error: ' + error.message + '</p>'
+ "<p>This usually means there's a typo in your chart specification. "
+ "See the javascript console for the full traceback.</p>"
+ '</div>');
throw error;
}
const el = document.getElementById('vis');
vegaEmbed("#vis", spec, embedOpt)
.catch(error => showError(el, error));
})(vegaEmbed);
</script>
</body>
</html>

View File

@@ -0,0 +1,42 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
#vis.vega-embed {
width: 100%;
display: flex;
}
#vis.vega-embed details,
#vis.vega-embed details summary {
position: relative;
}
</style>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vega@6"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vega-lite@6.1.0"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vega-embed@7"></script>
</head>
<body>
<div id="vis"></div>
<script>
(function(vegaEmbed) {
var spec = {"usermeta": {"embedOptions": {"theme": "dark"}}, "config": {"view": {"continuousWidth": 300, "continuousHeight": 300}, "axis": {"grid": true, "labelFont": "Segoe UI Variable", "labelFontSize": 16, "labelFontWeight": 400, "titleFont": "Segoe UI Variable", "titleFontSize": 18, "titleFontWeight": 600}, "title": {"anchor": "middle", "font": "Segoe UI Variable", "fontSize": 20, "fontWeight": 600}}, "data": {"name": "data-9ac31061938e99fd77617c4db2905740"}, "mark": {"type": "bar", "cornerRadius": 6, "width": 35}, "background": "#00000000", "encoding": {"color": {"field": "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str", "legend": null, "type": "nominal"}, "tooltip": [{"field": "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str", "type": "nominal"}, {"field": "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432", "type": "quantitative"}], "x": {"field": "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str", "sort": null, "title": "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432", "type": "nominal"}, "y": {"field": "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432", "title": "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432", "type": "quantitative"}}, "height": 400, "padding": 50, "title": "\u0420\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043f\u043e \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438: ENT", "width": 600, "$schema": "https://vega.github.io/schema/vega-lite/v6.1.0.json", "datasets": {"data-9ac31061938e99fd77617c4db2905740": [{"\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432": 0, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432": 117134, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str": "0"}, {"\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432": 1, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432": 958, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str": "1"}, {"\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432": 2, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432": 82, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str": "2"}, {"\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432": 3, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432": 9, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str": "3"}, {"\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432": 4, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432": 3, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str": "4"}, {"\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432": 5, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432": 2, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str": "5"}, {"\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432": 11, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432": 1, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str": "11"}]}};
var embedOpt = {"mode": "vega-lite"};
function showError(el, error){
el.innerHTML = ('<div style="color:red;">'
+ '<p>JavaScript Error: ' + error.message + '</p>'
+ "<p>This usually means there's a typo in your chart specification. "
+ "See the javascript console for the full traceback.</p>"
+ '</div>');
throw error;
}
const el = document.getElementById('vis');
vegaEmbed("#vis", spec, embedOpt)
.catch(error => showError(el, error));
})(vegaEmbed);
</script>
</body>
</html>

View File

@@ -0,0 +1,42 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
#vis.vega-embed {
width: 100%;
display: flex;
}
#vis.vega-embed details,
#vis.vega-embed details summary {
position: relative;
}
</style>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vega@6"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vega-lite@6.1.0"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vega-embed@7"></script>
</head>
<body>
<div id="vis"></div>
<script>
(function(vegaEmbed) {
var spec = {"usermeta": {"embedOptions": {"theme": "dark"}}, "config": {"view": {"continuousWidth": 300, "continuousHeight": 300}, "axis": {"grid": true, "labelFont": "Segoe UI Variable", "labelFontSize": 16, "labelFontWeight": 400, "titleFont": "Segoe UI Variable", "titleFontSize": 18, "titleFontWeight": 600}, "title": {"anchor": "middle", "font": "Segoe UI Variable", "fontSize": 20, "fontWeight": 600}}, "data": {"name": "data-4792fb2b4b01a241a8f5ddc724e48516"}, "mark": {"type": "bar", "cornerRadius": 6, "width": 35}, "background": "#00000000", "encoding": {"color": {"field": "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str", "legend": null, "type": "nominal"}, "tooltip": [{"field": "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str", "type": "nominal"}, {"field": "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432", "type": "quantitative"}], "x": {"field": "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str", "sort": null, "title": "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432", "type": "nominal"}, "y": {"field": "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432", "title": "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432", "type": "quantitative"}}, "height": 400, "padding": 50, "title": "\u0420\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043f\u043e \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438: HOTEL", "width": 600, "$schema": "https://vega.github.io/schema/vega-lite/v6.1.0.json", "datasets": {"data-4792fb2b4b01a241a8f5ddc724e48516": [{"\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432": 0, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432": 117759, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str": "0"}, {"\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432": 1, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432": 399, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str": "1"}, {"\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432": 2, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432": 28, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str": "2"}, {"\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432": 3, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432": 3, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str": "3"}]}};
var embedOpt = {"mode": "vega-lite"};
function showError(el, error){
el.innerHTML = ('<div style="color:red;">'
+ '<p>JavaScript Error: ' + error.message + '</p>'
+ "<p>This usually means there's a typo in your chart specification. "
+ "See the javascript console for the full traceback.</p>"
+ '</div>');
throw error;
}
const el = document.getElementById('vis');
vegaEmbed("#vis", spec, embedOpt)
.catch(error => showError(el, error));
})(vegaEmbed);
</script>
</body>
</html>

View File

@@ -0,0 +1,42 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
#vis.vega-embed {
width: 100%;
display: flex;
}
#vis.vega-embed details,
#vis.vega-embed details summary {
position: relative;
}
</style>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vega@6"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vega-lite@6.1.0"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vega-embed@7"></script>
</head>
<body>
<div id="vis"></div>
<script>
(function(vegaEmbed) {
var spec = {"usermeta": {"embedOptions": {"theme": "dark"}}, "config": {"view": {"continuousWidth": 300, "continuousHeight": 300}, "axis": {"grid": true, "labelFont": "Segoe UI Variable", "labelFontSize": 16, "labelFontWeight": 400, "titleFont": "Segoe UI Variable", "titleFontSize": 18, "titleFontWeight": 600}, "title": {"anchor": "middle", "font": "Segoe UI Variable", "fontSize": 20, "fontWeight": 600}}, "data": {"name": "data-fd86208218f3e63a52715a7a95c7e10c"}, "mark": {"type": "bar", "cornerRadius": 6, "width": 35}, "background": "#00000000", "encoding": {"color": {"field": "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str", "legend": null, "type": "nominal"}, "tooltip": [{"field": "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str", "type": "nominal"}, {"field": "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432", "type": "quantitative"}], "x": {"field": "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str", "sort": null, "title": "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432", "type": "nominal"}, "y": {"field": "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432", "title": "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432", "type": "quantitative"}}, "height": 400, "padding": 50, "title": "\u0420\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043f\u043e \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438: SHOPPING", "width": 600, "$schema": "https://vega.github.io/schema/vega-lite/v6.1.0.json", "datasets": {"data-fd86208218f3e63a52715a7a95c7e10c": [{"\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432": 0, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432": 117452, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str": "0"}, {"\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432": 1, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432": 625, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str": "1"}, {"\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432": 2, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432": 86, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str": "2"}, {"\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432": 3, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432": 16, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str": "3"}, {"\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432": 4, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432": 4, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str": "4"}, {"\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432": 5, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432": 3, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str": "5"}, {"\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432": 6, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432": 1, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str": "6"}, {"\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432": 11, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432": 2, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str": "11"}]}};
var embedOpt = {"mode": "vega-lite"};
function showError(el, error){
el.innerHTML = ('<div style="color:red;">'
+ '<p>JavaScript Error: ' + error.message + '</p>'
+ "<p>This usually means there's a typo in your chart specification. "
+ "See the javascript console for the full traceback.</p>"
+ '</div>');
throw error;
}
const el = document.getElementById('vis');
vegaEmbed("#vis", spec, embedOpt)
.catch(error => showError(el, error));
})(vegaEmbed);
</script>
</body>
</html>

View File

@@ -0,0 +1,42 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
#vis.vega-embed {
width: 100%;
display: flex;
}
#vis.vega-embed details,
#vis.vega-embed details summary {
position: relative;
}
</style>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vega@6"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vega-lite@6.1.0"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vega-embed@7"></script>
</head>
<body>
<div id="vis"></div>
<script>
(function(vegaEmbed) {
var spec = {"usermeta": {"embedOptions": {"theme": "dark"}}, "config": {"view": {"continuousWidth": 300, "continuousHeight": 300}, "axis": {"grid": true, "labelFont": "Segoe UI Variable", "labelFontSize": 16, "labelFontWeight": 400, "titleFont": "Segoe UI Variable", "titleFontSize": 18, "titleFontWeight": 600}, "title": {"anchor": "middle", "font": "Segoe UI Variable", "fontSize": 20, "fontWeight": 600}}, "data": {"name": "data-6a3e30f72b49598ac7803a03e6e1a4bf"}, "mark": {"type": "bar", "cornerRadius": 6, "width": 35}, "background": "#00000000", "encoding": {"color": {"field": "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str", "legend": null, "type": "nominal"}, "tooltip": [{"field": "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str", "type": "nominal"}, {"field": "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432", "type": "quantitative"}], "x": {"field": "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str", "sort": null, "title": "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432", "type": "nominal"}, "y": {"field": "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432", "title": "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432", "type": "quantitative"}}, "height": 400, "padding": 50, "title": "\u0420\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043f\u043e \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438: SUPER", "width": 600, "$schema": "https://vega.github.io/schema/vega-lite/v6.1.0.json", "datasets": {"data-6a3e30f72b49598ac7803a03e6e1a4bf": [{"\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432": 0, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432": 115768, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str": "0"}, {"\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432": 1, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432": 2281, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str": "1"}, {"\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432": 2, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432": 129, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str": "2"}, {"\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432": 3, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432": 9, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str": "3"}, {"\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432": 4, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432": 2, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str": "4"}]}};
var embedOpt = {"mode": "vega-lite"};
function showError(el, error){
el.innerHTML = ('<div style="color:red;">'
+ '<p>JavaScript Error: ' + error.message + '</p>'
+ "<p>This usually means there's a typo in your chart specification. "
+ "See the javascript console for the full traceback.</p>"
+ '</div>');
throw error;
}
const el = document.getElementById('vis');
vegaEmbed("#vis", spec, embedOpt)
.catch(error => showError(el, error));
})(vegaEmbed);
</script>
</body>
</html>

View File

@@ -0,0 +1,42 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
#vis.vega-embed {
width: 100%;
display: flex;
}
#vis.vega-embed details,
#vis.vega-embed details summary {
position: relative;
}
</style>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vega@6"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vega-lite@6.1.0"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/vega-embed@7"></script>
</head>
<body>
<div id="vis"></div>
<script>
(function(vegaEmbed) {
var spec = {"usermeta": {"embedOptions": {"theme": "dark"}}, "config": {"view": {"continuousWidth": 300, "continuousHeight": 300}, "axis": {"grid": true, "labelFont": "Segoe UI Variable", "labelFontSize": 16, "labelFontWeight": 400, "titleFont": "Segoe UI Variable", "titleFontSize": 18, "titleFontWeight": 600}, "title": {"anchor": "middle", "font": "Segoe UI Variable", "fontSize": 20, "fontWeight": 600}}, "data": {"name": "data-c399e6589132909c5df1d6122ea515c8"}, "mark": {"type": "bar", "cornerRadius": 6, "width": 35}, "background": "#00000000", "encoding": {"color": {"field": "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str", "legend": null, "type": "nominal"}, "tooltip": [{"field": "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str", "type": "nominal"}, {"field": "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432", "type": "quantitative"}], "x": {"field": "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str", "sort": null, "title": "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432", "type": "nominal"}, "y": {"field": "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432", "title": "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432", "type": "quantitative"}}, "height": 400, "padding": 50, "title": "\u0420\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043f\u043e \u043a\u0430\u0442\u0435\u0433\u043e\u0440\u0438\u0438: TRANSPORT", "width": 600, "$schema": "https://vega.github.io/schema/vega-lite/v6.1.0.json", "datasets": {"data-c399e6589132909c5df1d6122ea515c8": [{"\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432": 0, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432": 112318, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str": "0"}, {"\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432": 1, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432": 5516, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str": "1"}, {"\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432": 2, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432": 311, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str": "2"}, {"\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432": 3, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432": 35, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str": "3"}, {"\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432": 4, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432": 8, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str": "4"}, {"\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432": 5, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432": 1, "\u041a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0437\u0430\u043a\u0430\u0437\u043e\u0432_str": "5"}]}};
var embedOpt = {"mode": "vega-lite"};
function showError(el, error){
el.innerHTML = ('<div style="color:red;">'
+ '<p>JavaScript Error: ' + error.message + '</p>'
+ "<p>This usually means there's a typo in your chart specification. "
+ "See the javascript console for the full traceback.</p>"
+ '</div>');
throw error;
}
const el = document.getElementById('vis');
vegaEmbed("#vis", spec, embedOpt)
.catch(error => showError(el, error));
})(vegaEmbed);
</script>
</body>
</html>