আর-তে পিসিএ বিপ্লবতে অন্তর্নিহিত পরিবর্তনশীলগুলির তীর


11

প্রশ্নটি সফ্টওয়্যার-নির্দিষ্ট করে তোলার ঝুঁকিতে এবং এর সর্বব্যাপীতা এবং আইডিসিএনক্র্যাসির অজুহাতে, আমি biplot()আর এর কার্যকারিতা সম্পর্কে এবং বিশেষত এর ডিফল্ট, সুপারিম্পোজড রেড তীর সম্পর্কিত গণনা এবং পরিকল্পনা সম্পর্কে জিজ্ঞাসা করতে চাই want অন্তর্নিহিত চলকগুলিতে।


[কয়েকটি মন্তব্যে বোঝার জন্য, প্রাথমিকভাবে পোস্ট করা প্লটগুলিতে খুব কম আগ্রহের সমস্যা ছিল এবং এখন তা মুছে ফেলা হয়েছে।]


আপনি কীভাবে আপনার সবুজ তীর পেয়েছিলেন তা আমি বুঝতে পারি না। এগুলি সঠিক নয়। S. দৈর্ঘ্য সবুজ প্রায় যে সত্য। s.width সবুজ থেকে দ্বিগুণ দীর্ঘ আপনি সন্দেহ করতে পারবেন যে আপনি ভেরিয়েবলগুলি মানক না করে সম্পর্কিত চক্রান্ত করছেন plot পারস্পরিক সম্পর্কের ভিত্তিতে পিসিএর বাইপ্লট-এ এটি ঘটতে পারে না।
ttnphns

লাল তীরগুলি সঠিক বলে মনে হচ্ছে। দেখুন: এগুলি একই দৈর্ঘ্য এবং পিসি 2 সম্পর্কে প্রতিসম হয়। আপনি কেবলমাত্র 2 টি ভেরিয়েবল এবং পারস্পরিক সম্পর্কের উপর ভিত্তি করে পিসিএ করেন এমন একমাত্র সম্ভাব্য অবস্থান (যেমন স্ট্যান্ডার্ডাইজড ভেরিয়েবল)। পারস্পরিক সম্পর্কের উপর ভিত্তি করে পিসিএতে লোডিং (তীরের সমন্বিত) হ'ল পিসি এবং ভেরিয়েবলের মধ্যে পারস্পরিক সম্পর্ক। আপনার উদাহরণে, loadings (পিসি দ্বারা Vars) আছেন: .74752, .66424; -.74752, .66424
ttnphns

@ttnphns হ্যাঁ, লাল তীরগুলি হ'ল আমি পুনরুত্পাদন করার চেষ্টা করছি (সেগুলি সঠিক), এবং তারা biplot(name_of_the_PCA)কল দিয়ে আর-তে প্লট করা হয়েছিল , যা এই ক্ষেত্রে biplot(PCA)। আমি ডেটা কেন্দ্রিক এবং স্কেল করেছি।
আন্তনি পরল্লদা

সুতরাং আপনার প্রশ্ন কি? লাল তীরগুলির জন্য স্থানাঙ্কগুলি কীভাবে গণনা করবেন? সেগুলি পিসিএ লোডিং হওয়া উচিত । কখনও কখনও, আইজেনভেেক্টরগুলি প্লট করা হয় (আপনার আর কমান্ড সম্ভবত এটি করেছে ??) তবে, conক্যমত্যের অর্থপূর্ণ উপায় লোডিং প্লট করা
ttnphns

@ttnphns ইগেনভেেক্টরগুলিকে প্লট করা (আমি এটি লোডিংয়ের সমান বলে মনে করি) আমাকে সঠিক দিকনির্দেশনা দেয় (আপনাকে ধন্যবাদ), তবে লাল তীরের মতো আকার নয় (আমি ওপিতে চিত্রটি আটকিয়ে দিচ্ছি)।
আন্তনি পরেল্লদা

উত্তর:


19

@ অ্যামিবার এবং @ টিএনএফএনএস-এর পোস্টটি উত্সাহ দেওয়ার বিষয়ে বিবেচনা করুন । আপনার সহায়তা এবং ধারণা উভয়ের জন্য আপনাকে ধন্যবাদ।


নিম্নলিখিত উপর নির্ভর আর মধ্যে Iris ডেটা সেটটি , এবং বিশেষভাবে প্রথম তিন ভেরিয়েবল (কলাম): Sepal.Length, Sepal.Width, Petal.Length

