2012-03-14 37 views

Trả lời

44

Dưới đây là một ví dụ đơn giản về cách để làm điều đó:

import numpy as np 
import matplotlib.pyplot as plt 

# make some data 
x = np.linspace(0, 2*np.pi) 
y1 = np.sin(x) 
y2 = np.cos(x) 

# plot sin(x) and cos(x) 
p1 = plt.plot(x, y1, 'b-', linewidth=1.0) 
p2 = plt.plot(x, y2, 'r-', linewidth=1.0) 

# make a legend for both plots 
leg = plt.legend([p1, p2], ['sin(x)', 'cos(x)'], loc=1) 

# set the linewidth of each legend object 
for legobj in leg.legendHandles: 
    legobj.set_linewidth(2.0) 

plt.show() 
3

Nếu bạn muốn thay đổi tất cả các dòng trong một âm mưu, nó có thể có ích để xác định xử lý huyền thoại của riêng bạn:

import matplotlib.pyplot as plt 
from matplotlib import legend_handler 
from matplotlib.lines import Line2D 
import numpy as np 

class MyHandlerLine2D(legend_handler.HandlerLine2D): 
    def create_artists(self, legend, orig_handle, 
         xdescent, ydescent, width, height, fontsize, 
         trans): 

     xdata, xdata_marker = self.get_xdata(legend, xdescent, ydescent, 
              width, height, fontsize) 

     ydata = ((height-ydescent)/2.)*np.ones(xdata.shape, float) 
     legline = Line2D(xdata, ydata) 

     self.update_prop(legline, orig_handle, legend) 
     #legline.update_from(orig_handle) 
     #legend._set_artist_props(legline) # after update 
     #legline.set_clip_box(None) 
     #legline.set_clip_path(None) 
     legline.set_drawstyle('default') 
     legline.set_marker("") 
     legline.set_linewidth(10) 


     legline_marker = Line2D(xdata_marker, ydata[:len(xdata_marker)]) 
     self.update_prop(legline_marker, orig_handle, legend) 
     #legline_marker.update_from(orig_handle) 
     #legend._set_artist_props(legline_marker) 
     #legline_marker.set_clip_box(None) 
     #legline_marker.set_clip_path(None) 
     legline_marker.set_linestyle('None') 
     if legend.markerscale != 1: 
      newsz = legline_marker.get_markersize()*legend.markerscale 
      legline_marker.set_markersize(newsz) 
     # we don't want to add this to the return list because 
     # the texts and handles are assumed to be in one-to-one 
     # correpondence. 
     legline._legmarker = legline_marker 

     return [legline, legline_marker] 


plt.plot([0, 1], [0, 1], '-r', lw=1, label='Line') 
plt.legend(handler_map={Line2D:MyHandlerLine2D()}) 

plt.show() 
2

Phương pháp của @Brendan Wood sử dụng api được cung cấp bởi pyplot. Trong matplotlib, object oriented style using axes is prefered. Sau đây là cách bạn có thể đạt được điều này bằng phương pháp axes.

import numpy as np 
import matplotlib.pyplot as plt 

# make some data 
x = np.linspace(0, 2*np.pi) 
y1 = np.sin(x) 
y2 = np.cos(x) 

fig, ax = plt.subplots() 
ax.plot(x, y1, linewidth=1.0, label='sin(x)') 
ax.plot(x, y2, linewidth=1.0, label='cos(x)') 
leg = ax.legend() 

for line in leg.get_lines(): 
    line.set_linewidth(4.0) 

plt.show() 

Cốt truyện được sản xuất được hiển thị dưới đây, enter image description here

1

Theo mặc định, huyền thoại chứa các dòng họ. Do đó việc thay đổi độ rộng của các dòng trong canvas cũng sẽ thay đổi các dòng trong chú giải (và ngược lại, vì chúng chủ yếu là cùng một đối tượng).

Một giải pháp khả thi là sử dụng bản sao của nghệ sĩ từ canvas và chỉ thay đổi độ rộng của bản sao.

import numpy as np 
import matplotlib.pyplot as plt 
import copy 

x = np.linspace(0, 2*np.pi) 
y1 = np.sin(x) 
y2 = np.cos(x) 
fig = plt.figure() 
ax = fig.add_subplot(111) 
ax.plot(x, y1, c='b', label='y1',linewidth=1.0) 
ax.plot(x, y2, c='r', label='y2') 

# obtain the handles and labels from the figure 
handles, labels = ax.get_legend_handles_labels() 
# copy the handles 
handles = [copy.copy(ha) for ha in handles ] 
# set the linewidths to the copies 
[ha.set_linewidth(7) for ha in handles ] 
# put the copies into the legend 
leg = plt.legend(handles=handles, labels=labels) 

plt.savefig('leg_example') 
plt.show() 

enter image description here

Một lựa chọn khác nhau sẽ được sử dụng một và một chức năng handler_map cập nhật. Điều này là bằng cách nào đó tự động, xác định bản đồ xử lý sẽ tự động làm cho bất kỳ dòng trong huyền thoại 7 điểm rộng.

import numpy as np 
import matplotlib.pyplot as plt 
from matplotlib.legend_handler import HandlerLine2D 

x = np.linspace(0, 2*np.pi) 
y1 = np.sin(x) 
y2 = np.cos(x) 
fig = plt.figure() 
ax = fig.add_subplot(111) 
ax.plot(x, y1, c='b', label='y1',linewidth=1.0) 
ax.plot(x, y2, c='r', label='y2') 

linewidth=7 
def update(handle, orig): 
    handle.update_from(orig) 
    handle.set_linewidth(7) 

plt.legend(handler_map={plt.Line2D : HandlerLine2D(update_func=update)}) 

plt.show() 

Kết quả giống như trên.

+0

đẹp, tôi đã tìm kiếm điều này trước đó. Hy vọng nó được chấp nhận ở đây;] – Alnitak

+0

@Alnitak Tôi đã cập nhật câu trả lời này với một tùy chọn khác. – ImportanceOfBeingErnest

Các vấn đề liên quan