kích thước điểm đánh dấu phân tán pyplot


376

Trong tài liệu pyplot cho biểu đồ phân tán:

matplotlib.pyplot.scatter(x, y, s=20, c='b', marker='o', cmap=None, norm=None,
                          vmin=None, vmax=None, alpha=None, linewidths=None,
                          faceted=True, verts=None, hold=None, **kwargs)

Kích thước điểm đánh dấu

s: kích thước tính theo điểm ^ 2. Nó là một vô hướng hoặc một mảng có cùng độ dài với x và y.

Những loại đơn vị là points^2? Nó có nghĩa là gì? Có s=100nghĩa là 10 pixel x 10 pixelgì?

Về cơ bản, tôi đang cố gắng tạo ra các ô phân tán với các kích thước đánh dấu khác nhau và tôi muốn tìm hiểu sý nghĩa của con số.


khá chắc chắn rằng các điểm là cùng một đơn vị được sử dụng cho phông chữ.
tacaswell

@tcaswell, ý bạn là s=20kích thước điểm đánh dấu bằng với fontsize=20chữ cái?
LWZ

không, khu vực này sẽ là 20 điểm ^ 2, một fontsize=20chữ cái cao 20 điểm (hoặc ký tự tham chiếu trong phông chữ là cao 20 điểm).
tacaswell

23
matplotlib.pyplot.plot()mstham số ( markersize) tương đương với matplotlib.pyplot.scatter()tham số s( size). Chỉ là một lời nhắc nhở ..
niekas

@neikas đối với tôi có vẻ như không phải vậy, vì một cái là bằng pixel (markersize) và cái kia nằm trong đơn vị điểm bình phương kỳ lạ (kích thước) này. Điều này luôn gây nhầm lẫn cho tôi, nhưng tôi tin rằng nó phải làm với kích thước điểm đánh dấu phân tán được sử dụng để biểu thị số lượng theo cách tỷ lệ trực quan.
heltonbiker

Câu trả lời:


406

Đây có thể là một cách hơi khó hiểu để xác định kích thước nhưng về cơ bản bạn đang chỉ định khu vực của điểm đánh dấu. Điều này có nghĩa là, để tăng gấp đôi chiều rộng (hoặc chiều cao) của điểm đánh dấu, bạn cần tăng stheo hệ số 4. [vì A = W H => (2W) (2H) = 4A]

Tuy nhiên, có một lý do là kích thước của các điểm đánh dấu được xác định theo cách này. Do tỷ lệ diện tích là bình phương chiều rộng, nhân đôi chiều rộng thực sự xuất hiện để tăng kích thước hơn gấp 2 lần (thực tế nó tăng nó lên gấp 4 lần). Để xem điều này, hãy xem xét hai ví dụ sau và đầu ra mà chúng tạo ra.

# doubling the width of markers
x = [0,2,4,6,8,10]
y = [0]*len(x)
s = [20*4**n for n in range(len(x))]
plt.scatter(x,y,s=s)
plt.show()

cho

nhập mô tả hình ảnh ở đây

Chú ý làm thế nào kích thước tăng rất nhanh. Nếu thay vào đó chúng ta có

# doubling the area of markers
x = [0,2,4,6,8,10]
y = [0]*len(x)
s = [20*2**n for n in range(len(x))]
plt.scatter(x,y,s=s)
plt.show()

cho

nhập mô tả hình ảnh ở đây

Bây giờ kích thước rõ ràng của các điểm đánh dấu tăng một cách tuyến tính theo cách trực quan.

Đối với ý nghĩa chính xác của "điểm" là gì, nó khá tùy tiện cho các mục đích âm mưu, bạn chỉ có thể chia tỷ lệ tất cả các kích thước của mình theo một hằng số cho đến khi chúng trông hợp lý.

Hi vọng điêu nay co ich!

Chỉnh sửa: (Đáp lại nhận xét từ @Emma)

Đó có thể là từ ngữ khó hiểu về phía tôi. Câu hỏi hỏi về việc nhân đôi chiều rộng của một vòng tròn, vì vậy trong bức ảnh đầu tiên cho mỗi vòng tròn (khi chúng ta di chuyển từ trái sang phải) chiều rộng của nó gấp đôi chiều rộng trước đó đối với khu vực này là số mũ với cơ sở 4. Tương tự ví dụ thứ hai mỗi vòng tròn có diện tích gấp đôi diện tích cuối cùng mang lại số mũ với cơ sở 2.