একটি বাইপল্ট একটি লোডিং প্লট (অমানুষ্কৃত আইজেনভেেক্টর) - কংক্রিটের মধ্যে প্রথম দুটি লোডিং এবং একটি স্কোর প্লট (প্রধান উপাদানগুলির সাথে সম্মিলিতভাবে ঘোরানো এবং প্রসারিত ডেটা পয়েন্টগুলি ) একত্রিত করে । একই ডেটাসেটটি ব্যবহার করে @ অ্যামিবা প্রথম এবং দ্বিতীয় প্রধান উপাদানগুলির স্কোর প্লটের 3 সম্ভাব্য সাধারণকরণ এবং প্রাথমিক ভেরিয়েবলের লোডিং প্লট (তীর) এর 3 সাধারণকরণের উপর ভিত্তি করে পিসিএ বাইপলটের 9 টি সম্ভাব্য সংমিশ্রণের বর্ণনা দেয় । আর এই সম্ভাব্য সংমিশ্রণগুলি কীভাবে পরিচালনা করে তা দেখতে, biplot()পদ্ধতিটি দেখার জন্য এটি আকর্ষণীয় :


প্রথমে রৈখিক বীজগণিত কপি এবং পেস্ট করার জন্য প্রস্তুত:

X = as.matrix(iris[,1:3])             # Three first variables of Iris dataset
CEN = scale(X, center = T, scale = T) # Centering and scaling the data
PCA = prcomp(CEN)

# EIGENVECTORS:
(evecs.ei = eigen(cor(CEN))$vectors)       # Using eigen() method
(evecs.svd = svd(CEN)$v)                   # PCA with SVD...
(evecs = prcomp(CEN)$rotation)             # Confirming with prcomp()

# EIGENVALUES:
(evals.ei = eigen(cor(CEN))$values)        # Using the eigen() method
(evals.svd = svd(CEN)$d^2/(nrow(X) - 1))   # and SVD: sing.values^2/n - 1
(evals = prcomp(CEN)$sdev^2)               # with prcomp() (needs squaring)

# SCORES:
scr.svd = svd(CEN)$u %*% diag(svd(CEN)$d)  # with SVD
scr = prcomp(CEN)$x                        # with prcomp()
scr.mm = CEN %*% prcomp(CEN)$rotation      # "Manually" [data] [eigvecs]

# LOADINGS:

loaded = evecs %*% diag(prcomp(CEN)$sdev)  # [E-vectors] [sqrt(E-values)]

1. লোডিং প্লট (তীর) পুনরুত্পাদন:

এখানে @ttnphns দ্বারা পোস্টে জ্যামিতিক ব্যাখ্যা অনেক সহায়তা করে। পোস্টে ডায়াগ্রাম এর স্বরলিপি বজায় হয়েছে: ঘোরা মধ্যে পরিবর্তনশীল বিষয় স্থান । হ'ল সংশ্লিষ্ট তীরটি শেষ পর্যন্ত চক্রান্ত করা হয়; এবং স্থানাঙ্কগুলি এবং উপাদানটি একটি ভেরিয়েবল লোড করে এবং :এইচ 1 2 ভি পিসি 1 পিসি 2VSepal L.ha1a2VPC1PC2


এখানে চিত্র বর্ণনা লিখুন


Sepal L. সাথে সম্মত ভেরিয়েবলের উপাদানটি তখন হবে:PC1

a1=hcos(ϕ)

যা, যদি সাথে সম্মানের সাথে স্কোরগুলি হয় - আসুন তাদেরকে বলি - প্রমিত করা হয় যাতে তাদেরএস 1PC1S1

S1=1nscores12=1 , উপরের সমীকরণটি ডট পণ্য এর সমতুল্য :VS1

a1=VS1=VS1cos(ϕ)(1)=h×1×cos(ϕ)

যেহেতু ,V=x2

Var(V)=x2n1=Vn1V=h=var(V)n1.

একইভাবে,

S1=1=var(S1)n1.

এক্কে ফিরে যাচ্ছি। ,(1)

a1=h×1×cos(ϕ)=var(V)var(S1)cos(θ)(n1)

cos(ϕ) সুতরাং, বিবেচনা করা যেতে পারে একটি পিয়ারসন এর পারস্পরিক সম্পর্কের সহগের , , সতর্কীকরণ যে আমি এর বলি বুঝতে পারছি না সঙ্গে ফ্যাক্টর।rn1

