在Matplotlib中调整坐标轴夹角至60度的实现问题
解决Matplotlib中调整坐标轴夹角并同步散点位置的问题
你之前的代码仅调整了坐标轴的显示变换,但散点坐标未应用同样的规则,导致点位置不变。要实现原点、(1,0)、(0,1)构成等边三角形,需要让散点坐标和坐标轴按相同逻辑转换。
方法一:手动转换坐标(直观易控)
直接将原始(x,y)坐标映射为符合60度夹角的笛卡尔坐标,再绘制自定义斜坐标轴:
import matplotlib.pyplot as plt import numpy as np # 原始数据 x = [0.41729137, 0.31693662, 0.25544209, 0.13843966, 0.31218805,0.01035702, 0.4847026 , 0.11104309, 0.25144685, 0.18332651] y = [0.20372773, 0.5395082 , 0.6020569 , 0.19787512, 0.57743819,0.93317626, 0.43035489, 0.8235019 , 0.36000727, 0.24365175] # 坐标转换规则:让(0,1)映射到(0.5, √3/2),保证与(1,0)、原点构成等边三角形 cos60 = 0.5 sin60 = np.sqrt(3)/2 new_x = [xi + yi * cos60 for xi, yi in zip(x, y)] new_y = [yi * sin60 for yi in y] fig, ax = plt.subplots() ax.scatter(new_x, new_y, color='#1f77b4') # 绘制自定义斜坐标轴 ax.plot([0, 1], [0, 0], 'k-', linewidth=1.5) # x轴 ax.plot([0, cos60], [0, sin60], 'k-', linewidth=1.5) # y轴 # 标注坐标轴 ax.text(1.02, 0, 'x', ha='left', va='center') ax.text(cos60, sin60+0.02, 'y', ha='center', va='bottom') # 设置显示范围 ax.set_xlim(-0.15, 1.15) ax.set_ylim(-0.15, 1.0) # 隐藏默认笛卡尔坐标轴 ax.spines[['top', 'right', 'left']].set_visible(False) ax.yaxis.set_visible(False) plt.show()
方法二:利用FloatingAxes的变换(保留网格刻度)
修正你原有的代码,给散点坐标应用定义好的变换矩阵:
import matplotlib.pyplot as plt from matplotlib.transforms import Affine2D import mpl_toolkits.axisartist.floating_axes as floating_axes import numpy as np fig = plt.figure() plot_extents = 0, 1, 0, 1 # 定义正确的变换矩阵:等价于x'=x+0.5y,y'=y*(√3/2) cos60 = 0.5 sin60 = np.sqrt(3)/2 transform = Affine2D.from_values(1, cos60, 0, sin60, 0, 0) helper = floating_axes.GridHelperCurveLinear(transform, plot_extents) ax = floating_axes.FloatingSubplot(fig, 111, grid_helper=helper) fig.add_axes(ax) # 原始数据 x = [0.41729137, 0.31693662, 0.25544209, 0.13843966, 0.31218805,0.01035702, 0.4847026 , 0.11104309, 0.25144685, 0.18332651] y = [0.20372773, 0.5395082 , 0.6020569 , 0.19787512, 0.57743819,0.93317626, 0.43035489, 0.8235019 , 0.36000727, 0.24365175] # 将原始坐标应用变换后绘制 x_transformed, y_transformed = transform.transform(np.array([x, y]).T).T ax.scatter(x_transformed, y_transformed, color='#1f77b4') # 设置显示范围 ax.set_xlim(-0.15, 1.15) ax.set_ylim(-0.15, 1.15) plt.show()
关键说明
你原代码的核心问题是:floating_axes只给坐标轴和网格应用了变换,但ax.scatter默认使用原始笛卡尔坐标系绘制点。必须将变换矩阵同时应用到散点坐标上,才能让点和坐标轴同步变换,形成目标等边三角形区域。
内容的提问来源于stack exchange,提问作者Matthew Leingang
相关产品推荐
相关产品推荐

