2013-07-09 39 views
15

Tôi vẽ hai subplots với Matplotlib, về cơ bản sau đây:dòng Vẽ giữa hai lô trong Matplotlib

subplot(211); imshow(a); scatter(..., ...) 
subplot(212); imshow(b); scatter(..., ...) 

Tôi có thể vẽ ranh giới giữa hai ô phụ? Tôi sẽ làm như thế nào?

+1

Nghi ngờ bạn có thể làm điều này với 'annotate'. – tacaswell

Trả lời

6

Giải pháp từ các câu trả lời khác là tối ưu trong nhiều trường hợp (vì chúng chỉ hoạt động nếu không có thay đổi nào đối với cốt truyện sau khi tính toán điểm).

Một giải pháp tốt hơn sẽ sử dụng thiết kế đặc biệt ConnectionPatch:

import matplotlib.pyplot as plt 
from matplotlib.patches import ConnectionPatch 
import numpy as np 

fig = plt.figure(figsize=(10,5)) 
ax1 = fig.add_subplot(121) 
ax2 = fig.add_subplot(122) 

x,y = np.random.rand(100),np.random.rand(100) 

ax1.plot(x,y,'ko') 
ax2.plot(x,y,'ko') 

i = 10 
xy = (x[i],y[i]) 
con = ConnectionPatch(xyA=xy, xyB=xy, coordsA="data", coordsB="data", 
         axesA=ax2, axesB=ax1, color="red") 
ax2.add_artist(con) 

ax1.plot(x[i],y[i],'ro',markersize=10) 
ax2.plot(x[i],y[i],'ro',markersize=10) 


plt.show() 

enter image description here

+0

Điểm tốt. Điều này thực sự hoạt động tốt hơn so với câu trả lời được chấp nhận trước đó, vì vậy tôi sẽ chấp nhận nó thay thế. Cảm ơn! –

+0

Đó là giá trị nhận xét về lý do tại sao 'ax2.add_artist' nằm trên' ax2' thay vì 'ax1' github.com/matplotlib/matplotlib/issues/8744 và tại sao' axesA' được đặt thành 'ax2' – Joel

22

Bạn có thể sử dụng fig.line. Nó thêm bất kỳ dòng nào vào hình của bạn. Các dòng hình là mức cao hơn các đường trục, do đó bạn không cần bất kỳ trục nào để vẽ nó.

Ví dụ này đánh dấu cùng một điểm trên hai trục. Cần phải cẩn thận với hệ tọa độ, nhưng biến đổi làm tất cả công việc khó khăn cho bạn.

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

fig = plt.figure(figsize=(10,5)) 
ax1 = fig.add_subplot(121) 
ax2 = fig.add_subplot(122) 

x,y = np.random.rand(100),np.random.rand(100) 

ax1.plot(x,y,'ko') 
ax2.plot(x,y,'ko') 

i = 10 

transFigure = fig.transFigure.inverted() 

coord1 = transFigure.transform(ax1.transData.transform([x[i],y[i]])) 
coord2 = transFigure.transform(ax2.transData.transform([x[i],y[i]])) 


line = matplotlib.lines.Line2D((coord1[0],coord2[0]),(coord1[1],coord2[1]), 
           transform=fig.transFigure) 
fig.lines = line, 

ax1.plot(x[i],y[i],'ro',markersize=20) 
ax2.plot(x[i],y[i],'ro',markersize=20) 


plt.show() 

enter image description here

+5

có lẽ tốt hơn để làm 'fig.lines.append (line)' để không thổi bay bất cứ thứ gì đã có. – tacaswell

+0

Ví dụ được nhiều đánh giá cao, tôi đã không hiểu sự biến đổi Matplotlib đã đi đâu trước đó! @tcaswell là đúng mặc dù, tôi chỉ cần nhìn lên [docs] (http://matplotlib.org/users/annotations_guide.html#using-connectorpatch) trên 'chú thích', và' ConnectorPatch' dường như chính xác những gì tôi tìm kiếm, vì vậy tôi sẽ thử nó và quay lại sau! –

+0

Giải pháp rất đẹp. Tuy nhiên tôi đã có đường vẽ ở tọa độ sai với jupyter. Giải pháp là thêm 'fig.canvas.draw()' trước khi gọi 'transFigure = fig.transFigure.inverted()' để làm việc với các tọa độ chính xác. – scholi

1

Tôi không chắc chắn nếu điều này là chính xác những gì bạn đang tìm kiếm, nhưng một thủ thuật đơn giản để vẽ trên ô phụ.

import matplotlib.pyplot as plt 
import numpy as np 

ax1=plt.figure(1).add_subplot(211) 
ax2=plt.figure(1).add_subplot(212) 

x_data=np.linspace(0,10,20) 
ax1.plot(x_data, x_data**2,'o') 
ax2.plot(x_data, x_data**3, 'o') 

ax3 = plt.figure(1).add_subplot(111) 
ax3.plot([5,5],[0,1],'--') 
ax3.set_xlim([0,10]) 
ax3.axis("off") 
plt.show() 
Các vấn đề liên quan