এর নীল লাল তীরগুলির নকল এবং ওভারল্যাপিং biplot()

par(mfrow = c(1,2)); par(mar=c(1.2,1.2,1.2,1.2))

biplot(PCA, cex = 0.6, cex.axis = .6, ann = F, tck=-0.01) # R biplot
# R biplot with overlapping (reproduced) arrows in blue completely covering red arrows:
biplot(PCA, cex = 0.6, cex.axis = .6, ann = F, tck=-0.01) 
arrows(0, 0,
       cor(X[,1], scr[,1]) * 0.8 * sqrt(nrow(X) - 1), 
       cor(X[,1], scr[,2]) * 0.8 * sqrt(nrow(X) - 1), 
       lwd = 1, angle = 30, length = 0.1, col = 4)
arrows(0, 0,
       cor(X[,2], scr[,1]) * 0.8 * sqrt(nrow(X) - 1), 
       cor(X[,2], scr[,2]) * 0.8 * sqrt(nrow(X) - 1), 
       lwd = 1, angle = 30, length = 0.1, col = 4)
arrows(0, 0,
       cor(X[,3], scr[,1]) * 0.8 * sqrt(nrow(X) - 1), 
       cor(X[,3], scr[,2]) * 0.8 * sqrt(nrow(X) - 1), 
       lwd = 1, angle = 30, length = 0.1, col = 4)

এখানে চিত্র বর্ণনা লিখুন

আগ্রহের বিষয়:

  • তীরগুলি প্রথম দুটি মূল উপাদান দ্বারা উত্পাদিত স্কোরগুলির সাথে মূল ভেরিয়েবলের পারস্পরিক সম্পর্ক হিসাবে পুনরুত্পাদন করা যেতে পারে।
  • বিকল্পভাবে, এটি দ্বিতীয় সারির প্রথম প্লটের মতোই অর্জন করা যেতে পারে, @ অ্যামিবার পোস্টে be লেবেলযুক্ত :VS

এখানে চিত্র বর্ণনা লিখুন

বা আর কোডে:

    biplot(PCA, cex = 0.6, cex.axis = .6, ann = F, tck=-0.01) # R biplot
    # R biplot with overlapping arrows in blue completely covering red arrows:
    biplot(PCA, cex = 0.6, cex.axis = .6, ann = F, tck=-0.01) 
    arrows(0, 0,
       (svd(CEN)$v %*% diag(svd(CEN)$d))[1,1] * 0.8, 
       (svd(CEN)$v %*% diag(svd(CEN)$d))[1,2] * 0.8, 
       lwd = 1, angle = 30, length = 0.1, col = 4)
    arrows(0, 0,
       (svd(CEN)$v %*% diag(svd(CEN)$d))[2,1] * 0.8, 
       (svd(CEN)$v %*% diag(svd(CEN)$d))[2,2] * 0.8, 
       lwd = 1, angle = 30, length = 0.1, col = 4)
    arrows(0, 0,
       (svd(CEN)$v %*% diag(svd(CEN)$d))[3,1] * 0.8, 
       (svd(CEN)$v %*% diag(svd(CEN)$d))[3,2] * 0.8, 
       lwd = 1, angle = 30, length = 0.1, col = 4)

বা এখনও ...

    biplot(PCA, cex = 0.6, cex.axis = .6, ann = F, tck=-0.01) # R biplot
    # R biplot with overlapping (reproduced) arrows in blue completely covering red arrows:
    biplot(PCA, cex = 0.6, cex.axis = .6, ann = F, tck=-0.01) 
    arrows(0, 0,
       (loaded)[1,1] * 0.8 * sqrt(nrow(X) - 1), 
       (loaded)[1,2] * 0.8 * sqrt(nrow(X) - 1), 
       lwd = 1, angle = 30, length = 0.1, col = 4)
    arrows(0, 0,
       (loaded)[2,1] * 0.8 * sqrt(nrow(X) - 1), 
       (loaded)[2,2] * 0.8 * sqrt(nrow(X) - 1), 
       lwd = 1, angle = 30, length = 0.1, col = 4)
    arrows(0, 0,
       (loaded)[3,1] * 0.8 * sqrt(nrow(X) - 1), 
       (loaded)[3,2] * 0.8 * sqrt(nrow(X) - 1), 
       lwd = 1, angle = 30, length = 0.1, col = 4)

