Thêm một huyền thoại vào PyPlot trong Matplotlib theo cách đơn giản nhất có thể


263

TL; DR -> Làm cách nào để tạo một chú giải cho biểu đồ đường trong Matplotlib's PyPlotmà không tạo thêm bất kỳ biến nào?

Vui lòng xem xét kịch bản đồ thị dưới đây:

if __name__ == '__main__':
    PyPlot.plot(total_lengths, sort_times_bubble, 'b-',
                total_lengths, sort_times_ins, 'r-',
                total_lengths, sort_times_merge_r, 'g+',
                total_lengths, sort_times_merge_i, 'p-', )
    PyPlot.title("Combined Statistics")
    PyPlot.xlabel("Length of list (number)")
    PyPlot.ylabel("Time taken (seconds)")
    PyPlot.show()

Như bạn có thể thấy, đây là một sử dụng rất cơ bản của matplotlib's PyPlot. Điều này lý tưởng tạo ra một biểu đồ như dưới đây:

Đồ thị

Không có gì đặc biệt, tôi biết. Tuy nhiên, không rõ dữ liệu nào đang được vẽ ở đâu (Tôi đang cố gắng vẽ dữ liệu của một số thuật toán sắp xếp, độ dài theo thời gian và tôi muốn chắc chắn rằng mọi người biết đó là dòng nào). Vì vậy, tôi cần một huyền thoại, tuy nhiên, hãy xem ví dụ sau đây ( từ trang web chính thức ):

ax = subplot(1,1,1)
p1, = ax.plot([1,2,3], label="line 1")
p2, = ax.plot([3,2,1], label="line 2")
p3, = ax.plot([2,3,1], label="line 3")

handles, labels = ax.get_legend_handles_labels()

# reverse the order
ax.legend(handles[::-1], labels[::-1])

# or sort them by labels
import operator
hl = sorted(zip(handles, labels),
            key=operator.itemgetter(1))
handles2, labels2 = zip(*hl)

ax.legend(handles2, labels2)

Bạn sẽ thấy rằng tôi cần tạo thêm một biến ax. Làm cách nào tôi có thể thêm một chú giải vào biểu đồ của mình mà không phải tạo thêm biến này và giữ lại sự đơn giản của tập lệnh hiện tại của tôi?


Tôi bối rối bởi mối quan tâm của bạn về việc tạo ra một biến phụ. Bạn phải làm cho những đối tượng đằng sau hậu trường nào.
tacaswell

1
@tcaswell Vâng hãy để tôi thử làm dịu chúng. Tôi không muốn tạo thêm các biến, bởi vì nó làm tăng thêm độ phức tạp cho toàn bộ tập lệnh. Tôi đang cố gắng dạy điều này cho một nhóm sinh viên, và vì họ chưa từng sử dụng matplotlibtrước đây, tôi muốn giữ mọi thứ đơn giản nhất có thể. Ngoài ra, nếu bạn xem câu trả lời của Rob, nó đơn giản hơn nhiều so với ví dụ hiển thị trên trang web. Tôi hy vọng điều đó sẽ giúp.
Trò chơi Brainiac

1
Tôi sẽ lập luận rằng việc sử dụng giao diện máy trạng thái làm cho khó hiểu hơn về lâu dài bởi vì rất nhiều thứ đang được thực hiện 'bằng phép thuật'. Ngoài ra, quy ước là sử dụng import matplotlib.pyplot as pltthay vìPyPlot
tacaswell

Câu trả lời:


441

Thêm một label=vào mỗi plot()cuộc gọi của bạn và sau đó gọilegend(loc='upper left') .

Xem xét mẫu này (được thử nghiệm với Python 3.8.0):

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 20, 1000)
y1 = np.sin(x)
y2 = np.cos(x)

plt.plot(x, y1, "-b", label="sine")
plt.plot(x, y2, "-r", label="cosine")
plt.legend(loc="upper left")
plt.ylim(-1.5, 2.0)
plt.show()

nhập mô tả hình ảnh ở đây Sửa đổi một chút từ hướng dẫn này: http://jakevdp.github.io/mpl_tutorial/tutorial_pages/tut1.html


2
Có cách nào để làm điều này nếu bạn không biết nhãn tại thời điểm sê-ri được vẽ? Tức là một cách để thêm nhãn vào một loạt sau khi nó đã được vẽ? Hoặc có thể là một cách để sửa đổi nhãn giữ chỗ trước khi hiển thị chú giải?
davidA

13
plt.legend(loc='upper left')cũng hoạt động, từ đâu pltđến import matplotlib.pyplot as plt.
Matt Kleinsmith

Cảm ơn, @eric, đã lưu ý điều này. Tôi đã cập nhật mã.
Rob

