หมุนเมทริกซ์ด้วย Matplotlib
ฉันกำลังหมุนเมทริกซ์กังวล (n = 20 แม้ว่ามันจะเปลี่ยนแปลงได้) 30 องศาไปทางขวาโดยใช้วิธีการแปลงของ Matplotlib
ข้อผิดพลาดจะแสดงขึ้นเพราะการหมุน perfomed จากด้านบนและไม่ได้มาจากฐาน ผมได้พยายามที่จะผกผันดัชนีผ่านnp.flip()หรือax.imshow(origin = 'lower')แต่ก็ยังกลับสามเหลี่ยมดังนั้นฉันต้องการที่จะค้นพบวิธีการตั้งค่าจุดกำเนิดการเปลี่ยนแปลง
Defintley นี่คือสิ่งที่ฉันต้องการได้รับ :
โปรดสังเกตว่าสี่เหลี่ยมเล็ก ๆ ที่สอดคล้องกับเมทริกซ์แนวทแยงมุมจะกลายเป็นสามเหลี่ยม สามารถทำได้หรือไม่? อาจจะใช้วิธี imshow ที่ส่งกลับครึ่งพิกเซล? ส่วนที่เหลือของพิกเซลจะยังคงเหมือนเดิม (สี่เหลี่ยมเล็ก ๆ ที่ผิดรูป)
นี่คือรหัสสำหรับสร้างเมทริกซ์ ( จุดเริ่มต้น ):
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.transforms as mtransforms
matrix = np.random.rand(20,20)
# Generate a boolean matrix (same shape than 'matrix') and select lower triangle values:
condition = np.tril(np.ones((matrix.shape))).astype(np.bool)
triangle = np.where(condition, matrix, np.nan)
fig, ax = plt.subplots(figsize = (8,8))
ax.imshow(triangle, cmap = 'Spectral')
และนี่คือรหัสที่พยายามหมุน :
im = ax.imshow(matrix, cmap = 'Spectral')
im.set_transform(mtransforms.Affine2D().skew(30, 0) + ax.transData)
ax.plot(transform = trans_data)
ฉันไม่ได้ใช้คลาสสามเหลี่ยมของ Matplotlib เนื่องจากไดอะแกรมด้านท้ายถูกแสดงผ่านการดำเนินการแก้ไขและฉันต้องการแทนค่าเมทริกซ์ดั้งเดิม
ฉันขอขอบคุณสำหรับความช่วยเหลือบางส่วน ขอบคุณล่วงหน้า.
คำตอบ
แทนที่จะเปลี่ยนจุดเริ่มต้นของการแปลงแบบเบ้คุณสามารถเชื่อมโยงด้วยการแปลในทิศทาง x เพื่อให้ได้การเปลี่ยนแปลงที่คุณกำลังมองหา
โปรดทราบว่าการskewแปลงจะทำมุมเป็นเรเดียน (คุณใช้กับองศา) มีการskew_degแปลงที่เทียบเท่ากันหากคุณต้องการทำงานเป็นองศา แต่ที่นี่ฉันทำงานเป็นเรเดียน
โปรดทราบว่าฉันคิดว่าคุณต้องการมีสามเหลี่ยมหน้าจั่วที่มีฐานและความสูงเท่ากับ 20 (หรืออะไรก็ได้ที่คุณเลือกให้เป็น N) มุมที่คุณต้องการไม่ใช่ 30 องศา แต่จริงๆแล้วอาร์กแทน (1/2) (= 26.56 องศา)
จำนวนเงินที่คุณจำเป็นต้องแปลในทิศทาง x xtrans = N * np.tan(angle)คือ
คุณสามารถเชื่อมโยงการแปลงได้อย่างง่ายดายใน matplotlib ที่นี่เราสามารถเบ้ก่อนแล้วแปล:
mtransforms.Affine2D().skew(-angle, 0).translate(xtrans, 0)
โปรดทราบว่าสคริปต์นี้ใช้ได้กับค่าใด ๆ ของ N
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.transforms as mtransforms
N = 20
matrix = np.random.rand(N, N)
# Generate a boolean matrix (same shape than 'matrix') and select lower triangle values:
condition = np.tril(np.ones((matrix.shape))).astype(np.bool)
triangle = np.where(condition, matrix, np.nan)
fig, ax = plt.subplots(figsize = (8,8))
im = ax.imshow(triangle, cmap = 'Spectral')
angle = np.arctan(1/2)
xtrans = N * np.tan(angle)
im.set_transform(mtransforms.Affine2D().skew(-angle, 0).translate(xtrans, 0) + ax.transData)
ax.set_xlim(-0.5, N + 0.5)
plt.show()
สำหรับ N = 20
และสำหรับ N = 30
ในที่สุดฉันก็ได้รับสามเหลี่ยมด้านเท่ามาตราส่วน y -axis ที่นี่ฉันแสดงรหัส
ดังนั้นจึงอนุญาตให้แปลงเมทริกซ์เป็นรูปสามเหลี่ยมด้านเท่าสิ่งที่ตอบคำถามก่อนหน้าของฉัน:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.transforms as mtransforms
import matplotlib
bins = 50
Z = np.random.rand(bins, bins)
# Generate a boolean matrix (same shape than 'matrix') and select lower triangle values:
condition = np.tril(np.ones((Z.shape))).astype(np.bool)
Z = np.where(condition, Z, np.nan)
fig, ax = plt.subplots(figsize = (8,8))
im = ax.imshow(Z, cmap = 'Spectral')
# Required angles (in Rad)
alpha = np.arctan(1/2) # 26 deg angle, in radians.
beta = np.arctan(np.pi/6) # 30 deg angle, in radians.
# Coefficients:
xtrans = np.sin(beta) * bins
scale_y = np.cos(beta)
# Transformation:
im.set_transform(mtransforms.Affine2D().skew (-alpha, 0)
.scale (1,scale_y)
.translate (xtrans, 0)
+ ax.transData)
ax.set_ylim(bins,-5)
ax.set_xlim(-5,bins)
plt.show()