@ttnphns দ্বারা লোডিংয়ের জ্যামিতিক ব্যাখ্যার সাথে সংযুক্ত হচ্ছে , বা এই অন্যান্য তথ্যমূলক পোস্টটিও @ttnphns দ্বারা

  • একটি স্কেলিং ফ্যাক্টর রয়েছে: sqrt(nrow(X) - 1)যা কিছুটা রহস্য থেকে যায়।

  • 0.8 লেবেলের জন্য স্থান তৈরি করার সাথে - এখানে এই মন্তব্যটি দেখুন :

তদ্ব্যতীত, একটিও বলতে হবে যে তীরগুলি এমনভাবে প্লট করা হয়েছে যাতে পাঠ্য লেবেলের কেন্দ্র যেখানে থাকে সেখানে! এরপরে প্লট করার আগে তীরগুলি 0.80.8 দ্বারা গুণিত হয়, অর্থাত্ সমস্ত তীরগুলি যা হওয়া উচিত তার চেয়ে কম হয়, সম্ভবত পাঠ্য লেবেলের সাথে ওভারল্যাপিং রোধ করতে (বাইপলট.ডিফল্টের কোড দেখুন)। আমি দেখতে পেয়েছি এটি অত্যন্ত বিভ্রান্তিকর। - অ্যামিবা মার্চ 19 '15 এ 10:06 এ


২. biplot()স্কোর প্লট প্লট করা (এবং একই সাথে তীরগুলি):

অক্ষগুলি বর্গক্ষেত্রের এককের যোগফলকে স্কেল করা হয়, @ অ্যামিবার পোস্টে প্রথম সারির প্রথম প্লটের সাথে মিলে , যা এসভিডি পচানোর ম্যাট্রিক্স ম্যাথবিএফ পুনরুত্পাদন করা যেতে পারে (আরও পরে) - " ম্যাথবিএফের কলামগুলি : এইগুলি মূল স্কোয়ারগুলির ইউনিট যোগফলকে স্কেল করা হয় ""UU

এখানে চিত্র বর্ণনা লিখুন

বাইপলট নির্মাণে নীচে এবং শীর্ষ অনুভূমিক অক্ষগুলিতে খেলতে দুটি ভিন্ন স্কেল রয়েছে:

এখানে চিত্র বর্ণনা লিখুন

তবে আপেক্ষিক স্কেলটি তাত্ক্ষণিকভাবে সুস্পষ্ট নয়, যার জন্য ফাংশন এবং পদ্ধতিগুলির মধ্যে আনন্দ প্রয়োজন:

biplot() th এর কলাম হিসাবে প্লট স্কোরগুলি , যা অরথোগোনাল ইউনিটের ভেক্টরগুলি:U

> scr.svd = svd(CEN)$u %*% diag(svd(CEN)$d) 
> U = svd(CEN)$u
> apply(U, 2, function(x) sum(x^2))
[1] 1 1 1

যেখানে prcomp()আর ফাংশন ফেরৎ স্কোর তাদের eigenvalues স্কেল:

> apply(scr, 2, function(x) var(x))         # pr.comp() scores scaled to evals
       PC1        PC2        PC3 
2.02142986 0.90743458 0.07113557 
> evals                                     #... here is the proof:
[1] 2.02142986 0.90743458 0.07113557

সুতরাং আমরা ইগেনভ্যালুগুলি দিয়ে ভাগ করে এর প্রকরণটি স্কেল করতে পারি :1

> scr_var_one = scr/sqrt(evals)[col(scr)]  # to scale to var = 1
> apply(scr_var_one, 2, function(x) var(x)) # proved!
[1] 1 1 1

তবে যেহেতু আমরা স্কোয়ারের যোগফল হতে চাই তাই আমাদেরকে by দ্বারা ভাগ করতে হবে কারণ:1n1

var(scr_var_one)=1=1nscr_var_onen1
> scr_sum_sqrs_one = scr_var_one / sqrt(nrow(scr) - 1) # We / by sqrt n - 1.
> apply(scr_sum_sqrs_one, 2, function(x) sum(x^2))     #... proving it...
PC1 PC2 PC3 
  1   1   1

উল্লেখ্য, স্কেলিং ফ্যাক্টরের ব্যবহার , পরে পরিবর্তিত হয়ে to করা হয় যখন ব্যাখ্যাটি সংজ্ঞায়িত করা হয় বলে মনে হয় যে সত্যn1nlan