Tuy nhiên, đây là ví dụ thứ hai (nơi chúng ta đang mở rộng diện tích) rằng diện tích nhân đôi xuất hiện để làm cho vòng tròn lớn gấp đôi mắt. Do đó, nếu chúng ta muốn một vòng tròn xuất hiện một yếu tố nlớn hơn, chúng ta sẽ tăng diện tích bằng một yếu tố nkhông phải bán kính để kích thước rõ ràng quy mô tuyến tính với diện tích.

Chỉnh sửa để trực quan hóa nhận xét của @TomaszGandor:

Đây là giao diện của các chức năng khác nhau của kích thước điểm đánh dấu:

Kích thước hàm mũ, hình vuông hoặc tuyến tính

x = [0,2,4,6,8,10,12,14,16,18]
s_exp = [20*2**n for n in range(len(x))]
s_square = [20*n**2 for n in range(len(x))]
s_linear = [20*n for n in range(len(x))]
plt.scatter(x,[1]*len(x),s=s_exp, label='$s=2^n$', lw=1)
plt.scatter(x,[0]*len(x),s=s_square, label='$s=n^2$')
plt.scatter(x,[-1]*len(x),s=s_linear, label='$s=n$')
plt.ylim(-1.5,1.5)
plt.legend(loc='center left', bbox_to_anchor=(1.1, 0.5), labelspacing=3)
plt.show()

2
Tôi có thể hiểu sai quan điểm của bạn, nhưng trong ví dụ thứ hai của bạn, bạn đang tăng s theo cấp số nhân (s = [20, 40, 80, 160, 320, 640]) và nói rằng điều đó giúp chúng tôi tăng kích thước tuyến tính đẹp. Sẽ không có ý nghĩa hơn nếu tăng kích thước tuyến tính (ví dụ: s = [20, 40, 60, 80, 100, 120]) cho chúng ta kết quả tìm tuyến tính?
Emma

@Emma Trực giác của bạn là đúng, đó là từ ngữ kém về phần tôi (lựa chọn thay đổi tỷ lệ trục x kém). Tôi đã giải thích thêm một số trong một chỉnh sửa vì nó quá dài cho một bình luận.
Dan

1
Có thể thay đổi sgiá trị theo kích thước của cửa sổ hình? Ý tôi là, nếu chúng ta tối đa hóa các cửa sổ hình, tôi muốn có các dấu kích thước lớn hơn.
Sigur

2
Ví dụ tuyệt vời (chỉ là những thứ cần thiết!). Điều này không nên 4 ** n2 ** n, nhưng n ** 4n ** 2. Với 2 ** ncốt truyện thứ hai không quy mô tuyến tính về đường kính vòng tròn. Nó vẫn đi quá nhanh (chỉ là không quá nhiều so với đầu).
Tomasz Gandor

1
Nói ngắn gọn hơn - cốt truyện thứ hai cho thấy căn bậc hai của cấp số nhân - là một số mũ khác, chỉ hơi dốc hơn một chút.
Tomasz Gandor

218

Bởi vì các câu trả lời khác ở đây cho rằng sbiểu thị khu vực của điểm đánh dấu, tôi thêm câu trả lời này để làm rõ rằng điều này không nhất thiết phải như vậy.

Kích thước tính theo điểm ^ 2

Các đối số strong plt.scatterbiểu thị markersize**2. Như tài liệu nói

s: vô hướng hoặc mảng_like, hình dạng (n,),
kích thước tùy chọn trong các điểm ^ 2. Mặc định là RCParams ['lines.markersize'] ** 2.

Điều này có thể được thực hiện theo nghĩa đen. Để có được điểm đánh dấu x điểm lớn, bạn cần bình phương số đó và đưa nó vào sđối số.

Vì vậy, mối quan hệ giữa các điểm đánh dấu của một biểu đồ đường và đối số kích thước phân tán là hình vuông. Để tạo một điểm đánh dấu phân tán có cùng kích thước với điểm đánh dấu lô có kích thước 10 điểm, do đó bạn sẽ gọi scatter( .., s=100).

