ভালো গ্রাফ-এর নীতি
এই পাঠে যা শিখবেন
- Edward Tufte-র data-ink ratio ও chartjunk-এর ধারণা
- প্রশ্ন → chart-type matching: কখন bar, কখন line, কখন scatter
- color-blindness এবং accessibility — কেন viridis ব্যবহার করবেন
- "মিথ্যা" গ্রাফ চিনে ফেলা ও নিজে এড়ানো
১ · কেন ভিজ্যুয়ালাইজেশন গুরুত্বপূর্ণ
১৮৫৪ সালে লন্ডনে কলেরার মহামারী চলছিল। চিকিৎসক John Snow একটি মানচিত্রে রোগীর বাড়িগুলো এঁকে দেখালেন — সব Broad Street-এর একটি কুয়োর চারপাশে। কুয়োটি বন্ধ করার পর মহামারী থামল। এটাই data visualization-এর প্রথম বিখ্যাত উদাহরণ। সংখ্যা শুধু পড়লে কিছুই বোঝা যেত না — কিন্তু একটি ছবি প্রাণ বাঁচাল।
আজও data visualizationData Visualizationসংখ্যা ও তথ্যকে graphic আকারে উপস্থাপন — যাতে দ্রুত pattern চোখে পড়ে। মস্তিষ্ক ছবি অনেক দ্রুত process করে টেক্সট বা সংখ্যার চেয়ে।-এর তিনটি লক্ষ্য:
১) Explore (অন্বেষণ): ডেটায় কী আছে নিজে বোঝা — EDA-র অংশ।
২) Explain (ব্যাখ্যা): অন্যকে বোঝানো — দর্শক CEO থেকে গ্রামবাসী যেকেউ।
৩) Persuade (প্রভাবিত করা): সিদ্ধান্ত নিতে সাহায্য করা — কিন্তু সততার সাথে।
২ · Edward Tufte ও Data-Ink Ratio
Edward Tufte — Yale-এর professor, ১৯৮৩-তে "The Visual Display of Quantitative Information" বইটি লিখেন। তিনি বললেন প্রতিটি pixel ও কালির ফোঁটা যা আপনি graph-এ লাগাচ্ছেন — তার একটাই উদ্দেশ্য থাকবে: data দেখানো। বাকি সব chartjunkChartjunkTufte-র দেওয়া নাম — graph-এর সেই অংশ যা data বহন করে না: অপ্রয়োজনীয় background, 3D effect, gradient, gridline, decorative font। বাদ দিতে হবে।।
$$\text{Data-Ink Ratio} = \frac{\text{data দেখাতে ব্যবহৃত কালি}}{\text{মোট কালি}}$$
যত উঁচু — তত ভালো। লক্ষ্য ১.০-এর কাছে। বাস্তবে ০.৭+ হলেই উত্তম। Excel-এর default chart-গুলোতে ratio প্রায়ই ০.৩-এর নিচে — gridline, legend background, 3D-bar shadow সব মিলিয়ে।
৩ · Tufte-র পাঁচ মূল নীতি
- Above all else show the data — সবার আগে data।
- Maximize data-ink ratio — অপ্রয়োজনীয় কালি বাদ।
- Erase non-data ink — গৌণ gridline, border মুছে দিন।
- Erase redundant data-ink — একই data দু'বার দেখাবেন না।
- Revise and edit — প্রথম draft কখনো final না।
৪ · প্রশ্ন থেকে chart বাছাই
Visualization শুরু হয় প্রশ্ন দিয়ে — chart-type দিয়ে নয়। আপনি কী জানতে চাচ্ছেন তার উপর ভিত্তি করে chart বাছুন:
- তুলনা (comparison): "ঢাকা বনাম চট্টগ্রাম বিক্রি" → bar chart।
- সময়ের ধারা (trend): "১২ মাসে বিক্রি কেমন বদলেছে" → line chart।
- সম্পর্ক (relationship): "দাম ও বিক্রির সম্পর্ক" → scatter plot।
- অংশ-পুরোর হিসাব (composition): "মোট বিক্রির কত অংশ মোবাইল" → stacked-bar (pie নয়!)।
- বিতরণ (distribution): "গ্রাহকের বয়স বণ্টন" → histogram বা box-plot।
- ভৌগোলিক: "জেলাভিত্তিক বিক্রি" → choropleth map।
৫ · Pie chart কেন এড়াবেন
Pie chart মানুষের চোখে প্রায় অসম্ভব pattern পড়ার জন্য। মানুষ angle-এর তুলনা ভালো করতে পারে না — কিন্তু length-এর তুলনা ভালো করে। তাই ৫টি ক্যাটেগরি pie-তে দিলে আপনি বলতে পারবেন না কোনটা ১৮% আর কোনটা ২২%।
সমাধান: sorted bar chart। একই data, কিন্তু চোখ মুহূর্তে সঠিক ক্রম পড়ে নেয়। Tufte বলেছেন — "the only worse design than a pie chart is several of them"।
৬ · রঙ — সবচেয়ে ভুল-বোঝা সরঞ্জাম
রঙের তিনটি কাজ — sequence (sequential), diverging, ও categorical। প্রতিটির জন্য ভিন্ন palette।
- Sequential: ০ → বেশি, যেমন bd জেলায় জনসংখ্যা। viridis, plasma, blues।
- Diverging: ০-এর দু'পাশে — যেমন temperature anomaly, profit/loss। RdBu, coolwarm।
- Categorical: আলাদা শ্রেণি যেমন male/female/other। tab10, set1।
Color-blindness: পৃথিবীর প্রায় ৮% পুরুষ ও ০.৫% নারী red-green ভেদ করতে পারেন না (deuteranopia/protanopia)। বাংলাদেশে এর মানে প্রায় ৫০ লক্ষ মানুষ। তাই red-green combination এড়িয়ে viridis (পার্পল-হলুদ-সবুজ ক্রম) ব্যবহার করুন — ২০১৫-তে matplotlib-এ default হয়েছে।
৭ · "মিথ্যা" গ্রাফ — চিনে ফেলা
Darrell Huff-এর ১৯৫৪-র বই "How to Lie with Statistics" এখনো relevant। কয়েকটি সাধারণ ছল:
- Truncated y-axis: ০ থেকে শুরু না করে ৫০ থেকে — ছোট পার্থক্যকে বিশাল দেখায়। Fox News-এর গ্রাফে নিয়মিত।
- Dual y-axis: দু'টি ভিন্ন scale একই plot-এ — যেকোনো সম্পর্ক "প্রমাণ" করা যায়।
- Cherry-picked time range: "২০২০ থেকে ২০২২" দেখানো, কিন্তু পুরো decade দেখালে গল্প উল্টে যায়।
- 3D pie: সামনের slice বড় দেখায় perspective-এর কারণে — যদিও গণিতে সমান।
- Aspect ratio manipulation: chart চওড়া করলে trend flat দেখায়, লম্বা করলে dramatic।
৮ · Bangladesh-এ প্রয়োগ
Daraz, bKash, Pathao — সব data-team প্রতিদিন dashboard বানায়। যে analyst chart-ভিত্তিতে গল্প বলতে পারে — তাকে business team বেশি বিশ্বাস করে। একটি raw Excel sheet দেখিয়ে CEO-কে বুঝানো কঠিন; একটি পরিষ্কার line chart দেখিয়ে বললে — "গত ৬ মাসে গ্রামীণ গ্রাহক ৩৭% বেড়েছে" — সিদ্ধান্ত হয়।
বাংলাদেশের context-এ একটি বিশেষ চ্যালেঞ্জ — Bengali label। অনেক tool (Tableau-র পুরনো সংস্করণ, Power BI default font) Bengali ঠিকমতো render করে না। সমাধান: "Noto Sans Bengali" বা "SolaimanLipi" font বেছে নিন; যদি tool support না করে — label English-এ রাখুন কিন্তু title ও explanation Bengali-তে।
৯ · কোডে সরল উদাহরণ
একটি bar chart ও একটি line chart — matplotlib-এ। নিচের কোড চালান।
import matplotlib.pyplot as plt
# ৫ জেলার বিক্রি
districts = ['Dhaka', 'Chattogram', 'Sylhet', 'Rajshahi', 'Khulna']
sales = [1200, 850, 420, 380, 350]
# sorted bar — সবচেয়ে বড় সবার আগে
pairs = sorted(zip(sales, districts), reverse=True)
sorted_sales, sorted_dist = zip(*pairs)
fig, ax = plt.subplots(figsize=(8, 4))
ax.bar(sorted_dist, sorted_sales, color='#2563eb')
ax.set_ylabel('বিক্রি (লাখ টাকা)')
ax.set_title('জেলাভিত্তিক বিক্রি — ২০২৫')
ax.spines['top'].set_visible(False) # chartjunk বাদ
ax.spines['right'].set_visible(False)
plt.tight_layout()
plt.show()
import matplotlib.pyplot as plt
months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun']
revenue = [120, 135, 150, 145, 170, 195]
fig, ax = plt.subplots(figsize=(8, 4))
ax.plot(months, revenue, marker='o', color='#16a34a', linewidth=2.2)
ax.set_ylim(0, 220) # truncated না — ০ থেকে শুরু
ax.set_ylabel('আয় (লাখ টাকা)')
ax.set_title('মাসিক আয়ের ধারা')
ax.grid(True, alpha=0.3, linestyle='--')
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
plt.tight_layout()
plt.show()
set_ylim(0, 220) — y-axis ০ থেকে শুরু। এই একটি সিদ্ধান্ত graph-কে সৎ রাখে।
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।
প্র ০১ "আপনার দেশে গত ৫ বছরে GDP কত বেড়েছে" — এই গল্প বলতে আপনি কোন chart বাছবেন? কেন? কী কী trade-off আছে?
এটি একটি classic communication-design সমস্যা। চয়েস chart-type একটাই না — গল্প ও দর্শকের উপর নির্ভর।
Default option — line chart:
- সময়ের ধারা দেখানোর জন্য line অপরিহার্য।
- x-axis: ২০২০, ২১, ২২, ২৩, ২৪। y-axis: GDP (BDT trillion)।
- marker (dot) প্রতিটি বছরে — পাঠক exact value পড়তে পারেন।
- y-axis ০ থেকে শুরু — সততা।
বিকল্প — bar chart:
- মাত্র ৫টি বছর — ছোট সংখ্যা hence bar-ও কাজ করে।
- "যত বড় bar — তত বড় economy" — discrete comparison clear।
- কিন্তু "গতি" বা "ত্বরণ" ধরা যায় না — line এতে শ্রেষ্ঠ।
"% growth" দেখাতে চাইলে — column chart:
- প্রতি বছরের growth rate (৫.৫%, ৬.৩%...) — column-এ।
- কিন্তু একই সাথে absolute value হারিয়ে যায়।
- সমাধান: dual chart — line above (absolute), column below (% growth)।
Trade-offs:
- Aspect ratio: চওড়া chart trend flat; লম্বা chart dramatic. Tufte recommend "banking to 45°" — gradient ৪৫°-এর কাছাকাছি।
- Y-axis ০ থেকে? Absolute value হলে অবশ্যই; growth rate হলে ০ optional (negative growth-ও সম্ভব)।
- Inflation adjusted? Nominal GDP misleading — real GDP (inflation-adjusted) দেখান।
- Per-capita? মোট GDP বনাম per-capita ভিন্ন গল্প — population-ও বেড়েছে।
- Comparison context: একা চোখে ৬% growth দ্রুত মনে হতে পারে — কিন্তু ভিয়েতনাম বা ভারতের সাথে compare করলে ছবি বদলে যায়।
Audience-নির্ভর সিদ্ধান্ত:
- CEO presentation: একটি বড় line, minimal text, "৫ বছরে ৩৪% growth" highlight।
- Academic paper: dual line + confidence interval shading।
- Newspaper readers: bar chart with simple labels, growth percent annotated।
মূল উপলব্ধি: "best chart" বলে কিছু নেই — শুধু "best chart for this audience and this question"। আপনার গল্প আগে — chart পরে।
প্র ০২ আপনার boss দাবি করেন "আমাদের grow ৫০% বেড়েছে — y-axis-এ truncate করে দাও যাতে এটা impressive দেখায়"। আপনি কী করবেন?
এটি ethics ও practical politics দু'টোরই প্রশ্ন। একটি data professional-এর কর্মজীবনে এই scenario বহুবার আসবে।
সমস্যা কোথায়:
- "৫০% growth" নিজেই বড় খবর — truncate-এর প্রয়োজন নেই।
- Truncation শুধু তখনই দরকার যখন real growth ছোট কিন্তু আপনি বড় দেখাতে চান — অর্থাৎ deceit-এর উদ্দেশ্য।
- Sophisticated audience truncated y-axis ধরে ফেলে — credibility হারায়।
- Internal report ভিন্ন — investor pitch-এ ধরা পড়লে fraud allegation।
আপনার response strategy:
(১) Reframe — Boss-এর intent বুঝুন:
- Boss-ই hopefully "deceitful" না — হয়তো শুধু "impressive" চায়।
- Better alternatives propose: bigger font for "৫০% growth" label, color highlight, before/after comparison।
- "Sir, ৫০% নিজেই dramatic — y-axis ০ থেকে রাখলেও impact অনেক বেশি।"
(২) Educate — ছোট example দিয়ে দেখান:
- একই data দু'টি chart-এ বানান — truncated ও proper।
- দু'টির side-by-side দেখান। Boss চাইলে নিজেই বুঝবেন কোনটা professional।
(৩) Compromise — middle ground:
- Y-axis ০ থেকে; কিন্তু "broken axis" notation দেখান যদি extreme value থাকে।
- "% change" annotation যোগ — actual growth highlighted।
- Reference line — competitor average বা industry benchmark।
(৪) যদি boss জোর দেয়:
- Internal slide: ভিন্ন slide-এ "context" version রাখুন — যাতে কেউ প্রশ্ন করলে সঠিক answer থাকে।
- External (investor/regulator): clearly object। Audit trail-এ আপনার name থাকে।
- Document — email-এ লিখে রাখুন আপনি বিকল্প suggest করেছিলেন।
Real-world cases:
- Apple-র আগের stock split chart-এ truncated y-axis নিয়ে controversy ছিল।
- Bangladesh-এ নির্বাচনী poster-এ প্রায়ই politicians "growth" graph দেখান — আজকের voters more skeptical।
মূল উপলব্ধি: Data professional-এর primary loyalty data-র প্রতি। Boss-এর সাথে diplomacy দিয়ে চলুন, কিন্তু integrity-র উপর compromise নয়। ভাল analyst তিনি — যিনি truth ও clarity-র মধ্যে বাঁচান।
প্র ০৩ "Color-blindness" কী? AI/data team-এ কেন এটা serious concern? viridis কেন matplotlib-এ default হলো?
Color-blindness — আসলে "color vision deficiency" — visual perception-এর spectrum। সম্পূর্ণ অন্ধত্ব নয়, বরং কিছু color পার্থক্য করতে অক্ষমতা।
প্রকারভেদ:
- Deuteranopia/Deuteranomaly: green sensitivity কম — সবচেয়ে common (৬% পুরুষ)।
- Protanopia/Protanomaly: red sensitivity কম (~১% পুরুষ)।
- Tritanopia: blue-yellow — খুব rare।
- Achromatopsia: সম্পূর্ণ color-blindness, monochromat — অতি rare।
Bangladesh-এ scale:
- ~৫% পুরুষ + ~০.৫% নারী = প্রায় ৪৫-৫০ লক্ষ মানুষ।
- আপনার dashboard যদি color-blind unsafe হয় — এই বিশাল audience excluded।
- Employer/customer দু'ক্ষেত্রেই হতে পারে।
সাধারণ ভুলগুলো:
- Red/green pairing: profit (green), loss (red) — color-blind-এ একই দেখায়।
- Rainbow palette (jet): matplotlib-এর পুরনো default — perceptually non-uniform। Same color difference ≠ same value difference।
- Hue-only encoding: shape ও pattern না দিয়ে শুধু color দিয়ে category — bad accessibility।
Viridis কেন superior:
২০১৫-তে Stéfan van der Walt ও Nathaniel Smith viridis develop করেন। নীতি:
- Perceptually uniform: equal numeric step = equal perceptual step।
- Monotonic in luminosity: grayscale-এও pattern টিকে থাকে (printing, photocopy)।
- Color-blind safe: deuteranopia/protanopia simulator-এ test করা।
- Aesthetic: পার্পল → নীল → সবুজ → হলুদ — beautiful gradient।
Family of palettes:
- viridis — purple/yellow।
- plasma — purple/pink/yellow।
- inferno — black/orange/yellow।
- cividis — explicitly designed for color-blind first।
Accessibility checklist:
- Color-blind simulator দিয়ে test (Sim Daltonism, Coblis)।
- Color + shape/pattern combination — redundant encoding।
- Direct labels (chart-এর উপর label, না legend-এ alone)।
- High contrast text — WCAG AA standard।
Tools-এ default এখন:
- matplotlib 2.0+ — viridis default।
- seaborn — viridis সমর্থিত।
- Tableau — colorblind-safe palette built-in।
- Power BI — accessibility checker theme available।
মূল উপলব্ধি: Accessibility "nice to have" না — moral & business imperative। পৃথিবীর ৮% audience exclude করা মানে সম্ভাব্য customer/employee হারানো।
প্র ০৪ আপনার team-এর data scientist একটি 3D pie chart-এ ৭টি product category-র বিক্রি দেখিয়েছেন। কোথায় কোথায় সমস্যা? আপনি কীভাবে redesign করবেন?
এটি real-world feedback সিচুয়েশন — চমৎকার teaching moment।
সমস্যা চিহ্নিতকরণ:
(১) Pie চয়েস ভুল:
- মানুষ angle তুলনায় দুর্বল — ৫ ক্যাটেগরির উপরে pie প্রায় অপাঠ্য।
- ৭টি ক্যাটেগরি — কোনটা বড় কোনটা ছোট চোখে ধরা পড়ে না।
(২) 3D effect ক্ষতিকর:
- Perspective-এর কারণে সামনের slice অযৌক্তিকভাবে বড় দেখায়।
- Tufte-র "lie factor" বাড়ে।
- Data-ink ratio হ্রাস — extra ink data বহন করে না।
(৩) Color choice সম্ভবত সমস্যা:
- ৭টি rainbow color — adjacent slices অনেক সময় indistinguishable।
- Color-blind unfriendly likely।
Redesign — step by step:
Step ১: Goal পরিষ্কার করা
- "Which categories are top sellers?" — sorted bar।
- "Total কীভাবে split?" — ১০০% stacked bar।
- "Trend over time per category?" — small multiples line chart।
Step ২: Sorted bar chart (most likely best)
- X-axis: bar (vertical) বা y-axis: bar (horizontal — long category names-এ ভাল)।
- Sorted descending — top category প্রথমে।
- একটি single color (highlight color) — সব bar একই রঙ। focus data-এ, সাজসজ্জায় না।
- Direct value labels চাই থাকলে — bar শেষে।
Step ৩: Aspect ratio
- ৭টি bar — horizontal layout সম্ভবত ভালো (category name বড় হলে readable)।
- Width:height ≈ ১.৫:১।
Step ৪: Chartjunk বাদ
- Top ও right spine মুছে দিন।
- Gridline subtle (alpha=0.3, dashed)।
- Background pure white।
- Title clear, no title-shadow।
Step ৫: Annotation
- Top-3 category-র উপরে percentage label (যেমন "Mobile: ৩২%")।
- "Total revenue: ৪৫০ কোটি টাকা" — chart-এর কোণে।
- Source: "Daraz Q4 2025 internal data"।
Code skeleton:
import matplotlib.pyplot as plt
cats = ['Mobile','Fashion','Beauty','Home','Books','Sports','Toys']
sales = [320, 240, 180, 150, 110, 90, 60]
pairs = sorted(zip(sales, cats))
s, c = zip(*pairs)
fig, ax = plt.subplots(figsize=(8, 5))
ax.barh(c, s, color='#2563eb')
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.set_xlabel('বিক্রি (কোটি টাকা)')
ax.set_title('পণ্য-শ্রেণিভিত্তিক বিক্রি — Q4 2025')
plt.tight_layout()
Feedback delivery কৌশল:
- "3D pie খারাপ" বলবেন না — "এই data-এ sorted bar আরও clear হবে কেন বলে দিচ্ছি" বলুন।
- একটি ভাল alternative dekhao — co-author hisabe থাকুন।
- Tufte-র বই বা viz-resources share করুন follow-up-এ।
মূল উপলব্ধি: Visualization team-skill। কেউ একা শেখে না — team-এর constructive critique-এ গড়ে। আপনি যখন কাউকে redesign suggest করেন — পুরো team-ই বেটার হয়।
অনুশীলন
-
Chart-type matching: কোন chart বেছে নিবেন?
- "৬৪ জেলায় COVID টিকা coverage" — ?
- "১২ মাসে bKash transaction volume" — ?
- "বয়স ও আয়ের সম্পর্ক" — ?
- "গ্রাহকের বয়স distribution" — ?
- ৬৪ জেলা coverage → choropleth map (অথবা horizontal sorted bar chart)।
- ১২ মাসে transaction → line chart (trend)।
- বয়স ও আয় → scatter plot (relationship)।
- বয়স distribution → histogram বা box-plot।
-
Chartjunk চিহ্নিত করুন: একটি Excel default 3D bar chart দেখুন। কী কী chartjunk আছে? কীভাবে data-ink ratio বাড়াবেন?
সাধারণ chartjunk:
- 3D shadow ও perspective
- Background gradient (light blue → white)
- সব gridline (major + minor)
- Border চারপাশে
- Legend background fill
- Default font-shadow
সমাধান: 2D চয়েস, single color, plain background, top/right spine মুছুন, legend background transparent।
-
Truncated axis: একটি chart-এ y-axis ৯৫ থেকে ১০০ — দু'টি bar দেখাচ্ছে ৯৬ ও ৯৯। প্রথম-নজরে কেমন দেখায়? proper version-এ কেমন দেখাবে?
Truncated y-axis: ৯৬ ও ৯৯-এর পার্থক্য বিশাল মনে হয় (৯৬-এর bar প্রায় ০, ৯৯-এর bar উপরে)। মাত্র ৩%-এর পার্থক্য — কিন্তু চোখে ৩x বা ১০x পার্থক্য মনে হয়।
Proper (০ থেকে ১০০) version-এ — দু'টি bar প্রায় একই উচ্চতায়, খুব ক্ষুদ্র পার্থক্য। সঠিক perception।
সততা নিশ্চিত করতে:
ax.set_ylim(0, 100)ব্যবহার, বা broken-axis notation দেখান।
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- পাঠ ২৫ · Plotly দিয়ে interactive chart পরবর্তী পাঠ Static থেকে interactive — hover, zoom, animation যুক্ত chart।
- পাঠ ২৩ · ARIMA ও Prophet আগের পাঠ Time-series forecast — পরবর্তীতে যা visualize করতে পারেন।
- পাঠ ২৮ · Storytelling with data এই পাঠের সাথে সম্পর্কিত Chart বানালেই হবে না — গল্প বলতে শিখুন।
- সব AI Courses দেখুন ABCL TECH Python, ML, DL, NLP, CV, GenAI, RL, MLOps — সব AI কোর্স একসাথে।