prcomp ব্যবহার করে : "প্রিনম্পম্পের মতো নয়, বৈকল্পগুলি সাধারণ বিভাজকের সাথে গণনা করা হয় "।n1n1


সমস্ত ifবিবৃতি এবং অন্যান্য গৃহসজ্জার ফ্লাফ তাদের সরিয়ে দেওয়ার পরে , biplot()নিম্নলিখিত হিসাবে এগিয়ে যায়:

X   = as.matrix(iris[,1:3])                    # The original dataset
CEN = scale(X, center = T, scale = T)          # Centered and scaled
PCA = prcomp(CEN)                              # PCA analysis

par(mfrow = c(1,2))                            # Splitting the plot in 2.
biplot(PCA)                                    # In-built biplot() R func.

# Following getAnywhere(biplot.prcomp):

choices = 1:2                                  # Selecting first two PC's
scale = 1                                      # Default
scores= PCA$x                                  # The scores
lam = PCA$sdev[choices]                        # Sqrt e-vals (lambda) 2 PC's
n = nrow(scores)                               # no. rows scores
lam = lam * sqrt(n)                            # See below.

# at this point the following is called...
# biplot.default(t(t(scores[,choices])      /  lam), 
#                t(t(x$rotation[,choices]) *   lam))

# Following from now on getAnywhere(biplot.default):

x = t(t(scores[,choices])       / lam)         # scaled scores
# "Scores that you get out of prcomp are scaled to have variance equal to      
#  the eigenvalue. So dividing by the sq root of the eigenvalue (lam in 
#  biplot) will scale them to unit variance. But if you want unit sum of 
#  squares, instead of unit variance, you need to scale by sqrt(n)" (see comments).
# > colSums(x^2)
# PC1       PC2 
# 0.9933333 0.9933333    # It turns out that the it's scaled to sqrt(n/(n-1)), 
# ...rather than 1 (?) - 0.9933333=149/150

y = t(t(PCA$rotation[,choices]) * lam)         # scaled eigenvecs (loadings)


n = nrow(x)                                    # Same as dataset (150)
p = nrow(y)                                    # Three var -> 3 rows

# Names for the plotting:

xlabs = 1L:n
xlabs = as.character(xlabs)                    # no. from 1 to 150 
dimnames(x) = list(xlabs, dimnames(x)[[2L]])   # no's and PC1 / PC2

ylabs = dimnames(y)[[1L]]                      # Iris species
ylabs = as.character(ylabs)
dimnames(y) <- list(ylabs, dimnames(y)[[2L]])  # Species and PC1/PC2

# Function to get the range:
unsigned.range = function(x) c(-abs(min(x, na.rm = TRUE)), 
                                abs(max(x, na.rm = TRUE)))
rangx1 = unsigned.range(x[, 1L])               # Range first col x
# -0.1418269  0.1731236
rangx2 = unsigned.range(x[, 2L])               # Range second col x
# -0.2330564  0.2255037
rangy1 = unsigned.range(y[, 1L])               # Range 1st scaled evec
# -6.288626   11.986589
rangy2 = unsigned.range(y[, 2L])               # Range 2nd scaled evec
# -10.4776155   0.8761695

(xlim = ylim = rangx1 = rangx2 = range(rangx1, rangx2))
# range(rangx1, rangx2) = -0.2330564  0.2255037

# And the critical value is the maximum of the ratios of ranges of 
# scaled e-vectors / scaled scores:

(ratio = max(rangy1/rangx1, rangy2/rangx2)) 
# rangy1/rangx1   =   26.98328    53.15472
# rangy2/rangx2   =   44.957418   3.885388
# ratio           =   53.15472

par(pty = "s")                                 # Calling a square plot

# Plotting a box with x and y limits -0.2330564  0.2255037
# for the scaled scores:

plot(x, type = "n", xlim = xlim, ylim = ylim)  # No points
# Filling in the points as no's and the PC1 and PC2 labels:
text(x, xlabs) 
par(new = TRUE)                                # Avoids plotting what follows separately

# Setting now x and y limits for the arrows:

(xlim = xlim * ratio)  # We multiply the original limits x ratio
# -16.13617  15.61324
(ylim = ylim * ratio)  # ... for both the x and y axis
# -16.13617  15.61324

# The following doesn't change the plot intially...
plot(y, axes = FALSE, type = "n", 
     xlim = xlim, 
     ylim = ylim, xlab = "", ylab = "")

