2012-04-25 45 views
5

Tôi muốn có một số đường lưới trên một ô, nhưng thực sự các dòng có độ dài đầy đủ là quá nhiều/mất tập trung, thậm chí là các đường màu xám nhạt. Tôi đã đi và tự làm một số chỉnh sửa của đầu ra SVG để có được hiệu quả tôi đang tìm kiếm. Điều này có thể được thực hiện với matplotlib? Tôi đã có một cái nhìn tại api pyplot cho lưới điện, và điều duy nhất tôi có thể thấy rằng có thể có được để có được gần đó là xdata và ydata Line2D kwargs.Thay vì các đường lưới trên một ô, có thể in lưới chéo matplotlib?

enter image description here

Trả lời

3

này không thể được thực hiện thông qua các API cơ bản, bởi vì các đường lưới được tạo ra sử dụng chỉ hai điểm. Các đường lưới sẽ cần một điểm 'dữ liệu' ở mọi dấu tick để có một điểm đánh dấu được vẽ. Này được thể hiện trong ví dụ sau:

import matplotlib.pyplot as plt 

ax = plt.subplot(111) 
ax.grid(clip_on=False, marker='o', markersize=10) 
plt.savefig('crosses.png') 
plt.show() 

Điều này dẫn đến:

enter image description here

Thông báo như thế nào 'o' dấu chỉ ở đầu và cuối của các cạnh Axes, bởi vì các đường lưới chỉ liên quan đến hai điểm.

Bạn có thể viết một phương thức mô phỏng những gì bạn muốn, tạo dấu chéo bằng cách sử dụng một loạt Artists, nhưng sẽ nhanh hơn khi tận dụng khả năng vẽ sơ đồ cơ bản để vẽ mẫu chéo.

Đây là những gì tôi làm trong ví dụ sau:

import matplotlib.pyplot as plt 
import numpy as np 

NPOINTS=100 

def set_grid_cross(ax, in_back=True): 
    xticks = ax.get_xticks() 
    yticks = ax.get_yticks() 
    xgrid, ygrid = np.meshgrid(xticks, yticks) 
    kywds = dict() 
    if in_back: 
     kywds['zorder'] = 0 
    grid_lines = ax.plot(xgrid, ygrid, 'k+', **kywds) 

xvals = np.arange(NPOINTS) 
yvals = np.random.random(NPOINTS) * NPOINTS 

ax1 = plt.subplot(121) 
ax2 = plt.subplot(122) 

ax1.plot(xvals, yvals, linewidth=4) 
ax1.plot(xvals, xvals, linewidth=7) 
set_grid_cross(ax1) 
ax2.plot(xvals, yvals, linewidth=4) 
ax2.plot(xvals, xvals, linewidth=7) 
set_grid_cross(ax2, in_back=False) 

plt.savefig('gridpoints.png') 
plt.show() 

Điều này dẫn đến hình sau:

enter image description here

Như bạn thấy, tôi mất dấu tick trong x và y để xác định một loạt các điểm mà tôi muốn đánh dấu lưới ('+'). Tôi sử dụng meshgrid để lấy hai mảng 1D và tạo 2 mảng 2D tương ứng với vòng lặp đôi trên mỗi điểm lưới. Tôi vẽ nó với phong cách đánh dấu là '+', và tôi đã hoàn thành ... gần như. Điều này vẽ các thánh giá trên đầu trang và tôi đã thêm một từ khóa bổ sung để sắp xếp lại danh sách các dòng liên kết với cốt truyện. Tôi điều chỉnh zorder của các điểm đánh dấu lưới nếu chúng được vẽ phía sau mọi thứ. *****

Ví dụ hiển thị subplot bên trái theo mặc định lưới được đặt ở phía sau và subplot bên phải vô hiệu hóa tùy chọn này. Bạn có thể nhận thấy sự khác biệt nếu bạn theo dòng màu xanh lá cây trong mỗi ô.

Nếu bạn đang làm phiền bởi có lưới đi qua trên học sinh nội trú, bạn có thể loại bỏ các dấu ngoặc đánh dấu đầu tiên và cuối cùng cho cả x và y trước khi bạn xác định lưới điện trong set_grid_cross, như vậy:

xticks = ax.get_xticks()[1:-1] #< notice the slicing 
yticks = ax.get_yticks()[1:-1] #< notice the slicing 
xgrid, ygrid = np.meshgrid(xticks, yticks) 

tôi làm này trong ví dụ sau, sử dụng một lớn hơn, đánh dấu khác nhau để làm cho quan điểm của tôi:

enter image description here

***** Nhờ có câu trả lời bằng @fraxel cho trỏ này ra.

+0

nhiều thông tin và sáng tạo! Và kwargs có thể được sử dụng để thiết lập màu sắc và kích thước chi tiết hơn. –

+0

Cũng có vấn đề là nó đánh dấu các dấu mốc ở các trục. Nếu tôi chỉ có thể cắt xgrid, mảng ygrid –

3

Bạn có thể vẽ trên các đoạn đường tại mỗi điểm giao nhau của các điểm đánh dấu.Nó khá dễ làm, chỉ cần lấy các vị trí đánh dấu get_ticklocs() cho cả hai trục, sau đó lặp qua tất cả các kết hợp, vẽ các đoạn đường ngắn bằng cách sử dụng axhlineaxvline, do đó tạo ra một sợi ngang ở mọi giao lộ. Tôi đã đặt zorder=0 để các sợi ngang được vẽ đầu tiên, sao cho chúng nằm phía sau dữ liệu lô. Dễ dàng kiểm soát kích thước màu/alpha và tóc chéo. Cặp đôi 'gotchas' nhẹ nhàng ... làm cốt truyện trước khi bạn có được vị trí đánh dấu .. và cũng có các thông số xminxmax dường như yêu cầu chuẩn hóa.

import matplotlib.pyplot as plt 

fig = plt.figure() 
ax = fig.add_subplot(1,1,1)  
ax.plot((0,2,3,5,5,5,6,7,8,6,6,4,3,32,7,99), 'r-',linewidth=4) 

x_ticks = ax.xaxis.get_ticklocs() 
y_ticks = ax.yaxis.get_ticklocs()  
for yy in y_ticks[1:-1]: 
    for xx in x_ticks[1:-1]: 
     plt.axhline(y=yy, xmin=xx/max(x_ticks) - 0.02, 
       xmax=xx/max(x_ticks) + 0.02, color='gray', alpha=0.5, zorder=0) 
     plt.axvline(x=xx, ymin=yy/max(y_ticks) - 0.02, 
       ymax=yy/max(y_ticks) + 0.02, color='gray', alpha=0.5, zorder=0) 
plt.show() 

enter image description here

+0

Tuyệt vời! Rất linh hoạt để tinh chỉnh kích thước/chiều dài của thánh giá. Bạn đang đúng về bit bình thường hóa, sẽ phải làm việc trên nhận tỷ lệ đúng, đặc biệt là cho các kích thước hình vuông không vuông. Tôi thấy rằng có thêm đường ở các trục nơi các dấu tick cũng vậy, vì vậy sẽ cố gắng loại bỏ chúng. –

+0

@a khác nhau ben - Hey, đã không nhận thấy về thập giá trên trục x và y! Tôi đã cập nhật để loại bỏ chúng với lát. Và vâng, các giá trị tối thiểu và tối đa phụ thuộc vào kích thước lô thay vì giá trị trục là một giá trị rất lạ! – fraxel

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