nhập mô tả hình ảnh ở đây

import matplotlib.pyplot as plt

fig,ax = plt.subplots()

ax.plot([0],[0], marker="o",  markersize=10)
ax.plot([0.07,0.93],[0,0],    linewidth=10)
ax.scatter([1],[0],           s=100)

ax.plot([0],[1], marker="o",  markersize=22)
ax.plot([0.14,0.86],[1,1],    linewidth=22)
ax.scatter([1],[1],           s=22**2)

plt.show()

Kết nối với "khu vực"

Vậy tại sao các câu trả lời khác và thậm chí tài liệu nói về "diện tích" khi nói đến stham số?

Tất nhiên đơn vị của điểm ** 2 là đơn vị diện tích.

  • Đối với trường hợp đặc biệt của điểm đánh dấu vuông, marker="s"diện tích của điểm đánh dấu thực sự trực tiếp là giá trị của stham số.
  • Đối với một vòng tròn, diện tích của vòng tròn là area = pi/4*s.
  • Đối với các điểm đánh dấu khác, thậm chí có thể không có bất kỳ mối quan hệ rõ ràng nào với khu vực của điểm đánh dấu.

nhập mô tả hình ảnh ở đây

Tuy nhiên, trong mọi trường hợp, diện tích của điểm đánh dấu tỷ lệ thuận với stham số . Đây là động lực để gọi nó là "khu vực" mặc dù trong hầu hết các trường hợp, nó không thực sự.

Việc chỉ định kích thước của các điểm đánh dấu phân tán theo một số lượng tỷ lệ thuận với diện tích của điểm đánh dấu có ý nghĩa rất xa vì đó là khu vực của điểm đánh dấu được cảm nhận khi so sánh các miếng vá khác nhau thay vì chiều dài hoặc đường kính của nó. Tức là nhân đôi số lượng cơ bản nên nhân đôi diện tích của điểm đánh dấu.

nhập mô tả hình ảnh ở đây

Điểm là gì?

Cho đến nay, câu trả lời cho kích thước của điểm đánh dấu phân tán có nghĩa là gì được đưa ra theo đơn vị điểm. Điểm thường được sử dụng trong kiểu chữ, trong đó phông chữ được chỉ định trong điểm. Ngoài ra băng thông thường được chỉ định trong các điểm. Kích thước tiêu chuẩn của các điểm trong matplotlib là 72 điểm mỗi inch (ppi) - 1 điểm là 1/72 inch.

Có thể hữu ích khi có thể chỉ định kích thước bằng pixel thay vì điểm. Nếu con số dpi là 72, một điểm là một pixel. Nếu hình dpi khác nhau (mặc định là matplotlib fig.dpi=100),

1 point == fig.dpi/72. pixels

Do đó, kích thước của các điểm đánh dấu phân tán theo các điểm sẽ khác nhau đối với các hình khác nhau, nhưng người ta có thể tạo ra một điểm đánh dấu 10 x 10 pixel ^ 2, sẽ luôn có cùng số pixel được bao phủ:

nhập mô tả hình ảnh ở đây nhập mô tả hình ảnh ở đây nhập mô tả hình ảnh ở đây

import matplotlib.pyplot as plt

for dpi in [72,100,144]:

    fig,ax = plt.subplots(figsize=(1.5,2), dpi=dpi)
    ax.set_title("fig.dpi={}".format(dpi))

    ax.set_ylim(-3,3)
    ax.set_xlim(-2,2)

    ax.scatter([0],[1], s=10**2, 
               marker="s", linewidth=0, label="100 points^2")
    ax.scatter([1],[1], s=(10*72./fig.dpi)**2, 
               marker="s", linewidth=0, label="100 pixels^2")

    ax.legend(loc=8,framealpha=1, fontsize=8)

    fig.savefig("fig{}.png".format(dpi), bbox_inches="tight")

plt.show() 

Nếu bạn quan tâm đến sự phân tán trong các đơn vị dữ liệu, hãy kiểm tra câu trả lời này .


