如何在三元图中的刻度上而不是 x 和 y 轴上进行缩放

Posted

技术标签:

【中文标题】如何在三元图中的刻度上而不是 x 和 y 轴上进行缩放【英文标题】:How to put the scaling on the ticks in ternary plot instead of x and y axis 【发布时间】:2018-05-31 21:52:55 【问题描述】:

我正在尝试用三元相图来计算我的原子组成,这是我的照片

我希望将我的刻度放在三元相图(即那些三角轴)上的刻度上,而不是 x 和 y 轴。有没有办法将刻度放在三角轴上而不是轴 x 和 y 上?如何在保留标签的同时删除 x 轴和 y 轴?

from __future__ import division
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.tri as tri

def plot_ticks(start, stop, tick, n):
    r = np.linspace(0, 1, n+1)
    x = start[0] * (1 - r) + stop[0] * r
    x = np.vstack((x, x + tick[0]))
    y = start[1] * (1 - r) + stop[1] * r
    y = np.vstack((y, y + tick[1]))
    plt.plot(x, y, 'k', lw=1)

n = 5
tick_size = 0.1
margin = 0.05

# define corners of triangle    
left = np.r_[0, 0]
right = np.r_[1, 0]
top = np.r_[0.5, np.sqrt(3)*0.576]
triangle = np.c_[left, right, top, left]

# define corners of triangle    
left = np.r_[0, 0]
right = np.r_[1, 0]
top = np.r_[0.5, np.sqrt(3)*0.576]
triangle = np.c_[left, right, top, left]

# define vectors for ticks
bottom_tick = 0.8264*tick_size * (right - top) / n
right_tick = 0.8264*tick_size * (top - left) / n
left_tick = 0.8264*tick_size * (left - right) / n

# first load some data:  format x1,x2,x3,value
test_data = np.array([[4,0,0,2.238],
                      [0,4,0,2.315],
                      [0,0,4,2.147],
                      [3,1,0,2.494],
                      [2,2,0,2.190],
                      [2,2,0,2.632],
                      [3,0,1,2.173],
                      [2,0,2,2.329],
                      [1,0,3,2.526],
                      [0,3,1,2.365],
                      [0,2,2,2.220],
                      [0,1,3,2.080],
                      [2,1,1,2.231],
                      [1,2,1,2.291],
                      [1,1,2,2.088]])

#Define twin axis
#ax = plt.gca()
fig, ax = plt.subplots()
plot_ticks(left, right, bottom_tick, n)
plot_ticks(right, top, right_tick, n)
plot_ticks(left, top, left_tick, n)
#ax2 = ax.twinx()

# barycentric coords: (a,b,c)
a=test_data[:,0]
b=test_data[:,1]
c=test_data[:,2]

# values is stored in the last column
v = test_data[:,-1]

# translate the data to cartesian corrds
x = 0.5 * ( 2.*b+c ) / ( a+b+c )
y = 0.576*np.sqrt(3) * c / (a+b+c)


# create a triangulation out of these points
T = tri.Triangulation(x,y)

# plot the contour
plt.tricontourf(x,y,T.triangles,v,cmap='jet')


# create the grid
corners = np.array([[0, 0], [1, 0], [0.5,  np.sqrt(3)*0.576]])
triangle = tri.Triangulation(corners[:, 0], corners[:, 1])

# creating the grid
refiner = tri.UniformTriRefiner(triangle)
trimesh = refiner.refine_triangulation(subdiv=4)

#plotting the mesh and caliberate the axis
plt.triplot(trimesh,'k--')
#plt.title('Binding energy peratom of Al-Ti-Ni clusters')
ax.set_xlabel('Al-Ti',fontsize=12,color='black')
ax.set_ylabel('Ti-Ni',fontsize=12,color='black')
ax2 = ax.twinx()
ax2.set_ylabel('Al-Ni',fontsize=12,color='black')
plt.gcf().text(0.07, 0.05, 'Ti', fontsize=12,color='black')
plt.gcf().text(0.93, 0.05, 'Al', fontsize=12,color='black')
plt.gcf().text(0.5, 0.9, 'Ni', fontsize=12,color='black')

#set scale for axis
ax.set_xlim(1, 0)
ax.set_ylim(0, 1)
ax2.set_ylim(1, 0)

cax = plt.axes([0.75, 0.55, 0.055, 0.3])
plt.colorbar(cax=cax,format='%.3f')
plt.savefig("AID.png", dpi=1000)
plt.show()

【问题讨论】:

我猜你忘了问一个问题。有什么问题? 有没有办法将刻度放在三角轴而不是轴 x 和 y 上的刻度上? 如果我理解正确,您已经找到了定位刻度的方法。在它们旁边放置一些文本应该是同样可能的(ax.text(x,y,str(y)) 或类似的)。 【参考方案1】:

正如 cmets 中提到的,您可以通过在生成的刻度上添加文本来制作自己的轴。大多数时候你需要一点点调整 获得正确的偏移量...


def plot_ticks(start, stop, tick, n, offset=(.0, .0)):
    r = np.linspace(0, 1, n+1)
    x = start[0] * (1 - r) + stop[0] * r
    x = np.vstack((x, x + tick[0]))
    y = start[1] * (1 - r) + stop[1] * r
    y = np.vstack((y, y + tick[1]))
    plt.plot(x, y, 'k', lw=1)
    
    # add tick labels
    for xx, yy, rr in zip(x[1], y[1], r):
        plt.text(xx+offset[0], yy+offset[1], ":.2".format(rr))

# Note that the ordering from start to stop is important for the tick labels
plot_ticks(right, left, bottom_tick, n, offset=(0, -0.04))
plot_ticks(left, top, left_tick, n, offset=(-0.06, -0.0))
plot_ticks(top, right, right_tick, n)

此外,我通过ax.set_axis_off() 关闭了轴,还删除了双轴,因为您仅使用它们来显示连接的刻度和标签。这些标签也可以通过fig.text() 轻松放置,就像您对角所做的那样:

# Corners
fig.text(0.07, 0.05, 'Ti', fontsize=12, color='black')
fig.text(0.93, 0.05, 'Al', fontsize=12, color='black')
fig.text(0.50, 0.90, 'Ni', fontsize=12, color='black')

# Connections
fig.text(0.47, 0.05, 'Ti-Al', fontsize=12, color='black')  # Note: not sure about
fig.text(0.72, 0.50, 'Al-Ni', fontsize=12, color='black')  # the nomenclature;
fig.text(0.25, 0.50, 'Ti-Ni', fontsize=12, color='black')  # might be switched

【讨论】:

以上是关于如何在三元图中的刻度上而不是 x 和 y 轴上进行缩放的主要内容,如果未能解决你的问题,请参考以下文章

如何更改 plot.zoo 图中的(数量)x 轴刻度? (轴()失败)

如何使用 Plotly 删除堆叠和分组条形图中的 x 轴刻度标签

自定义刻度线/标签出现在曲面图中的x和y轴上?

如何在绘图图中整齐地或以一定间隔的形式显示 X 轴日期刻度

excel折线图中怎么设置不等距的Y轴,可以设置吗?

使用 Seaborn 和 Matplotlib 在热图和线图的共享子图中对齐 x 轴刻度