آموزش Seaborn؛ مصورسازی آماری و رسم نمودار حرفهای با پایتون
در این آموزش جامع Seaborn، رسم نمودارهای آماری، Heatmap، Pairplot، Box Plot، بررسی توزیع و همبستگی، ساخت گزارش تصویری و ترکیب تحلیل داده پایتون با هوش مصنوعی درواره را عملی یاد میگیرید.
رسم نمودار فقط تبدیل چند عدد به خط و رنگ نیست. یک نمودار مناسب باید بتواند توزیع داده، رابطه متغیرها، اختلاف گروهها، دادههای پرت و الگوهای پنهان را به شکلی قابل فهم نمایش دهد.
کتابخانه Seaborn یکی از محبوبترین ابزارهای مصورسازی آماری در پایتون است. این کتابخانه روی Matplotlib ساخته شده و ارتباط بسیار خوبی با DataFrameهای کتابخانه Pandas دارد. به همین دلیل میتوان با کد کمتر، نمودارهایی خوانا و مناسب تحلیل اکتشافی داده ایجاد کرد.
در این آموزش جامع یاد میگیرید:
- Seaborn چیست و چه تفاوتی با Matplotlib دارد
- چگونه Seaborn را نصب و پیکربندی کنید
- داده را با ساختار مناسب به نمودار بدهید
- نمودارهای خطی، پراکندگی، هیستوگرام و KDE بسازید
- دادههای دستهای را با Bar Plot، Box Plot و Violin Plot بررسی کنید
- ماتریس همبستگی را با Heatmap نمایش دهید
- با Pairplot و Jointplot چند متغیر را همزمان تحلیل کنید
- چند نمودار را براساس گروههای مختلف بسازید
- متن فارسی را در نمودار نمایش دهید
- یک پروژه واقعی تحلیل فروش را اجرا کنید
- خلاصه آماری را برای تحلیل متنی به API درواره بفرستید
Seaborn چیست؟
Seaborn یک کتابخانه پایتون برای مصورسازی آماری دادههاست. براساس مستندات رسمی Seaborn، این کتابخانه روی Matplotlib ساخته شده و یک رابط سطح بالاتر برای ایجاد نمودارهای آماری خوانا و informative ارائه میدهد.
Seaborn بهطور خاص برای کار با دادههای جدولی مناسب است. کافی است یک DataFrame و نام ستونهای موردنظر را مشخص کنید تا کتابخانه بسیاری از جزئیات مربوط به گروهبندی، رنگ، Legend و تخمین آماری را مدیریت کند.
کاربردهای متداول Seaborn عبارتاند از:
- تحلیل اکتشافی داده یا EDA
- بررسی توزیع متغیرهای عددی
- مقایسه داده میان گروهها
- مشاهده رابطه میان دو یا چند متغیر
- بررسی همبستگی ستونها
- شناسایی دادههای پرت
- نمایش نتیجه آزمایشها
- تحلیل رفتار کاربران
- بررسی دادههای فروش و بازاریابی
- ارزیابی اولیه دادههای یادگیری ماشین
تفاوت Seaborn و Matplotlib چیست؟
Seaborn جایگزین کامل Matplotlib نیست. این دو کتابخانه معمولاً در کنار یکدیگر استفاده میشوند.
| ویژگی | Seaborn | Matplotlib |
|---|---|---|
| سطح رابط | سطح بالا | سطح پایینتر و دقیقتر |
| تمرکز اصلی | نمودارهای آماری | رسم عمومی و کنترل جزئیات |
| ارتباط با Pandas | بسیار خوب | خوب |
| ظاهر پیشفرض | آمادهتر و حرفهایتر | سادهتر |
گروهبندی با hue | داخلی و آسان | معمولاً نیازمند کدنویسی بیشتر |
| نمودار توزیع | بسیار مناسب | امکانات پایه |
| Heatmap و Pairplot | آماده | نیازمند پیادهسازی بیشتر |
| کنترل جزئیات | خوب | بسیار زیاد |
| خروجی و ذخیرهسازی | با زیرساخت Matplotlib | مستقیم |
در عمل، Seaborn نمودار اصلی را میسازد و Matplotlib برای تنظیم عنوان، محور، اندازه، Annotation و ذخیره خروجی استفاده میشود.
برای مثال:
import seaborn as sns
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(10, 5))
sns.scatterplot(
data=df,
x="advertising_cost",
y="sales",
ax=ax
)
ax.set_title("Advertising Cost vs Sales")
plt.show()
نصب Seaborn
ابتدا یک محیط مجازی بسازید:
python -m venv .venv
فعالسازی در ویندوز:
.venv\Scripts\activate
فعالسازی در Linux یا macOS:
source .venv/bin/activate
نصب Seaborn:
python -m pip install seaborn
دستور نصب عادی، وابستگیهای اصلی مانند Pandas، NumPy و Matplotlib را نیز در صورت نیاز نصب میکند. برای برخی قابلیتهای آماری پیشرفته میتوانید بستههای اختیاری را نصب کنید:
python -m pip install "seaborn[stats]"
برای این مقاله بهتر است بستههای زیر را داشته باشید:
python -m pip install seaborn pandas numpy matplotlib scipy
بررسی نسخه نصبشده:
python -c "import seaborn as sns; print(sns.__version__)"
واردکردن Seaborn و تنظیم Theme
قرارداد متداول برای واردکردن Seaborn استفاده از نام sns است:
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
برای فعالکردن Theme پیشفرض:
sns.set_theme()
یک تنظیم مناسب برای بیشتر نمودارهای تحلیلی:
sns.set_theme(
style="whitegrid",
context="notebook",
palette="deep"
)
پارامترها:
styleظاهر پسزمینه و Grid را تعیین میکندcontextاندازه نسبی متن و عناصر نمودار را تنظیم میکندpaletteمجموعه رنگهای پیشفرض را مشخص میکند
اولین نمودار با Seaborn
ابتدا یک DataFrame ساده میسازیم:
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
df = pd.DataFrame({
"advertising_cost": [10, 15, 18, 25, 30, 38, 45, 55, 65, 80],
"sales": [32, 40, 43, 58, 66, 74, 91, 105, 118, 145],
"channel": [
"Search", "Social", "Search", "Social", "Search",
"Social", "Search", "Social", "Search", "Social"
]
})
sns.set_theme(style="whitegrid")
fig, ax = plt.subplots(
figsize=(10, 5),
layout="constrained"
)
sns.scatterplot(
data=df,
x="advertising_cost",
y="sales",
hue="channel",
s=100,
ax=ax
)
ax.set_title("Advertising Cost vs Sales")
ax.set_xlabel("Advertising Cost")
ax.set_ylabel("Sales")
plt.show()
پارامتر hue دادهها را براساس یک ستون دستهای رنگآمیزی میکند و Legend را نیز بهطور خودکار میسازد.
ساختار Long-form و Wide-form در Seaborn
Seaborn میتواند ساختارهای مختلف داده را دریافت کند، اما در بیشتر پروژهها قالب Long-form انتخاب مناسبتری است.
داده Wide-form
date mobile laptop tablet
2026-01-01 120 90 45
2026-01-02 135 82 51
داده Long-form
date category sales
2026-01-01 mobile 120
2026-01-01 laptop 90
2026-01-01 tablet 45
2026-01-02 mobile 135
ساختار Long-form مشخص میکند:
- هر ردیف یک Observation است
- هر ستون یک Variable است
- هر سلول یک مقدار دارد
این قالب استفاده از hue، style، size، col و row را آسان میکند.
تبدیل داده Wide به Long با Pandas:
long_df = wide_df.melt(
id_vars="date",
var_name="category",
value_name="sales"
)
دو خانواده اصلی توابع Seaborn
توابع Seaborn را میتوان از نظر سطح مدیریت Figure به دو گروه تقسیم کرد.
Axes-level Functions
این توابع نمودار را داخل یک Axes مشخص میسازند:
scatterplotlineplothistplotkdeplotbarplotcountplotboxplotviolinplotheatmap
مثال:
fig, ax = plt.subplots()
sns.histplot(
data=df,
x="sales",
ax=ax
)
این روش برای ساخت داشبورد با plt.subplots() مناسب است.
Figure-level Functions
این توابع کل Figure و شبکه نمودارها را مدیریت میکنند:
relplotdisplotcatplotlmplotjointplotpairplot
مثال:
grid = sns.relplot(
data=df,
x="advertising_cost",
y="sales",
col="channel"
)
خروجی relplot یک Axes معمولی نیست، بلکه معمولاً یک FacetGrid است.
برای تنظیم عنوان:
grid.figure.suptitle(
"Sales by Advertising Channel",
y=1.03
)
این تفاوت هنگام شخصیسازی نمودار و ترکیب آن با Subplotها اهمیت زیادی دارد.
رسم Scatter Plot
Scatter Plot برای بررسی رابطه دو متغیر عددی استفاده میشود.
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
rng = np.random.default_rng(42)
rows = 200
df = pd.DataFrame({
"advertising_cost": rng.integers(10, 100, rows),
"conversion_rate": rng.uniform(0.01, 0.12, rows),
"channel": rng.choice(
["Search", "Social", "Referral"],
rows
)
})
df["sales"] = (
df["advertising_cost"] * 2.2
+ df["conversion_rate"] * 600
+ rng.normal(0, 18, rows)
)
fig, ax = plt.subplots(
figsize=(11, 6),
layout="constrained"
)
sns.scatterplot(
data=df,
x="advertising_cost",
y="sales",
hue="channel",
style="channel",
size="conversion_rate",
sizes=(40, 220),
alpha=0.75,
ax=ax
)
ax.set_title("Advertising Performance")
ax.set_xlabel("Advertising Cost")
ax.set_ylabel("Sales")
plt.show()
در این نمودار چهار متغیر نمایش داده میشوند:
- محور X: هزینه تبلیغات
- محور Y: فروش
- رنگ: کانال
- اندازه نقطه: نرخ تبدیل
افزودن متغیرهای زیاد همیشه مفید نیست. اگر نمودار به توضیح طولانی نیاز دارد، احتمالاً باید آن را به چند نمودار سادهتر تقسیم کنید.
رسم Line Plot
برای نمایش تغییرات در طول زمان از lineplot استفاده کنید:
dates = pd.date_range(
"2026-01-01",
periods=30,
freq="D"
)
daily_df = pd.DataFrame({
"date": np.tile(dates, 2),
"visits": np.concatenate([
rng.integers(800, 1400, 30),
rng.integers(500, 1100, 30)
]),
"source": ["Organic"] * 30 + ["Paid"] * 30
})
fig, ax = plt.subplots(
figsize=(12, 5),
layout="constrained"
)
sns.lineplot(
data=daily_df,
x="date",
y="visits",
hue="source",
marker="o",
ax=ax
)
ax.set_title("Daily Website Visits")
ax.set_xlabel("Date")
ax.set_ylabel("Visits")
ax.tick_params(axis="x", rotation=30)
plt.show()
اگر برای هر تاریخ چند ردیف وجود داشته باشد، lineplot ممکن است بهطور پیشفرض مقدار مرکزی و Error Bar را محاسبه کند. اگر میخواهید دقیقاً داده از قبل تجمیعشده نمایش داده شود، ابتدا آن را با Pandas گروهبندی کنید.
daily = (
raw_df.groupby(
["date", "source"],
as_index=False
)["visits"].sum()
)
سپس daily را رسم کنید.
استفاده از Facet برای مقایسه گروهها
برای ساخت یک نمودار جداگانه برای هر گروه:
grid = sns.relplot(
data=daily_df,
x="date",
y="visits",
col="source",
kind="line",
height=4,
aspect=1.3
)
grid.set_axis_labels("Date", "Visits")
grid.set_titles("{col_name}")
grid.figure.suptitle(
"Traffic by Source",
y=1.04
)
for ax in grid.axes.flat:
ax.tick_params(axis="x", rotation=30)
plt.show()
Facet زمانی مفید است که قرار دادن تمام گروهها در یک نمودار باعث شلوغی شود.
رسم Histogram
هیستوگرام توزیع یک متغیر عددی را نمایش میدهد:
response_time = rng.lognormal(
mean=5.5,
sigma=0.35,
size=1500
)
response_df = pd.DataFrame({
"response_time": response_time
})
fig, ax = plt.subplots(
figsize=(10, 5),
layout="constrained"
)
sns.histplot(
data=response_df,
x="response_time",
bins=35,
color="#6C4DF6",
edgecolor="white",
ax=ax
)
ax.set_title("API Response Time Distribution")
ax.set_xlabel("Response Time (ms)")
ax.set_ylabel("Count")
plt.show()
افزودن KDE به هیستوگرام
sns.histplot(
data=response_df,
x="response_time",
bins=35,
kde=True,
color="#6C4DF6",
ax=ax
)
KDE یک تخمین هموار از چگالی توزیع است. شکل KDE به پهنای باند وابسته است و نباید آن را جایگزین خود داده یا یک احتمال قطعی در نظر گرفت.
مقایسه توزیع چند گروه
latency_df = pd.DataFrame({
"latency": np.concatenate([
rng.normal(320, 45, 400),
rng.normal(410, 70, 400)
]),
"model": (
["Model A"] * 400
+ ["Model B"] * 400
)
})
fig, ax = plt.subplots(
figsize=(10, 5),
layout="constrained"
)
sns.histplot(
data=latency_df,
x="latency",
hue="model",
bins=30,
element="step",
stat="density",
common_norm=False,
alpha=0.35,
ax=ax
)
ax.set_title("Latency Distribution by Model")
ax.set_xlabel("Latency (ms)")
plt.show()
گزینه common_norm=False باعث میشود هر گروه بهصورت مستقل نرمالسازی شود. این گزینه برای مقایسه شکل توزیع گروههایی با تعداد نمونه متفاوت مفید است.
نمودار ECDF
ECDF نشان میدهد چه نسبتی از دادهها کمتر یا مساوی یک مقدار مشخص هستند.
fig, ax = plt.subplots(
figsize=(10, 5),
layout="constrained"
)
sns.ecdfplot(
data=latency_df,
x="latency",
hue="model",
ax=ax
)
ax.set_title("Latency ECDF")
ax.set_xlabel("Latency (ms)")
ax.set_ylabel("Proportion")
plt.show()
برای مثال، با ECDF میتوانید بهصورت تصویری بررسی کنید چه درصدی از درخواستها زیر یک زمان پاسخ مشخص قرار دارند.
رسم Count Plot
countplot تعداد رکوردهای هر دسته را نمایش میدهد:
orders_df = pd.DataFrame({
"status": rng.choice(
["Completed", "Cancelled", "Pending"],
size=1000,
p=[0.76, 0.09, 0.15]
)
})
fig, ax = plt.subplots(
figsize=(8, 5),
layout="constrained"
)
sns.countplot(
data=orders_df,
x="status",
hue="status",
legend=False,
palette="deep",
ax=ax
)
ax.set_title("Order Status Count")
ax.set_xlabel("Status")
ax.set_ylabel("Number of Orders")
for container in ax.containers:
ax.bar_label(container, padding=3)
plt.show()
تفاوت countplot و barplot مهم است:
countplotتعداد ردیفها را میشماردbarplotیک مقدار آماری را برای متغیر عددی محاسبه میکند
رسم Bar Plot
مثال زیر میانگین مبلغ سفارش را در هر کانال نشان میدهد:
order_values = pd.DataFrame({
"channel": rng.choice(
["Search", "Social", "Referral"],
600
),
"order_value": rng.lognormal(
mean=15.2,
sigma=0.45,
size=600
)
})
fig, ax = plt.subplots(
figsize=(9, 5),
layout="constrained"
)
sns.barplot(
data=order_values,
x="channel",
y="order_value",
hue="channel",
legend=False,
estimator="mean",
errorbar=("ci", 95),
ax=ax
)
ax.set_title("Average Order Value by Channel")
ax.set_xlabel("Channel")
ax.set_ylabel("Average Order Value")
plt.show()
نکته مهم درباره Bar Plot
ارتفاع میله در sns.barplot بهطور پیشفرض مجموع مقادیر نیست. این تابع معمولاً یک تخمین آماری مانند میانگین را نمایش میدهد.
اگر هدف نمایش مجموع فروش است، ابتدا داده را تجمیع کنید:
channel_sales = (
sales_df.groupby(
"channel",
as_index=False
)["revenue"].sum()
)
سپس نمودار را بدون تفسیر آماری اضافی رسم کنید:
sns.barplot(
data=channel_sales,
x="channel",
y="revenue",
hue="channel",
legend=False,
errorbar=None
)
این کار از اشتباه رایج میان «میانگین فروش» و «مجموع فروش» جلوگیری میکند.
رسم Box Plot
Box Plot برای نمایش میانه، دامنه بین چارکی و نقاط پرت مناسب است:
fig, ax = plt.subplots(
figsize=(10, 5),
layout="constrained"
)
sns.boxplot(
data=order_values,
x="channel",
y="order_value",
hue="channel",
legend=False,
palette="Set2",
ax=ax
)
ax.set_title("Order Value Distribution by Channel")
ax.set_xlabel("Channel")
ax.set_ylabel("Order Value")
plt.show()
Box Plot برای مقایسه گروهها معمولاً اطلاعات بیشتری از یک نمودار میانگین ارائه میدهد؛ زیرا شکل کلی توزیع را پنهان نمیکند.
نقطه خارج از Whisker الزاماً داده اشتباه نیست. ابتدا باید علت مقدار غیرعادی بررسی شود.
رسم Violin Plot
Violin Plot ترکیبی از نمایش توزیع و خلاصه آماری است:
fig, ax = plt.subplots(
figsize=(10, 5),
layout="constrained"
)
sns.violinplot(
data=order_values,
x="channel",
y="order_value",
hue="channel",
legend=False,
inner="quart",
cut=0,
palette="Set2",
ax=ax
)
ax.set_title("Order Value Distribution")
ax.set_xlabel("Channel")
ax.set_ylabel("Order Value")
plt.show()
پارامتر cut=0 مانع امتداد تخمین KDE فراتر از حداقل و حداکثر داده مشاهدهشده میشود.
Violin Plot برای حجم نمونه بسیار کم میتواند تصور اشتباهی از شکل توزیع ایجاد کند. در این شرایط بهتر است نقاط خام را نیز نمایش دهید.
ترکیب Box Plot و Strip Plot
برای مشاهده خلاصه آماری و نقاط واقعی:
fig, ax = plt.subplots(
figsize=(10, 5),
layout="constrained"
)
sns.boxplot(
data=order_values,
x="channel",
y="order_value",
color="#D9D2FF",
showfliers=False,
ax=ax
)
sns.stripplot(
data=order_values.sample(
n=min(250, len(order_values)),
random_state=42
),
x="channel",
y="order_value",
color="#35219A",
alpha=0.45,
jitter=0.22,
size=4,
ax=ax
)
ax.set_title("Order Value by Channel")
plt.show()
در دادههای بزرگ بهتر است برای لایه نقاط نمونهبرداری کنید؛ زیرا رسم تمام نقاط نمودار را شلوغ میکند.
رسم Regression Plot
برای مشاهده یک خط رگرسیون روی رابطه دو متغیر:
fig, ax = plt.subplots(
figsize=(9, 5),
layout="constrained"
)
sns.regplot(
data=df,
x="advertising_cost",
y="sales",
scatter_kws={
"alpha": 0.55,
"s": 55
},
line_kws={
"color": "#EF476F",
"linewidth": 2.5
},
ax=ax
)
ax.set_title("Advertising Cost and Sales Trend")
plt.show()
خط رگرسیون فقط یک الگوی آماری را نشان میدهد. مشاهده رابطه یا همبستگی بهتنهایی علت و معلول را ثابت نمیکند.
برای مقایسه رگرسیون گروهها:
grid = sns.lmplot(
data=df,
x="advertising_cost",
y="sales",
hue="channel",
height=5,
aspect=1.5
)
grid.set_axis_labels(
"Advertising Cost",
"Sales"
)
plt.show()
رسم Heatmap همبستگی
Heatmap یکی از پرکاربردترین نمودارهای Seaborn در تحلیل داده و Machine Learning است.
ابتدا ماتریس همبستگی را محاسبه کنید:
numeric_df = pd.DataFrame({
"advertising_cost": rng.normal(50, 15, 500),
"site_visits": rng.normal(5000, 1100, 500),
"conversion_rate": rng.uniform(0.01, 0.10, 500),
"average_order_value": rng.normal(4_500_000, 900_000, 500)
})
numeric_df["revenue"] = (
numeric_df["site_visits"]
* numeric_df["conversion_rate"]
* numeric_df["average_order_value"]
)
correlation = numeric_df.corr(numeric_only=True)
fig, ax = plt.subplots(
figsize=(10, 7),
layout="constrained"
)
sns.heatmap(
correlation,
annot=True,
fmt=".2f",
cmap="vlag",
center=0,
square=True,
linewidths=0.5,
ax=ax
)
ax.set_title("Correlation Matrix")
plt.show()
پارامترهای مهم:
annot=True: نمایش عدد داخل سلولfmt=".2f": نمایش دو رقم اعشارcenter=0: قرار دادن صفر در مرکز پالت رنگsquare=True: مربعشدن سلولهاlinewidths: فاصله بصری میان سلولها
جلوگیری از نمایش نیمه تکراری ماتریس
ماتریس همبستگی متقارن است. میتوان نیمه بالایی را مخفی کرد:
mask = np.triu(
np.ones_like(
correlation,
dtype=bool
)
)
fig, ax = plt.subplots(
figsize=(10, 7),
layout="constrained"
)
sns.heatmap(
correlation,
mask=mask,
annot=True,
fmt=".2f",
cmap="vlag",
center=0,
ax=ax
)
plt.show()
تفسیر همبستگی
ضریب همبستگی معمولاً در بازه منفی یک تا مثبت یک قرار دارد:
- نزدیک مثبت یک: رابطه خطی مثبت
- نزدیک منفی یک: رابطه خطی منفی
- نزدیک صفر: نبود رابطه خطی قوی
همبستگی پایین به معنای نبود هر نوع رابطه نیست. ممکن است رابطه غیرخطی باشد. همچنین همبستگی بالا بهتنهایی رابطه علت و معلولی را اثبات نمیکند.
رسم Pairplot
Pairplot رابطه جفتی متغیرهای عددی را نشان میدهد:
pair_df = numeric_df.copy()
pair_df["segment"] = rng.choice(
["New", "Returning"],
size=len(pair_df)
)
sns.pairplot(
data=pair_df.sample(
n=300,
random_state=42
),
vars=[
"site_visits",
"conversion_rate",
"average_order_value",
"revenue"
],
hue="segment",
corner=True,
diag_kind="hist",
plot_kws={
"alpha": 0.55,
"s": 35
}
)
plt.show()
Pairplot با افزایش تعداد ستونها بسیار سنگین و شلوغ میشود. اگر ۲۰ ستون عددی داشته باشید، ساخت نمودار برای تمام ترکیبها مناسب نیست. ابتدا ستونهای مهم را انتخاب کنید.
رسم Jointplot
Jointplot رابطه دو متغیر و توزیع جداگانه هرکدام را در یک تصویر نشان میدهد:
grid = sns.jointplot(
data=numeric_df,
x="site_visits",
y="revenue",
kind="hex",
height=7,
color="#6C4DF6"
)
grid.figure.suptitle(
"Site Visits and Revenue",
y=1.02
)
plt.show()
kind="hex" برای دادههایی که نقاط زیادی روی هم قرار میگیرند مناسب است؛ زیرا تراکم را در سلولهای ششضلعی نمایش میدهد.
پالت رنگ در Seaborn
Seaborn چند نوع پالت اصلی دارد.
Qualitative Palette
برای دستههایی که ترتیب عددی ندارند:
sns.color_palette("deep")
sns.color_palette("Set2")
sns.color_palette("colorblind")
Sequential Palette
برای مقادیر کم تا زیاد:
sns.color_palette("viridis", as_cmap=True)
sns.color_palette("mako", as_cmap=True)
Diverging Palette
برای مقادیری که یک نقطه مرکزی مانند صفر دارند:
sns.color_palette("vlag", as_cmap=True)
sns.color_palette("coolwarm", as_cmap=True)
اصل انتخاب رنگ:
- دستهها: رنگهای متمایز
- شدت مقدار: پالت ترتیبی
- مقادیر مثبت و منفی: پالت دوطرفه
- مخاطب عمومی: پالت قابل تشخیص برای افراد دارای اختلال دید رنگ
برای بیشتر گزارشها، رنگ نباید تنها راه تشخیص گروهها باشد. در نمودار خطی میتوانید همزمان از style و Marker استفاده کنید.
شخصیسازی ظاهر نمودار
Theme عمومی:
sns.set_theme(
style="whitegrid",
context="talk",
palette="colorblind"
)
Styleهای متداول:
sns.set_style("white")
sns.set_style("whitegrid")
sns.set_style("dark")
sns.set_style("darkgrid")
sns.set_style("ticks")
حذف خطوط اضافه:
sns.despine()
تنظیم Scale عناصر برای گزارش یا ارائه:
sns.set_context("paper")
sns.set_context("notebook")
sns.set_context("talk")
sns.set_context("poster")
برای کنترل بیشتر از Matplotlib استفاده کنید:
fig, ax = plt.subplots(
figsize=(12, 6),
layout="constrained"
)
sns.lineplot(
data=daily_df,
x="date",
y="visits",
hue="source",
ax=ax
)
ax.set_title(
"Daily Traffic",
fontsize=18,
fontweight="bold"
)
ax.spines["top"].set_visible(False)
ax.spines["right"].set_visible(False)
ax.grid(axis="y", alpha=0.2)
plt.show()
نمایش متن فارسی در Seaborn
Seaborn برای نمایش متن از زیرساخت Matplotlib استفاده میکند. بنابراین در برخی محیطها، متن فارسی ممکن است جدا یا با جهت نادرست نمایش داده شود.
نصب وابستگیها:
python -m pip install arabic-reshaper python-bidi
تابع تبدیل متن:
import arabic_reshaper
from bidi.algorithm import get_display
def fa(text):
reshaped = arabic_reshaper.reshape(
str(text)
)
return get_display(reshaped)
مثال:
persian_df = pd.DataFrame({
"city": ["تهران", "شیراز", "تبریز", "مشهد"],
"sales": [820, 470, 390, 610]
})
persian_df["city_label"] = (
persian_df["city"].map(fa)
)
fig, ax = plt.subplots(
figsize=(9, 5),
layout="constrained"
)
sns.barplot(
data=persian_df,
x="city_label",
y="sales",
hue="city_label",
legend=False,
palette="Purples_d",
ax=ax
)
ax.set_title(fa("مقایسه فروش شهرها"))
ax.set_xlabel(fa("شهر"))
ax.set_ylabel(fa("میزان فروش"))
plt.show()
استفاده از فونت فارسی
اگر فایل Vazirmatn-Regular.ttf در پروژه موجود است:
from matplotlib.font_manager import FontProperties
persian_font = FontProperties(
fname="Vazirmatn-Regular.ttf"
)
ax.set_title(
fa("گزارش فروش"),
fontproperties=persian_font,
fontsize=17
)
for label in ax.get_xticklabels():
label.set_fontproperties(
persian_font
)
در سرور یا Docker بهتر است فایل فونت همراه پروژه باشد تا خروجی در تمام محیطها یکسان بماند.
پروژه عملی: تحلیل تصویری داده فروش آنلاین
در این پروژه یک مجموعه داده شبیهسازیشده برای فروشگاه آنلاین میسازیم و چند سؤال کاربردی را پاسخ میدهیم:
- روند فروش چگونه تغییر کرده است؟
- کدام کانال بیشترین درآمد را ایجاد میکند؟
- توزیع ارزش سفارش در کانالها چگونه است؟
- نرخ تبدیل با درآمد چه رابطهای دارد؟
- متغیرهای عددی چه همبستگیهایی دارند؟
مرحله اول: ساخت داده
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from matplotlib.ticker import FuncFormatter
rng = np.random.default_rng(42)
rows = 2500
dates = pd.date_range(
"2026-01-01",
periods=180,
freq="D"
)
channels = np.array([
"Organic",
"Paid Search",
"Social",
"Referral"
])
categories = np.array([
"Mobile",
"Laptop",
"Tablet",
"Accessories"
])
df = pd.DataFrame({
"date": rng.choice(dates, rows),
"channel": rng.choice(
channels,
rows,
p=[0.36, 0.28, 0.21, 0.15]
),
"category": rng.choice(
categories,
rows,
p=[0.30, 0.24, 0.16, 0.30]
),
"visits": rng.integers(
100,
1500,
rows
),
"conversion_rate": rng.uniform(
0.008,
0.095,
rows
),
"average_order_value": rng.integers(
1_500_000,
20_000_000,
rows
)
})
df["orders"] = np.maximum(
1,
np.round(
df["visits"]
* df["conversion_rate"]
)
).astype(int)
df["revenue"] = (
df["orders"]
* df["average_order_value"]
)
مرحله دوم: اعتبارسنجی داده
print(df.head())
print(df.info())
print(df.isna().sum())
print(df.duplicated().sum())
print(df.describe())
کنترل داده قبل از رسم اهمیت زیادی دارد. نمودار جذاب نمیتواند داده نامعتبر را اصلاح کند.
مرحله سوم: ساخت خلاصهها
daily = (
df.groupby("date", as_index=False)
.agg(
revenue=("revenue", "sum"),
orders=("orders", "sum"),
visits=("visits", "sum")
)
.sort_values("date")
)
channel_revenue = (
df.groupby("channel", as_index=False)
.agg(
revenue=("revenue", "sum"),
orders=("orders", "sum")
)
.sort_values(
"revenue",
ascending=False
)
)
مرحله چهارم: ساخت داشبورد
sns.set_theme(
style="whitegrid",
context="notebook",
palette="deep"
)
money_formatter = FuncFormatter(
lambda value, position:
f"{value / 1_000_000_000:.1f}B"
)
fig, axes = plt.subplots(
2,
2,
figsize=(16, 10),
layout="constrained"
)
fig.suptitle(
"E-commerce Performance Dashboard",
fontsize=20,
fontweight="bold"
)
sns.lineplot(
data=daily,
x="date",
y="revenue",
color="#6C4DF6",
linewidth=2.2,
ax=axes[0, 0]
)
axes[0, 0].set_title("Daily Revenue")
axes[0, 0].set_xlabel("Date")
axes[0, 0].set_ylabel("Revenue")
axes[0, 0].yaxis.set_major_formatter(
money_formatter
)
sns.barplot(
data=channel_revenue,
x="channel",
y="revenue",
hue="channel",
legend=False,
errorbar=None,
palette="viridis",
ax=axes[0, 1]
)
axes[0, 1].set_title(
"Total Revenue by Channel"
)
axes[0, 1].set_xlabel("Channel")
axes[0, 1].set_ylabel("Revenue")
axes[0, 1].yaxis.set_major_formatter(
money_formatter
)
axes[0, 1].tick_params(
axis="x",
rotation=15
)
plot_sample = df.sample(
n=min(900, len(df)),
random_state=42
)
sns.boxplot(
data=plot_sample,
x="channel",
y="average_order_value",
hue="channel",
legend=False,
palette="Set2",
ax=axes[1, 0]
)
axes[1, 0].set_title(
"Order Value Distribution"
)
axes[1, 0].set_xlabel("Channel")
axes[1, 0].set_ylabel(
"Average Order Value"
)
axes[1, 0].yaxis.set_major_formatter(
money_formatter
)
axes[1, 0].tick_params(
axis="x",
rotation=15
)
sns.scatterplot(
data=plot_sample,
x="conversion_rate",
y="revenue",
hue="channel",
alpha=0.65,
s=45,
ax=axes[1, 1]
)
axes[1, 1].set_title(
"Conversion Rate vs Revenue"
)
axes[1, 1].set_xlabel(
"Conversion Rate"
)
axes[1, 1].set_ylabel("Revenue")
axes[1, 1].yaxis.set_major_formatter(
money_formatter
)
for ax in axes.flat:
ax.grid(axis="y", alpha=0.2)
sns.despine(ax=ax)
fig.savefig(
"ecommerce_dashboard.png",
dpi=160,
bbox_inches="tight",
facecolor="white"
)
plt.show()
این پروژه یک فایل تصویری با نام ecommerce_dashboard.png تولید میکند.
افزودن Heatmap به پروژه فروش
numeric_columns = [
"visits",
"conversion_rate",
"orders",
"average_order_value",
"revenue"
]
correlation = (
df[numeric_columns]
.corr()
)
mask = np.triu(
np.ones_like(
correlation,
dtype=bool
)
)
fig, ax = plt.subplots(
figsize=(9, 7),
layout="constrained"
)
sns.heatmap(
correlation,
mask=mask,
annot=True,
fmt=".2f",
cmap="vlag",
center=0,
square=True,
linewidths=0.5,
ax=ax
)
ax.set_title(
"E-commerce Correlation Matrix"
)
fig.savefig(
"correlation_heatmap.png",
dpi=160,
bbox_inches="tight"
)
plt.show()
تفسیر Heatmap باید با منطق تولید داده و تعریف شاخصها همراه باشد. برای مثال، اگر درآمد مستقیماً از تعداد سفارش ضربدر ارزش سفارش ساخته شده باشد، مشاهده همبستگی میان این متغیرها تعجبآور نیست.
اتصال تحلیل Seaborn به هوش مصنوعی درواره
Seaborn نمودار را با استفاده از داده واقعی تولید میکند. هوش مصنوعی میتواند خلاصه آماری محاسبهشده را به یک گزارش قابل فهم تبدیل کند.
معماری پیشنهادی:
- خواندن داده با Pandas
- پاکسازی و اعتبارسنجی
- محاسبه شاخصها با کد
- ساخت نمودار با Seaborn
- ارسال خلاصه آماری به مدل
- تولید توضیح متنی براساس اعداد موجود
برای دسترسی API به مدلهای مختلف میتوانید در درواره ثبتنام کنید. فهرست مدلهای قابل استفاده و قیمت بهروز آنها در صفحه مدلهای درواره قرار دارد.
نگهداری API Key
در Linux یا macOS:
export DARVAREH_API_KEY="YOUR_DARVAREH_API_KEY"
در PowerShell:
$env:DARVAREH_API_KEY="YOUR_DARVAREH_API_KEY"
تولید خلاصه قطعی با Pandas
summary = {
"total_revenue": float(
df["revenue"].sum()
),
"total_orders": int(
df["orders"].sum()
),
"average_order_value": float(
df["average_order_value"].mean()
),
"median_order_value": float(
df["average_order_value"].median()
),
"average_conversion_rate": float(
df["conversion_rate"].mean()
),
"top_channel_by_revenue": str(
channel_revenue.iloc[0]["channel"]
),
"top_channel_revenue": float(
channel_revenue.iloc[0]["revenue"]
)
}
ارسال خلاصه به API درواره
import json
import os
import requests
response = requests.post(
"https://api.darvareh.ir/v1/chat/completions",
headers={
"Authorization": (
f"Bearer "
f"{os.environ['DARVAREH_API_KEY']}"
),
"Content-Type": "application/json"
},
json={
"model": "YOUR_MODEL_ID",
"messages": [
{
"role": "system",
"content": (
"تو یک دستیار تحلیل داده هستی. "
"فقط از اعداد ارائهشده استفاده کن. "
"هیچ عدد یا علت جدیدی اختراع نکن. "
"همبستگی را علت و معلول معرفی نکن."
)
},
{
"role": "user",
"content": (
"خلاصه زیر مربوط به عملکرد یک "
"فروشگاه آنلاین است. یک گزارش "
"فارسی شامل چهار یافته، سه پرسش "
"برای بررسی بیشتر و یک جمعبندی "
"کوتاه بنویس.\n\n"
+ json.dumps(
summary,
ensure_ascii=False
)
)
}
],
"temperature": 0.2
},
timeout=60
)
response.raise_for_status()
result = response.json()
print(
result["choices"][0]
["message"]
["content"]
)
چرا محاسبات را به مدل واگذار نکنیم؟
برای محاسبات دقیق بهتر است از Pandas و NumPy استفاده شود؛ زیرا:
- نتیجه قابل تکرار است
- نوع داده مشخص است
- خطای محاسباتی راحتتر بررسی میشود
- تست نوشتن برای کد ممکن است
- مصرف توکن کاهش پیدا میکند
- احتمال تولید عدد نادرست کمتر میشود
مدل زبانی را برای توضیح، نامگذاری، خلاصهسازی و پیشنهاد بررسیهای بعدی استفاده کنید.
استفاده از هوش مصنوعی برای پیشنهاد نمودار
میتوانید فقط Schema و هدف تحلیل را برای مدل ارسال کنید:
schema = {
"date": "تاریخ سفارش",
"channel": "کانال جذب",
"category": "دسته محصول",
"visits": "تعداد بازدید",
"conversion_rate": "نرخ تبدیل",
"orders": "تعداد سفارش",
"revenue": "درآمد"
}
پرامپت پیشنهادی:
برای این مجموعه داده، پنج نمودار مناسب برای تحلیل عملکرد فروشگاه پیشنهاد بده.
برای هر نمودار مشخص کن:
1. تابع مناسب Seaborn چیست
2. محور X و Y چه باشند
3. آیا hue لازم است
4. چه تجمیعی باید با Pandas انجام شود
5. نمودار چه پرسشی را پاسخ میدهد
6. چه خطای تفسیری ممکن است رخ دهد
هیچ عددی تولید نکن و فقط از ستونهای معرفیشده استفاده کن.
پس از دریافت پیشنهاد، کد را بررسی و روی داده واقعی اجرا کنید.
ساخت تابع قابل استفاده مجدد
from pathlib import Path
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
def create_category_boxplot(
df: pd.DataFrame,
category_column: str,
value_column: str,
output_path: str
) -> Path:
required = {
category_column,
value_column
}
missing = required - set(df.columns)
if missing:
raise ValueError(
f"Missing columns: {sorted(missing)}"
)
clean_df = df[
[category_column, value_column]
].copy()
clean_df[value_column] = pd.to_numeric(
clean_df[value_column],
errors="coerce"
)
clean_df = clean_df.dropna()
if clean_df.empty:
raise ValueError(
"No valid data to plot"
)
fig, ax = plt.subplots(
figsize=(11, 6),
layout="constrained"
)
sns.boxplot(
data=clean_df,
x=category_column,
y=value_column,
hue=category_column,
legend=False,
palette="Set2",
ax=ax
)
ax.set_title(
f"{value_column} by {category_column}"
)
ax.tick_params(
axis="x",
rotation=20
)
sns.despine(ax=ax)
path = Path(output_path)
path.parent.mkdir(
parents=True,
exist_ok=True
)
fig.savefig(
path,
dpi=160,
bbox_inches="tight",
facecolor="white"
)
plt.close(fig)
return path
استفاده:
chart_path = create_category_boxplot(
df=df,
category_column="channel",
value_column="average_order_value",
output_path="reports/order_value.png"
)
print(chart_path)
ذخیره نمودار Seaborn
چون Seaborn روی Matplotlib ساخته شده، ذخیره خروجی با fig.savefig انجام میشود:
fig.savefig(
"chart.png",
dpi=180,
bbox_inches="tight",
facecolor="white"
)
برای SVG:
fig.savefig(
"chart.svg",
bbox_inches="tight"
)
برای PDF:
fig.savefig(
"chart.pdf",
bbox_inches="tight"
)
در توابع Figure-level:
grid = sns.displot(
data=df,
x="revenue"
)
grid.savefig(
"revenue_distribution.png",
dpi=180,
bbox_inches="tight"
)
تولید نمودار Seaborn در سرور
در سرور بدون رابط گرافیکی، Backend را پیش از واردکردن Pyplot تنظیم کنید:
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import seaborn as sns
پس از ذخیره نمودار، Figure را ببندید:
plt.close(fig)
در پردازش دستهای، باز ماندن Figureها میتواند مصرف حافظه را افزایش دهد.
بهینهسازی Seaborn برای دادههای بزرگ
نمونهبرداری برای Scatter Plot
plot_df = df.sample(
n=min(20_000, len(df)),
random_state=42
)
تجمیع داده زمانی
daily = (
df.set_index("date")
.resample("D")["revenue"]
.sum()
.reset_index()
)
محدودکردن Pairplot
selected_columns = [
"visits",
"conversion_rate",
"orders",
"revenue"
]
sns.pairplot(
df[selected_columns].sample(
n=500,
random_state=42
)
)
استفاده محتاطانه از Swarm Plot
swarmplot برای داده کوچک بسیار مفید است، اما روی هزاران نقطه میتواند کند شود. برای داده بزرگ از stripplot با Alpha پایین یا نمونهبرداری استفاده کنید.
محاسبه خلاصه پیش از Bar Plot
اگر هدف نمایش مجموع یا شاخص دقیق است، ابتدا با Pandas محاسبه کنید و سپس خروجی کوچک را رسم کنید.
خطاهای رایج Seaborn
خطای نصب نبودن کتابخانه
ModuleNotFoundError: No module named 'seaborn'
راهحل:
python -m pip install seaborn
خطای پیدا نشدن ستون
ValueError: Could not interpret value
نام ستونها را بررسی کنید:
print(df.columns.tolist())
گاهی فاصله اضافی در نام ستون وجود دارد:
df.columns = df.columns.str.strip()
رسم نشدن نمودار
در اسکریپت محلی:
plt.show()
در سرور از savefig استفاده کنید.
دریافت خطا برای ax در توابع Figure-level
توابعی مانند relplot، displot و catplot کل Figure را مدیریت میکنند و معمولاً برای قرار گرفتن داخل یک Axes موجود طراحی نشدهاند.
برای Subplot از نسخه Axes-level استفاده کنید:
relplot←scatterplotیاlineplotdisplot←histplotیاkdeplotcatplot←boxplot،barplotیاcountplot
نمایش Error Bar ناخواسته
اگر داده از قبل تجمیع شده است:
sns.barplot(
data=summary_df,
x="channel",
y="revenue",
errorbar=None
)
نمایش اشتباه مجموع بهجای میانگین
barplot بهطور پیشفرض برای نمایش یک تخمین آماری طراحی شده است. برای مجموع، ابتدا groupby().sum() را اجرا کنید.
شلوغشدن Pairplot
تعداد ستونها و ردیفها را کاهش دهید و فقط متغیرهای مرتبط را انتخاب کنید.
جداشدن حروف فارسی
از arabic-reshaper، python-bidi و یک فونت دارای پشتیبانی فارسی استفاده کنید.
هشدار باز بودن Figureهای زیاد
پس از ذخیره:
plt.close(fig)
اشتباهات تحلیلی رایج
تفسیر همبستگی بهعنوان علت
Heatmap فقط شدت رابطه آماری را نشان میدهد و دلیل ایجاد رابطه را مشخص نمیکند.
استفاده از Bar Plot بدون شناخت Estimator
ارتفاع میله ممکن است میانگین باشد، نه مجموع. عنوان و محور باید نوع شاخص را واضح بیان کنند.
مقایسه گروههایی با حجم نمونه بسیار متفاوت
میانگین دو گروه بدون نمایش تعداد نمونه و پراکندگی میتواند گمراهکننده باشد.
استفاده از KDE برای داده کم
منحنی هموار ممکن است الگویی را نشان دهد که پشتیبانی کافی در داده خام ندارد.
حذف داده پرت فقط براساس Box Plot
داده پرت ممکن است یک تراکنش واقعی و مهم باشد. ابتدا منبع آن را بررسی کنید.
نمایش درصد بدون مخرج
عبارت «نرخ تبدیل ۱۰ درصد» بدون تعداد بازدید یا نمونه، اطلاعات کاملی ارائه نمیدهد.
استفاده از رنگ زیاد
رنگهای متعدد توجه خواننده را از سؤال اصلی دور میکنند. رنگ باید معنای مشخص داشته باشد.
چکلیست نمودار حرفهای Seaborn
- هدف تحلیل پیش از انتخاب نمودار مشخص شده است
- ستونها نوع داده صحیح دارند
- مقادیر گمشده بررسی شدهاند
- دادههای تکراری کنترل شدهاند
- تجمیع موردنیاز با Pandas انجام شده است
- تفاوت میان مجموع، میانگین و تعداد روشن است
- نوع Estimator در Bar Plot مشخص است
- Error Bar بهدرستی تفسیر میشود
- تعداد نمونه گروهها بررسی شده است
- محور و واحد اندازهگیری نوشته شدهاند
- عنوان نمودار واضح است
- پالت رنگ با نوع داده سازگار است
- نمودار برای مخاطب دارای اختلال دید رنگ قابل فهم است
- همبستگی بهعنوان علیت معرفی نشده است
- متن فارسی درست نمایش داده میشود
- خروجی با DPI مناسب ذخیره شده است
- Figure پس از پردازش بسته میشود
پرسشهای متداول
Seaborn چیست؟
Seaborn یک کتابخانه پایتون برای رسم نمودارهای آماری است که روی Matplotlib ساخته شده و ارتباط نزدیکی با Pandas دارد.
Seaborn بهتر است یا Matplotlib؟
هیچکدام بهصورت مطلق بهتر نیستند. Seaborn برای تحلیل آماری و کار سریع با DataFrame مناسب است. Matplotlib کنترل دقیقتری روی اجزای نمودار ارائه میدهد. معمولاً از هر دو در کنار یکدیگر استفاده میشود.
آیا برای یادگیری Seaborn باید Matplotlib بلد باشیم؟
الزامی نیست، اما شناخت Figure، Axes، عنوان، محور و savefig باعث میشود نمودارهای Seaborn را بهتر شخصیسازی کنید.
چگونه Heatmap رسم کنیم؟
ابتدا ماتریس همبستگی را با Pandas محاسبه و سپس به sns.heatmap بدهید:
correlation = df.corr(
numeric_only=True
)
sns.heatmap(
correlation,
annot=True,
cmap="vlag",
center=0
)
تفاوت Histplot و KDE چیست؟
Histplot داده را داخل بازهها میشمارد. KDE یک تخمین هموار از چگالی توزیع ایجاد میکند. هیستوگرام ارتباط مستقیمتری با داده مشاهدهشده دارد.
تفاوت Countplot و Barplot چیست؟
Countplot تعداد ردیفهای هر دسته را نشان میدهد. Barplot یک تخمین آماری از یک متغیر عددی را برای هر دسته محاسبه میکند.
چرا Barplot مجموع فروش را نشان نمیدهد؟
زیرا Barplot بهطور پیشفرض برای نمایش یک Estimator مانند میانگین طراحی شده است. برای مجموع، ابتدا داده را با Pandas گروهبندی و جمع کنید.
Pairplot برای چه کاری مناسب است؟
Pairplot برای بررسی سریع رابطه جفتی چند متغیر عددی مناسب است. تعداد ستونها و ردیفها باید محدود شود تا نمودار سنگین و شلوغ نشود.
چگونه متن فارسی را نمایش دهیم؟
از یک فونت فارسی مناسب همراه با arabic-reshaper و python-bidi استفاده کنید.
آیا Seaborn برای داشبورد تعاملی مناسب است؟
Seaborn بیشتر برای نمودار ثابت و تحلیل اکتشافی مناسب است. برای تعامل کامل در مرورگر، ابزارهایی مانند Plotly انتخاب مناسبتری هستند.
چگونه Seaborn را به هوش مصنوعی درواره متصل کنیم؟
شاخصها را با Pandas محاسبه کنید، نمودار را با Seaborn بسازید و خلاصه ساختاریافته را از طریق endpoint سازگار chat/completions درواره برای تولید گزارش متنی به مدل بفرستید.
جمعبندی
Seaborn یکی از بهترین ابزارهای پایتون برای تحلیل اکتشافی و مصورسازی آماری دادههاست. این کتابخانه با فراهمکردن توابع سطح بالا، کارهایی مانند مقایسه توزیع، رسم Heatmap، نمایش روابط چندمتغیره و بررسی گروههای دستهای را ساده میکند.
برای ساخت یک جریان تحلیل قابل اعتماد:
- Pandas داده را میخواند، پاکسازی و تجمیع میکند
- NumPy محاسبات عددی را انجام میدهد
- Seaborn الگوهای آماری را به تصویر میکشد
- Matplotlib ظاهر و خروجی نهایی را کنترل میکند
- هوش مصنوعی گزارش و توضیح متنی ایجاد میکند
- درواره دسترسی API یکپارچه به مدل موردنیاز پروژه را فراهم میکند
برای شروع استفاده از مدلها، در درواره ثبتنام کنید، API Key بگیرید و مدل مناسب پروژه را از صفحه مدلها و قیمتها انتخاب کنید.
مقالات مرتبط
- آموزش ساخت نمودار با هوش مصنوعی از روی داده
- آموزش تحلیل فایل CSV با هوش مصنوعی
- هوش مصنوعی برای Excel، فرمولنویسی و تحلیل داده
- آموزش تبدیل متن به جدول با هوش مصنوعی
- آموزش کامل نوشتن گزارش با هوش مصنوعی
- آموزش دریافت API Key هوش مصنوعی
برای مطالعه شرایط استفاده و محدودیتهای مسئولیت، صفحه «سلب مسئولیت» را مشاهده کنید.