Tự hỏi làm thế nào người ta sẽ tính toán tham số nào để phân tán để có được một vòng tròn bao gồm đường kính, giả sử, 0,1 trong tọa độ thực của âm mưu (để lấp đầy khoảng cách giữa giả sử 0,4 và 0,5 trên một âm mưu từ (0 , 0) đến (1,1)?
Anatoly Alekseev

@AnatolyAlekseev Điều đó nên được trả lời bằng câu hỏi này .
ImportanceOfByingErnest

21

Bạn có thể sử dụng markersize để chỉ định kích thước của vòng tròn trong phương thức cốt truyện

import numpy as np
import matplotlib.pyplot as plt

x1 = np.random.randn(20)
x2 = np.random.randn(20)
plt.figure(1)
# you can specify the marker size two ways directly:
plt.plot(x1, 'bo', markersize=20)  # blue circle with size 10 
plt.plot(x2, 'ro', ms=10,)  # ms is just an alias for markersize
plt.show()

Từ đây

nhập mô tả hình ảnh ở đây


Câu hỏi là về phân tán, và trong matplotlib, hai hàm vẽ có các tham số khác nhau ( đánh dấu cho biểu đồs cho phân tán ). Vì vậy, câu trả lời này không áp dụng.
Dom

3
@Dom Tôi đã nâng cấp, vì câu hỏi này bật lên là kết quả đầu tiên trong google ngay cả khi tôi tìm kiếm "kích thước điểm đánh dấu lô pyplot", vì vậy câu trả lời này rất hữu ích.
Przemek D

Tôi biết phương pháp cốt truyện và phương pháp phân tán khác nhau về plt nhưng cả hai đều có thể nhận ra 'biểu đồ phân tán' và điều chỉnh đánh dấu, vì vậy câu trả lời này chỉ là một cách giải quyết khác nếu bạn sử dụng phương pháp cốt truyện @Dom
zhao Khánh

18

Đây là khu vực của điểm đánh dấu. Ý tôi là nếu bạn có s1 = 1000và sau đó s2 = 4000, mối quan hệ giữa bán kính của mỗi vòng tròn là : r_s2 = 2 * r_s1. Xem cốt truyện sau:

plt.scatter(2, 1, s=4000, c='r')
plt.scatter(2, 1, s=1000 ,c='b')
plt.scatter(2, 1, s=10, c='g')

nhập mô tả hình ảnh ở đây

Tôi đã có cùng nghi ngờ khi tôi nhìn thấy bài đăng, vì vậy tôi đã làm ví dụ này sau đó tôi sử dụng một thước đo trên màn hình để đo bán kính.


Đây là câu trả lời sạch nhất và chất béo nhất. Cảm ơn
Ayan Mitra

6

Tôi cũng đã cố gắng sử dụng 'phân tán' ban đầu cho mục đích này. Sau một chút lãng phí thời gian - tôi giải quyết các giải pháp sau đây.

import matplotlib.pyplot as plt
input_list = [{'x':100,'y':200,'radius':50, 'color':(0.1,0.2,0.3)}]    
output_list = []   
for point in input_list:
    output_list.append(plt.Circle((point['x'], point['y']), point['radius'], color=point['color'], fill=False))
ax = plt.gca(aspect='equal')
ax.cla()
ax.set_xlim((0, 1000))
ax.set_ylim((0, 1000))
for circle in output_list:    
   ax.add_artist(circle)

nhập mô tả hình ảnh ở đây

Điều này dựa trên câu trả lời cho câu hỏi này


rất hữu ích. Nhưng tại sao lại dùng hai vòng?
Grabantot

1
@grabantot không có lý do, chỉ là tôi đã không nghĩ quá nhiều về nó.
Ike

2

Nếu kích thước của các vòng tròn tương ứng với bình phương của tham số s=parameter, sau đó gán căn bậc hai cho mỗi phần tử bạn nối vào mảng kích thước của bạn, như sau: s=[1, 1.414, 1.73, 2.0, 2.24]khi lấy các giá trị này và trả về chúng, tăng kích thước tương đối của chúng sẽ là căn bậc hai của tiến trình bình phương, trả về một tiến trình tuyến tính.

Nếu tôi đã bình phương mỗi cái khi nó được xuất ra cốt truyện : output=[1, 2, 3, 4, 5]. Hãy thử giải thích danh sách:s=[numpy.sqrt(i) for i in s]


1
Nên là i in output nên không?
Sigur
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.