/
AlexShe23
/
ShestakovTableDataset
Обзор
Документация
Войти
/
AlexShe23
/
ShestakovTableDataset
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
pyplot_visualisation.py
206 строк
9 KB
AlexShe23
create: categorical_to_numerical.py, Diagrams.py, DiagramsModified.py, filtration.py, heatmap.py, new_categoria.py, noise.py, pyplot_visualisation.py, SeabornDiagrams.py
31 май 2026, 17:36
Верифицирован
31 май 2026, 17:36
3d651da
Код
Авторство
О чём код?
import numpy as np import pandas as pd import matplotlib.pyplot as plt import matplotlib.colors as mcolors from mpl_toolkits.mplot3d import Axes3D # noqa: F401 # ── Попытка подключить mplcursors (опционально) ─────────────────────────────── try: import mplcursors HAS_CURSORS = True except ImportError: HAS_CURSORS = False print("Подсказки при наведении недоступны. Установите: pip install mplcursors") # ── Загрузка данных ──────────────────────────────────────────────────────────── df = pd.read_csv("/Users/xyander23/PycharmProjects/PythonProject/uniproject.csv") att = df["attendance_percentage"] exer = df["exercise_frequency"].astype(int) score = df["exam_score"] # Цветовая карта: 7 групп упражнений CMAP = plt.get_cmap("RdYlGn", 7) COLORS = [CMAP(i) for i in range(7)] EX_LABELS = [f"{i} дн/нед" for i in range(7)] # ══════════════════════════════════════════════════════════════════════════════ # Холст: 2 строки × 3 колонки; правая колонка — 3D на всю высоту # ══════════════════════════════════════════════════════════════════════════════ fig = plt.figure(figsize=(18, 11)) fig.canvas.manager.set_window_title("Анализ успеваемости студентов") fig.suptitle( "Посещаемость занятий · Частота упражнений · Итоговый балл", fontsize=17, fontweight="bold", y=0.98 ) gs = fig.add_gridspec(2, 3, hspace=0.42, wspace=0.35) ax1 = fig.add_subplot(gs[0, 0]) ax2 = fig.add_subplot(gs[0, 1]) ax3 = fig.add_subplot(gs[1, 0]) ax4 = fig.add_subplot(gs[1, 1]) ax5 = fig.add_subplot(gs[:, 2], projection="3d") # ── 1. Scatter 2D: посещаемость vs балл ─────────────────────────────────────── sc = ax1.scatter( att, score, c=exer, cmap="RdYlGn", vmin=0, vmax=6, alpha=0.5, s=22, linewidths=0, picker=True, ) cbar = fig.colorbar(sc, ax=ax1, pad=0.02, shrink=0.85) cbar.set_label("Упражнения (дн/нед)", fontsize=9) cbar.set_ticks(range(7)) z = np.polyfit(att, score, 1) x_line = np.linspace(att.min(), att.max(), 200) ax1.plot(x_line, np.poly1d(z)(x_line), color="#C44E52", linewidth=2, linestyle="--", label=f"Тренд (r = {att.corr(score):.2f})") ax1.set_xlabel("Посещаемость (%)", fontsize=10) ax1.set_ylabel("Балл экзамена", fontsize=10) ax1.set_title("Посещаемость vs Балл", fontsize=11, fontweight="bold") ax1.legend(fontsize=9) ax1.grid(alpha=0.25) ax1.spines[["top", "right"]].set_visible(False) # Hover-подсказки для scatter 2D if HAS_CURSORS: cursor = mplcursors.cursor(sc, hover=True) @cursor.connect("add") def on_add(sel): idx = sel.index sel.annotation.set_text( f"Посещаемость: {att.iloc[idx]:.1f}%\n" f"Балл: {score.iloc[idx]:.1f}\n" f"Упражнения: {exer.iloc[idx]} дн/нед" ) sel.annotation.get_bbox_patch().set( boxstyle="round,pad=0.4", fc="#1e2333", alpha=0.88 ) sel.annotation.set_color("white") # ── 2. Boxplot: балл по группам упражнений ──────────────────────────────────── groups = [score[exer == i].values for i in range(7)] bp = ax2.boxplot( groups, patch_artist=True, medianprops=dict(color="black", linewidth=2), whiskerprops=dict(linewidth=1.2), capprops=dict(linewidth=1.2), flierprops=dict(marker="o", markersize=3.5, alpha=0.35), widths=0.55, ) for patch, color in zip(bp["boxes"], COLORS): patch.set_facecolor(color) patch.set_alpha(0.78) ax2.set_xticks(range(1, 8)) ax2.set_xticklabels(EX_LABELS, fontsize=8, rotation=25) ax2.set_xlabel("Частота упражнений", fontsize=10) ax2.set_ylabel("Балл экзамена", fontsize=10) ax2.set_title("Балл по группам упражнений", fontsize=11, fontweight="bold") ax2.grid(axis="y", alpha=0.25) ax2.spines[["top", "right"]].set_visible(False) # ── 3. Гистограмма: посещаемость ────────────────────────────────────────────── n_hist, bins, patches_h = ax3.hist( att, bins=20, edgecolor="white", alpha=0.88 ) norm_att = mcolors.Normalize(vmin=bins.min(), vmax=bins.max()) cmap_att = plt.get_cmap("Blues") for patch, left in zip(patches_h, bins[:-1]): patch.set_facecolor(cmap_att(norm_att(left))) ax3.axvline(att.mean(), color="#DD8452", linewidth=2, linestyle="--", label=f"Среднее = {att.mean():.1f}%") ax3.axvline(att.median(), color="#55A868", linewidth=2, linestyle=":", label=f"Медиана = {att.median():.1f}%") def on_hist_click(event): if event.inaxes != ax3: return for i, (patch, left) in enumerate(zip(patches_h, bins[:-1])): if patch.contains(event)[0]: right = bins[i + 1] ax3.set_title( f"Посещаемость {left:.1f}–{right:.1f}% → " f"{int(n_hist[i])} студентов", fontsize=10, fontweight="bold", color="#4C72B0" ) fig.canvas.draw_idle() break fig.canvas.mpl_connect("button_press_event", on_hist_click) ax3.set_xlabel("Посещаемость (%)", fontsize=10) ax3.set_ylabel("Количество студентов", fontsize=10) ax3.set_title("Распределение посещаемости", fontsize=11, fontweight="bold") ax3.legend(fontsize=9) ax3.grid(axis="y", alpha=0.25) ax3.spines[["top", "right"]].set_visible(False) # ── 4. Столбчатая: средний балл по группам с CI ─────────────────────────────── means = [score[exer == i].mean() for i in range(7)] stds = [score[exer == i].std() for i in range(7)] ns = [score[exer == i].count()for i in range(7)] cis = [1.96 * s / np.sqrt(n_i) for s, n_i in zip(stds, ns)] bars = ax4.bar( range(7), means, color=COLORS, edgecolor="white", linewidth=0.5, yerr=cis, capsize=5, error_kw=dict(elinewidth=1.4, ecolor="gray", capthick=1.4), width=0.65, ) for bar, mean in zip(bars, means): ax4.text( bar.get_x() + bar.get_width() / 2, bar.get_height() + 1.5, f"{mean:.1f}", ha="center", va="bottom", fontsize=9, fontweight="bold" ) def on_bar_click(event): if event.inaxes != ax4: return for i, bar in enumerate(bars): if bar.contains(event)[0]: ax4.set_title( f"Упражнения {i} дн/нед | " f"Средний балл: {means[i]:.1f} | " f"Студентов: {ns[i]}", fontsize=9, fontweight="bold", color="#55A868" ) fig.canvas.draw_idle() break fig.canvas.mpl_connect("button_press_event", on_bar_click) ax4.set_xticks(range(7)) ax4.set_xticklabels(EX_LABELS, fontsize=8, rotation=25) ax4.set_xlabel("Частота упражнений", fontsize=10) ax4.set_ylabel("Средний балл", fontsize=10) ax4.set_ylim(0, max(means) * 1.18) ax4.set_title("Средний балл по группам (95% ДИ)", fontsize=11, fontweight="bold") ax4.grid(axis="y", alpha=0.25) ax4.spines[["top", "right"]].set_visible(False) # ── 5. Scatter 3D: все три признака ─────────────────────────────────────────── sc3 = ax5.scatter( att, exer, score, c=score, cmap="RdYlGn", vmin=score.min(), vmax=score.max(), alpha=0.5, s=16, ) fig.colorbar(sc3, ax=ax5, pad=0.08, shrink=0.6, label="Балл экзамена") ax5.set_xlabel("Посещаемость (%)", fontsize=9, labelpad=8) ax5.set_ylabel("Упражнения", fontsize=9, labelpad=8) ax5.set_zlabel("Балл", fontsize=9, labelpad=8) ax5.set_title("3D: все три признака\n(зажмите ЛКМ для поворота)", fontsize=10, fontweight="bold", pad=12) ax5.view_init(elev=22, azim=130) ax5.grid(True, alpha=0.2) # ── Показ окна ──────────────────────────────────────────────────────────────── plt.show()