# ... but it does now by plotting the ticks and new limits...
# ... along the top margin (3) and the right margin (4)
axis(3); axis(4)
text(y, labels = ylabs, col = 2)  # This just prints the species

arrow.len = 0.1                   # Length of the arrows about to plot.

# The scaled e-vecs are further reduced to 80% of their value
arrows(0, 0, y[, 1L] * 0.8, y[, 2L] * 0.8, 
       length = arrow.len, col = 2)

যা প্রত্যাশিত হিসাবে, biplot()আউটপুটটিকে সরাসরি biplot(PCA)(নীচে বাম প্লট) এর সমস্ত ছোঁয়াচে নান্দনিক ত্রুটিগুলি পুনরুত্পাদন করে :

এখানে চিত্র বর্ণনা লিখুন

আগ্রহের বিষয়:

  • তীরগুলি দুটি মূল উপাদানগুলির প্রত্যেকটির মাপকৃত ইগেনভেেক্টর এবং তাদের নিজ নিজ স্কেল স্কোর (দ) এর মধ্যে সর্বাধিক অনুপাত সম্পর্কিত একটি স্কেলে প্লট করা হয় ratio। এএস @ অ্যামিবা মন্তব্য করেছেন:

বিচ্ছুরিত প্লট এবং "তীর প্লট" এমনভাবে পরিমাপ করা হয়েছে যে তীরগুলির বৃহত্তম (পরম মান) x বা y তীর স্থানাঙ্কটি বিচ্ছুরিত ডেটা পয়েন্টগুলির বৃহত্তম (পরম মান) x বা y স্থানাঙ্কের সমান ছিল

  • উপরে প্রত্যাশিত হিসাবে, পয়েন্টগুলি সরাসরি ম্যাট্রিক্স এর স্কোর হিসাবে প্লট করা যেতে পারে :U


1
+1, ভাল অধ্যয়ন। আমি Rআপনার প্রশ্নে ট্যাগ যুক্ত করেছি কারণ বিভ্রান্তিকর বিষয়টি (যথা, স্কেলিং সহগ) আংশিক আর-নির্দিষ্ট প্রমাণিত। সাধারণভাবে, আপনি নিজেকে দেখতে সক্ষম হয়েছিলেন যে পিসিএ বিপ্লট উপাদান উপাদানগুলি (সারি সমন্বয়) এবং উপাদান নির্দেশের সহগ (কলাম স্থানাঙ্ক) এর একটি ওভারলে স্ক্র্যাটারপ্লট এবং যেহেতু "জড়তা" (বৈকল্পিক) দ্বারা বিভিন্ন পরিমাণে মান প্রমিতকরণ প্রতিটি ক্ষেত্রে প্রয়োগ করা যেতে পারে এছাড়াও, তাই বাইপ্লট বিভিন্ন চেহারা উত্থাপিত হতে পারে। যোগ করতে: সর্বাধিক (আরও জ্ঞান), লোডিংগুলি কলাম স্থানাঙ্ক (তীর) হিসাবে প্রদর্শিত হয়।
ttnphns

1
( ধারাবাহিক ) বাইপ্লট সম্পর্কে আমার ওভারভিউ দেখুন যা ব্যাখ্যা করে, বিভিন্ন কথায়, আপনি আপনার উত্তরের উত্তরে কী দেখিয়েছেন।
ttnphns

2
টিউটোরিয়াল লেখার জন্য এবং আমাদের জন্য পুনরুত্পাদনযোগ্য কোড সহ +1 ধন্যবাদ!
হাইতাও ডু

অ্যান্টনি, আপনি কি আঁকেন (যেমন হাতে) বা আপনি নিজের ছবিটি প্লট করেছিলেন (ডেটা দিয়েছিলেন)? আপনি কোন সফ্টওয়্যার ব্যবহার করেছেন? দেখতে সুন্দর লাগছে।
ttnphns

@ttnphns আপনাকে ধন্যবাদ! এটির লিঙ্কটি এখানে । আমি ভাবছিলাম যে আপনি যদি এটির উন্নতি করতে পারেন, এবং লোডিংগুলি এবং পিসি আরও ভাল, আরও যুক্তিযুক্ত উপায়ে প্লট করুন। পরিবর্তন করতে নির্দ্বিধায় (এটি একটি আশ্চর্যজনকভাবে ব্যবহারকারী বান্ধব প্রোগ্রাম) এবং আপনি যদি তা করেন তবে দয়া করে ভাগ করুন।
আন্তনি পরল্লদা
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.