4

I am try to work out with my atomic composition with ternary phase diagram, here is my picture

enter image description here

I wish to put my scale to the ticks on the ternary phase diagram (i.e. those triangular axis) instead of x and y axis. Is there a ways to put the scale on the tick at triangular axis instead of axis x and y? How to remove the x-axis and y-axis while still maintain its labels?

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()
scleronomic
  • 4,392
  • 1
  • 13
  • 43

1 Answers1

0

As was mentioned in the comments you can make your own axis just by adding a text to the ticks you generate. Most of the time you need a little tweaking to get the offsets right...


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)

In addition I switched the axis off via ax.set_axis_off() and I also deleted the twin axis, as you used these only to display the ticks and labels for the connections. These labels can also easily be placed via fig.text() as you did with the corners:

# 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

triangle ticks

scleronomic
  • 4,392
  • 1
  • 13
  • 43