Upvoted vì stack overflow là tuyệt vời và tốt câu trả lời có thể thay đổi
eric

1
@davidA Có, bạn chỉ cần chuyển một danh sách các chuỗi vào plt.legend:plt.legend(['First Label', 'Second Label'])
Apollys hỗ trợ Monica

36

Bạn có thể truy cập vào trường hợp Axes ( ax) với plt.gca(). Trong trường hợp này, bạn có thể sử dụng

plt.gca().legend()

Bạn có thể thực hiện việc này bằng cách sử dụng label=từ khóa trong mỗi plt.plot()cuộc gọi của mình hoặc bằng cách gán nhãn của bạn dưới dạng một tuple hoặc danh sách bên trong legend, như trong ví dụ hoạt động này:

import numpy as np
import matplotlib.pyplot as plt
x = np.linspace(-0.75,1,100)
y0 = np.exp(2 + 3*x - 7*x**3)
y1 = 7-4*np.sin(4*x)
plt.plot(x,y0,x,y1)
plt.gca().legend(('y0','y1'))
plt.show()

pltGcaLegend

Tuy nhiên, nếu bạn cần truy cập vào đối tượng Axes nhiều hơn một lần, tôi khuyên bạn nên lưu nó vào biến axvới

ax = plt.gca()

và sau đó gọi axthay plt.gca().


câu trả lời sao chép không yêu cầu đọc và với một hình ảnh! câu trả lời này xứng đáng nhận được nhiều tín dụng hơn
Gulzar

14

Đây là một ví dụ để giúp bạn ...

fig = plt.figure(figsize=(10,5))
ax = fig.add_subplot(111)
ax.set_title('ADR vs Rating (CS:GO)')
ax.scatter(x=data[:,0],y=data[:,1],label='Data')
plt.plot(data[:,0], m*data[:,0] + b,color='red',label='Our Fitting 
Line')
ax.set_xlabel('ADR')
ax.set_ylabel('Rating')
ax.legend(loc='best')
plt.show()

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


2
Tôi chỉ tò mò, tại sao dòng phù hợp của bạn quá xa dữ liệu?
Apollys hỗ trợ Monica

13

Một cốt truyện đơn giản cho các đường cong sin và cos với một huyền thoại.

Đã sử dụng matplotlib.pyplot

import math
import matplotlib.pyplot as plt
x=[]
for i in range(-314,314):
    x.append(i/100)
ysin=[math.sin(i) for i in x]
ycos=[math.cos(i) for i in x]
plt.plot(x,ysin,label='sin(x)')  #specify label for the corresponding curve
plt.plot(x,ycos,label='cos(x)')
plt.xticks([-3.14,-1.57,0,1.57,3.14],['-$\pi$','-$\pi$/2',0,'$\pi$/2','$\pi$'])
plt.legend()
plt.show()

Âm mưu tội lỗi và Cosine (bấm vào để xem hình ảnh)


6

Thêm nhãn cho mỗi đối số trong lệnh gọi cốt truyện của bạn tương ứng với chuỗi nó đang vẽ đồ thị, nghĩa là label = "series 1"

Sau đó, chỉ cần thêm Pyplot.legend()vào dưới cùng của tập lệnh của bạn và chú giải sẽ hiển thị các nhãn này.


Đây là ý tưởng đúng, nhưng bạn không bao giờ thêm nhãn vì vậy huyền thoại sẽ trống rỗng
tacaswell

4

Bạn có thể thêm một tài liệu truyền thuyết tùy chỉnh

first = [1, 2, 4, 5, 4]
second = [3, 4, 2, 2, 3]
plt.plot(first,'g--', second, 'r--')
plt.legend(['First List','Second List'], loc='upper left')
plt.show()

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


0
    # Dependencies
    import numpy as np
    import matplotlib.pyplot as plt

    #Set Axes
    # Set x axis to numerical value for month
    x_axis_data = np.arange(1,13,1)
    x_axis_data

    # Average weather temp
    points = [39, 42, 51, 62, 72, 82, 86, 84, 77, 65, 55, 44]

    # Plot the line
    plt.plot(x_axis_data, points)
    plt.show()

    # Convert to Celsius C = (F-32) * 0.56
    points_C = [round((x-32) * 0.56,2) for x in points]
    points_C

    # Plot using Celsius
    plt.plot(x_axis_data, points_C)
    plt.show()

    # Plot both on the same chart
    plt.plot(x_axis_data, points)
    plt.plot(x_axis_data, points_C)

    #Line colors
    plt.plot(x_axis_data, points, "-b", label="F")
    plt.plot(x_axis_data, points_C, "-r", label="C")

    #locate legend
    plt.legend(loc="upper left")
    plt.show()
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.