import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
from matplotlib import rc, rcParams
from matplotlib.patches import Patch
import matplotlib.ticker as mtick
mpl.rcParams['figure.autolayout'] = False
mpl.rcParams['figure.constrained_layout.use'] = False
plt.close('all')
# -----------------------------
# 0) Font & style
# -----------------------------
font = 16
rc('text', usetex=False)
rc('font', family='Arial')
rcParams['font.size'] = font
mpl.rcParams['axes.linewidth'] = 1.5
# -----------------------------
# 1) Data
# -----------------------------
materials = ['MnO', 'FeO', 'CoO', 'NiO']
params_uv = [r"$U_{TM}$", r"$V_{TM,O}$"]
params_eg = ["E$_{g}$"]
params_mu = [r"$\mu_B$"]
comboOrder = [
('LRT', 'DFT+U'),
('eACBN0', 'DFT+U'),
('LRT', 'DFT+U+V'),
('eACBN0','DFT+U+V'),
]
color_map = {'LRT':'green', 'eACBN0':'darkorange'}
hatch_map = {'DFT+U':'', 'DFT+U+V':'//'}
data = {
('MnO', r"$U_{TM}$"): {('LRT','DFT+U'): 5.01, ('eACBN0','DFT+U'):4.94, ('LRT','DFT+U+V'): 5.03, ('eACBN0','DFT+U+V'):5.15},
('MnO', r"$V_{TM,O}$"): {('LRT','DFT+U'): 0.0, ('eACBN0','DFT+U'):0.0, ('LRT','DFT+U+V'): 0.39, ('eACBN0','DFT+U+V'):2.73},
('MnO', "E$_{g}$"): {('LRT','DFT+U'): 2.03, ('eACBN0','DFT+U'):2.03, ('LRT','DFT+U+V'): 2.02, ('eACBN0','DFT+U+V'):1.94},
('MnO', r"$\mu_B$"): {('LRT','DFT+U'): 4.72, ('eACBN0','DFT+U'):4.72, ('LRT','DFT+U+V'): 4.71, ('eACBN0','DFT+U+V'):4.61},
('FeO', r"$U_{TM}$"): {('LRT','DFT+U'): 8.50, ('eACBN0','DFT+U'):6.04, ('LRT','DFT+U+V'): 8.39, ('eACBN0','DFT+U+V'):6.11},
('FeO', r"$V_{TM,O}$"): {('LRT','DFT+U'): 0.0, ('eACBN0','DFT+U'):0.0, ('LRT','DFT+U+V'): 0.28, ('eACBN0','DFT+U+V'):2.79},
('FeO', "E$_{g}$"): {('LRT','DFT+U'): 2.83, ('eACBN0','DFT+U'):2.36, ('LRT','DFT+U+V'): 2.84, ('eACBN0','DFT+U+V'):2.07},
('FeO', r"$\mu_B$"): {('LRT','DFT+U'): 3.80, ('eACBN0','DFT+U'):3.74, ('LRT','DFT+U+V'): 3.79, ('eACBN0','DFT+U+V'):3.63},
('CoO', r"$U_{TM}$"): {('LRT','DFT+U'): 6.59, ('eACBN0','DFT+U'):6.44, ('LRT','DFT+U+V'): 6.66, ('eACBN0','DFT+U+V'):6.38},
('CoO', r"$V_{TM,O}$"): {('LRT','DFT+U'): 0.0, ('eACBN0','DFT+U'):0.0, ('LRT','DFT+U+V'): 0.41, ('eACBN0','DFT+U+V'):2.91},
('CoO', "E$_{g}$"): {('LRT','DFT+U'): 2.22, ('eACBN0','DFT+U'):2.19, ('LRT','DFT+U+V'): 2.27, ('eACBN0','DFT+U+V'):2.41},
('CoO', r"$\mu_B$"): {('LRT','DFT+U'): 2.78, ('eACBN0','DFT+U'):2.78, ('LRT','DFT+U+V'): 2.77, ('eACBN0','DFT+U+V'):2.66},
('NiO', r"$U_{TM}$"): {('LRT','DFT+U'): 7.48, ('eACBN0','DFT+U'):7.78, ('LRT','DFT+U+V'): 7.50, ('eACBN0','DFT+U+V'):7.63},
('NiO', r"$V_{TM,O}$"): {('LRT','DFT+U'): 0.0, ('eACBN0','DFT+U'):0.0, ('LRT','DFT+U+V'): 0.38, ('eACBN0','DFT+U+V'):2.94},
('NiO', "E$_{g}$"): {('LRT','DFT+U'): 3.45, ('eACBN0','DFT+U'):3.46, ('LRT','DFT+U+V'): 3.45, ('eACBN0','DFT+U+V'):3.46},
('NiO', r"$\mu_B$"): {('LRT','DFT+U'): 1.83, ('eACBN0','DFT+U'):1.83, ('LRT','DFT+U+V'): 1.81, ('eACBN0','DFT+U+V'):1.73},
}
# -----------------------------
# 2) Make 3 subplots
# -----------------------------
fig, (ax_uv, ax_eg, ax_mu) = plt.subplots(3, 1, figsize=(10, 10))
y_offsets_u = {
'MnO': 5.5,
'FeO': 9.0,
'CoO': 7.5,
'NiO': 8.3,
}
y_offsets_v = {
'MnO': 3,
'FeO': 3,
'CoO': 3.2,
'NiO': 3.2,
}
y_offsets_eg = {
'MnO': 2.2,
'FeO': 3.0,
'CoO': 3.8,
'NiO': 4.5,
}
y_offsets_mu = {
'MnO': 5.0,
'FeO': 4.4,
'CoO': 4.2,
'NiO': 2.1,
}
# common bar‐plotting helper
def plot_bars(ax, paramList, data, comboOrder,
ylabel, ylim, label, label_ypos,
show_mat_labels=True, show_param_labels=True):
ax.set_ylabel(ylabel, fontsize=font)
ax.grid(True, axis='y', linestyle='--', alpha=0.6)
ax.set_xticks([])
ax.set_ylim(*ylim)
ax.text(-0.15, 1.1, label, transform=ax.transAxes,
fontsize=font+6, ha='left', va='top')
barWidth = 0.12
gap_mat = 0.6
extra = 0.2
gap_bar = 0.06
nC = len(comboOrder)
sW = nC*(barWidth+gap_bar)-gap_bar+extra
gW = len(paramList)*sW + gap_mat
for i, mat in enumerate(materials):
gStart = i * gW
center = gStart + (len(paramList)*sW - extra)/2 - 0.05
# material names
if show_mat_labels:
ax.text(center, label_ypos-0.3, mat,
ha='center', va='top', fontsize=font)
for j, p in enumerate(paramList):
sgStart = gStart + j * sW
sgCtr = sgStart + (nC*(barWidth+gap_bar)-gap_bar)/2 - 0.05
# parameter labels
if show_param_labels:
ax.text(sgCtr, label_ypos, p,
ha='center', va='top', fontsize=font)
for k, combo in enumerate(comboOrder):
x = sgStart + k*(barWidth+gap_bar)
v = data[(mat, p)][combo]
bar = ax.bar(x, v, barWidth,
color=color_map[combo[0]],
hatch=hatch_map[combo[1]],
edgecolor='black', alpha=0.8, zorder=2)
if v > 0:
if p == r"$U_{TM}$":
offset = y_offsets_u[mat]
elif p == r"$V_{TM,O}$":
offset = y_offsets_v[mat]
elif ax is ax_eg:
offset = y_offsets_eg[mat]
elif ax is ax_mu:
offset = y_offsets_mu[mat]
else:
offset = v+0.2
#ax.text(x+0.02, v+0.2, f'{v:.2f}',
ax.text(x+0.02, offset, f'{v:.2f}',
ha='center', va='bottom',
fontsize=font-6, rotation=90, zorder=3)
# -----------------------------
# 3-panel calls
# -----------------------------
#fig, (ax_uv, ax_eg, ax_mu) = plt.subplots(3, 1, figsize=(10, 12))
# (a) U & V — show both param and material labels
plot_bars(ax_uv, params_uv, data, comboOrder,
ylabel="Hubbard parameter (eV)", ylim=(0,10.5),
label="(a)", label_ypos=-0.2,
show_mat_labels=False, show_param_labels=True)
ax_uv.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.1f'))
# (b) E_g — hide both material & param labels
plot_bars(ax_eg, params_eg, data, comboOrder,
ylabel="Band gap (eV)", ylim=(0,5.5),
label="(b)", label_ypos=-0.1,
show_mat_labels=False, show_param_labels=False)
ax_eg.set_yticks([0.0, 1.0, 2.0, 3.0, 4.0, 5.0])
ax_eg.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.1f'))
# (b) E_g
expt_eg = {
"MnO": [3.9, 4.1, 3.8, 4.2], # 1991 Phys. Rev. B 44 1530, 2008 Phys. Rev. B 77 165127, 1968 Fiz. Tverd. Tela 10 3082
"FeO": [2.4, 2.4], # 1973 J. Solid State. Chem. 12, 355
"CoO": [2.5, 2.6, 3.6], # 1991 Phys. Rev. B 44 6090–103, 2008 Phys. Rev. B 77 165127, 1972 J. Phys. Chem. Solids 33 893
"NiO": [4.3, 4.0, 3.7], # 1984 Phys. Rev. Lett. 53 2339, 2008 Phys. Rev. B 77 165127, 1965 Fiz. Tverd. Tela 7 1884
}
barWidth = 0.12
gap_bar = 0.06
extra = 0.2
nC = len(comboOrder)
sW = nC*(barWidth+gap_bar) - gap_bar + extra
gW = len(params_eg)*sW + 0.6
def draw_expt_lines(ax, expt_dict, materials, gW, nC, barWidth, gap_bar,
x_shift=-0.05, color='blue', linestyle='--',
linewidth=3, zorder=2):
for i, mat in enumerate(materials):
vals = expt_dict.get(mat, [])
if np.isscalar(vals):
vals = [vals]
gStart = i * gW
x0 = gStart + x_shift
x1 = gStart + (nC - 1) * (barWidth + gap_bar) + barWidth + x_shift
for y in vals:
ax.hlines(y, x0, x1,
colors=color,
linestyles=linestyle,
linewidth=linewidth,
zorder=zorder)
draw_expt_lines(ax_eg, expt_eg, materials, gW, nC, barWidth, gap_bar)
# (c) μ_B — show only material labels, hide param label
plot_bars(ax_mu, params_mu, data, comboOrder,
ylabel=r"Mag. moment ($\mu_B$)", ylim=(0,6.0),
label="(c)", label_ypos=-0.1,
show_mat_labels=True, show_param_labels=False)
ax_mu.set_yticks([0.0, 2.0, 4.0, 6.0])
ax_mu.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.1f'))
# (c) μ_B
expt_mu = {
"MnO": [4.58, 4.79], #1983 Phys. Rev. B 27 6964, 1968 J. Chem. Phys. 48 990
"FeO": [3.32, 4.20], #1958 Phys. Rev. 110 1333–41, J. Phys. C: Solid State Phys. 12 337
"CoO": [3.35, 3.98], #1970 Phys. Rev. B 1 2243–9, 2001 Phys. Rev. B 64 052102
"NiO": [1.77, 1.90], #1983 Phys. Rev. B 27 6964, 1968 J. Chem. Phys. 48 990
}
for i, mat in enumerate(materials):
gStart = i * gW
x0 = gStart -0.05
x1 = gStart + (nC-1)*(barWidth+gap_bar) + barWidth -0.05
for idx, y in enumerate(expt_mu[mat]):
ax_mu.hlines(y, x0, x1,
colors='blue',
linestyles='--',
linewidth=3,
zorder=2)
# -----------------------------
# Legend in two columns
# -----------------------------
legend_elems = [
Patch(facecolor='green', edgecolor='black', hatch='', label='LRT'),
Patch(facecolor='darkorange', edgecolor='black', hatch='', label='eACBN0'),
Patch(facecolor='white', edgecolor='black', hatch='', label='DFT+$U$'),
Patch(facecolor='white', edgecolor='black', hatch='//',label='DFT+$U$+$V$'),
]
#ax_uv.legend(handles=legend_elems, loc='upper left', fontsize=font-2, ncol =4)
fig.legend(handles=legend_elems, loc="upper center",
bbox_to_anchor=(0.5, 0.97),
ncol=4, fontsize=font)
#plt.tight_layout(rect=[0, 0, 1, 0.98])
fig.align_ylabels([ax_uv, ax_eg, ax_mu])
plt.subplots_adjust(hspace=0.16, top = 0.9, bottom=0.08)
plt.savefig('TMO_wo_O.pdf', bbox_inches='tight')
plt.show()
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
from matplotlib import rc, rcParams
from matplotlib.patches import Patch
# Close any existing figures (especially in Jupyter)
plt.close('all')
# -----------------------------
# 0) Font & style
# -----------------------------
font = 16
rc('text', usetex=False)
rc('font', family='Arial')
rcParams['font.size'] = font
mpl.rcParams['axes.linewidth'] = 1.5
# -----------------------------
# 1) Data
# -----------------------------
materials = ['MnO', 'FeO', 'CoO', 'NiO']
params_top = [r"$U_{TM}$", r"$U_{O}$", r"$V_{TM,O}$"]
params_eg = [r"E$_g$"]
params_mu = [r"$\mu_B$"]
comboOrder = [
('LRT', 'DFT+U'),
('eACBN0', 'DFT+U'),
('LRT', 'DFT+U+V'),
('eACBN0', 'DFT+U+V'),
]
color_map = {'LRT':'green', 'eACBN0':'darkorange'}
hatch_map = {'DFT+U':'', 'DFT+U+V':'//'}
data = {}
# -----------------------------
# MnO
# -----------------------------
data[('MnO', r"$U_{TM}$")] = {
('LRT','DFT+U'): 4.95, ('eACBN0','DFT+U'): 4.95,
('LRT','DFT+U+V'): 4.99, ('eACBN0','DFT+U+V'):5.28,
}
data[('MnO', r"$U_{O}$")] = {
('LRT','DFT+U'): 10.27, ('eACBN0','DFT+U'): 2.85,
('LRT','DFT+U+V'): 10.25, ('eACBN0','DFT+U+V'):2.88,
}
data[('MnO', r"$V_{TM,O}$")] = {
('LRT','DFT+U'): 0.0, ('eACBN0','DFT+U'):0.0,
('LRT','DFT+U+V'): 0.36, ('eACBN0','DFT+U+V'):2.75,
}
data[('MnO', r"E$_g$")] = {
('LRT','DFT+U'): 3.90, ('eACBN0','DFT+U'):2.53,
('LRT','DFT+U+V'): 3.91, ('eACBN0','DFT+U+V'):2.46,
}
data[('MnO', r"$\mu_B$")] = {
('LRT','DFT+U'): 4.80, ('eACBN0','DFT+U'):4.75,
('LRT','DFT+U+V'): 4.79, ('eACBN0','DFT+U+V'):4.65,
}
# -----------------------------
# FeO
# -----------------------------
data[('FeO', r"$U_{TM}$")] = {
('LRT','DFT+U'): 9.95, ('eACBN0','DFT+U'):6.06,
('LRT','DFT+U+V'): 9.89, ('eACBN0','DFT+U+V'):6.17,
}
data[('FeO', r"$U_{O}$")] = {
('LRT','DFT+U'): 10.19, ('eACBN0','DFT+U'):2.81,
('LRT','DFT+U+V'): 10.18, ('eACBN0','DFT+U+V'):2.69,
}
data[('FeO', r"$V_{TM,O}$")] = {
('LRT','DFT+U'): 0.0, ('eACBN0','DFT+U'):0.0,
('LRT','DFT+U+V'): 0.18, ('eACBN0','DFT+U+V'):2.80,
}
data[('FeO', "E$_g$")] = {
('LRT','DFT+U'): 4.84, ('eACBN0','DFT+U'):2.65,
('LRT','DFT+U+V'): 4.82, ('eACBN0','DFT+U+V'):2.37,
}
data[('FeO', r"$\mu_B$")] = {
('LRT','DFT+U'): 3.88, ('eACBN0','DFT+U'):3.77,
('LRT','DFT+U+V'): 3.88, ('eACBN0','DFT+U+V'):3.66,
}
# -----------------------------
# CoO
# -----------------------------
data[('CoO', r"$U_{TM}$")] = {
('LRT','DFT+U'): 6.83, ('eACBN0','DFT+U'):6.23,
('LRT','DFT+U+V'): 6.86, ('eACBN0','DFT+U+V'):6.36,
}
data[('CoO', r"$U_{O}$")] = {
('LRT','DFT+U'): 9.87, ('eACBN0','DFT+U'):2.28,
('LRT','DFT+U+V'): 9.85, ('eACBN0','DFT+U+V'):2.08,
}
data[('CoO', r"$V_{TM,O}$")] = {
('LRT','DFT+U'): 0.0, ('eACBN0','DFT+U'):0.0,
('LRT','DFT+U+V'): 0.36, ('eACBN0','DFT+U+V'):2.92,
}
data[('CoO', "E$_g$")] = {
('LRT','DFT+U'): 3.78, ('eACBN0','DFT+U'):2.54,
('LRT','DFT+U+V'): 3.82, ('eACBN0','DFT+U+V'):2.74,
}
data[('CoO', r"$\mu_B$")] = {
('LRT','DFT+U'): 2.87, ('eACBN0','DFT+U'):2.79,
('LRT','DFT+U+V'): 2.86, ('eACBN0','DFT+U+V'):2.68,
}
# -----------------------------
# NiO
# -----------------------------
data[('NiO', r"$U_{TM}$")] = {
('LRT','DFT+U'): 7.84, ('eACBN0','DFT+U'):8.45,
('LRT','DFT+U+V'): 7.86, ('eACBN0','DFT+U+V'):7.56,
}
data[('NiO', r"$U_{O}$")] = {
('LRT','DFT+U'): 9.84, ('eACBN0','DFT+U'):3.12,
('LRT','DFT+U+V'): 9.82, ('eACBN0','DFT+U+V'):2.08,
}
data[('NiO', r"$V_{TM,O}$")] = {
('LRT','DFT+U'): 0.0, ('eACBN0','DFT+U'):0.0,
('LRT','DFT+U+V'): 0.31, ('eACBN0','DFT+U+V'):2.95,
}
data[('NiO', "E$_g$")] = {
('LRT','DFT+U'): 5.61, ('eACBN0','DFT+U'):4.13,
('LRT','DFT+U+V'): 5.60, ('eACBN0','DFT+U+V'):3.84,
}
data[('NiO', r"$\mu_B$")] = {
('LRT','DFT+U'): 1.90, ('eACBN0','DFT+U'):1.87,
('LRT','DFT+U+V'): 1.89, ('eACBN0','DFT+U+V'):1.75,
}
y_offsets_u = {
'MnO': 11.0,
'FeO': 11.0,
'CoO': 10.8,
'NiO': 10.8,
}
y_offsets_v = {
'MnO': 3.5,
'FeO': 3.5,
'CoO': 3.7,
'NiO': 3.7,
}
y_offsets_eg = {
'MnO': 4.4,
'FeO': 5.1,
'CoO': 4,
'NiO': 5.9,
}
y_offsets_mu = {
'MnO': 5.0,
'FeO': 4.4,
'CoO': 4.2,
'NiO': 2.1,
}
# -----------------------------
# 2) A unified bar‐plot function
# -----------------------------
def plot_grouped_bars(ax, params, show_mat, show_param, ylbl, ylim, label):
ax.set_ylabel(ylbl, fontsize=font)
ax.grid(axis='y', linestyle='--', alpha=0.6)
ax.set_xticks([])
ax.set_ylim(*ylim)
ax.text(-0.15, 1.1, label, transform=ax.transAxes,
fontsize=font+6, ha='left', va='top')
# layout defs
barW = 0.12
gapM = 0.6
extra = 0.2
gapB = 0.06
nC = len(comboOrder)
sW = nC*(barW+gapB) - gapB + extra
gW = len(params)*sW + gapM
for i, mat in enumerate(materials):
start = i * gW
center = start + (len(params)*sW - extra)/2 - 0.05
if show_mat:
ax.text(center, -0.07, mat,
transform=ax.get_xaxis_transform(),
ha='center', va='top', fontsize=font)
for j, p in enumerate(params):
sg = start + j*sW
sgc = sg + (nC*(barW+gapB)-gapB)/2 - 0.05
if show_param:
ax.text(sgc, -0.03, p,
transform=ax.get_xaxis_transform(),
ha='center', va='top', fontsize=font)
for k, combo in enumerate(comboOrder):
x = sg + k*(barW+gapB)
v = data[(mat, p)][combo]
tgt = ax
ax.bar(x, v, barW,
color=color_map[combo[0]],
hatch=hatch_map[combo[1]],
edgecolor='black', alpha=0.8)
if v > 0:
if p == r"$U_{TM}$":
offset = y_offsets_u[mat]
elif p == r"$U_{O}$":
offset = y_offsets_u[mat]
elif p == r"$V_{TM,O}$":
offset = y_offsets_v[mat]
elif ax is ax_b:
offset = y_offsets_eg[mat]
elif ax is ax_c:
offset = y_offsets_mu[mat]
else:
offset = v+0.15
ax.text(x+0.02, offset, f"{v:.2f}",
ha='center', va='bottom',
fontsize=font-6, rotation=90)
# -----------------------------
# 3) Build the 3-panel figure
# -----------------------------
fig, (ax_a, ax_b, ax_c) = plt.subplots(3, 1, figsize=(10, 10))
plot_grouped_bars(ax_a,
params_top,
show_mat=False,
show_param=True,
ylbl="Hubbard parameter (eV)",
ylim=(0,14),
label="(a)")
ax_a.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.1f'))
plot_grouped_bars(ax_b,
params_eg,
show_mat=False,
show_param=False,
ylbl=r"Band gap (eV)",
ylim=(0,7),
label="(b)")
ax_b.set_yticks([0.0, 2.0, 4.0, 6.0])
ax_b.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.1f'))
# (b) E_g
expt_eg = {
"MnO": [3.9, 4.1, 3.8, 4.2], # 1991 Phys. Rev. B 44 1530, 2008 Phys. Rev. B 77 165127, 1968 Fiz. Tverd. Tela 10 3082
"FeO": [2.4, 2.4], # 1973 J. Solid State. Chem. 12, 355
"CoO": [2.5, 2.6, 3.6], # 1991 Phys. Rev. B 44 6090–103, 2008 Phys. Rev. B 77 165127, 1972 J. Phys. Chem. Solids 33 893
"NiO": [4.3, 4.0, 3.7], # 1984 Phys. Rev. Lett. 53 2339, 2008 Phys. Rev. B 77 165127, 1965 Fiz. Tverd. Tela 7 1884
}
# layout defs
barW = 0.12
gapM = 0.6
extra = 0.2
gapB = 0.06
nC = len(comboOrder)
sW = nC*(barW+gapB) - gapB + extra
gW = len(params_eg)*sW + gapM
def draw_expt_lines(ax, expt_dict, materials, gW, nC, barWidth, gap_bar,
x_shift=-0.05, color='blue', linestyle='--',
linewidth=3, zorder=2):
for i, mat in enumerate(materials):
vals = expt_dict.get(mat, [])
if np.isscalar(vals):
vals = [vals]
gStart = i * gW
x0 = gStart + x_shift
x1 = gStart + (nC - 1) * (barWidth + gap_bar) + barWidth + x_shift
for y in vals:
ax.hlines(y, x0, x1,
colors=color,
linestyles=linestyle,
linewidth=linewidth,
zorder=zorder)
draw_expt_lines(ax_b, expt_eg, materials, gW, nC, barW, gapB)
plot_grouped_bars(ax_c,
params_mu,
show_mat=True,
show_param=False,
ylbl=r"Mag. moment ($\mu_B$)",
ylim=(0,6),
label="(c)")
ax_c.set_yticks([0.0, 2.0, 4.0, 6.0])
ax_c.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.1f'))
# (c) μ_B
expt_mu = {
"MnO": [4.58, 4.79], #1983 Phys. Rev. B 27 6964, 1968 J. Chem. Phys. 48 990
"FeO": [3.32, 4.20], #1958 Phys. Rev. 110 1333–41, J. Phys. C: Solid State Phys. 12 337
"CoO": [3.35, 3.98], #1970 Phys. Rev. B 1 2243–9, 2001 Phys. Rev. B 64 052102
"NiO": [1.77, 1.90], #1983 Phys. Rev. B 27 6964, 1968 J. Chem. Phys. 48 990
}
for i, mat in enumerate(materials):
gStart = i * gW
x0 = gStart -0.05
x1 = gStart + (nC-1)*(barW+gapB) + barW -0.05
for idx, y in enumerate(expt_mu[mat]):
ax_c.hlines(y, x0, x1,
colors='blue',
linestyles='--',
linewidth=3,
zorder=2)
#y_offset = 0.05 + 0.08*idx
#ax_c.text((x0+x1)/2, y + y_offset,
# f"Expt. {y:.2f}",
# ha='center', va='bottom',
# fontsize=font-4, color='blue')
# -----------------------------
# 4) Legend
# -----------------------------
legend_elems = [
Patch(facecolor='green', edgecolor='black', hatch='', label='LRT'),
Patch(facecolor='darkorange', edgecolor='black', hatch='', label='eACBN0'),
Patch(facecolor='white', edgecolor='black', hatch='', label='DFT+$U$'),
Patch(facecolor='white', edgecolor='black', hatch='//',label='DFT+$U$+$V$'),
]
#fig.legend(handles=legend_elems, loc="upper center", ncol=4, fontsize=font)
fig.legend(handles=legend_elems, loc="upper center",
bbox_to_anchor=(0.5, 0.97),
ncol=4, fontsize=font)
fig.align_ylabels([ax_a, ax_b, ax_c])
plt.subplots_adjust(hspace=0.16, top = 0.9, bottom=0.08)
plt.savefig('TMO_with_O.pdf', bbox_inches='tight')
#plt.savefig('TMO_with_O.png', dpi=300)
plt.show()
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Patch
import matplotlib as mpl
import matplotlib.ticker as mtick
mpl.rcParams['figure.autolayout'] = False
mpl.rcParams['figure.constrained_layout.use'] = False
font = 16
# -----------------------------
# 1) Data for ZrO2
# -----------------------------
comboList = [
("LRT", "DFT+U"),
("eACBN0", "DFT+U"),
("LRT", "DFT+U+V"),
("eACBN0", "DFT+U+V"),
]
color_map = {"LRT": "green", "eACBN0": "darkorange"}
hatch_map = {"DFT+U": "", "DFT+U+V": "//"}
data_uv = {
(r"$U_{Zr}$", "LRT", "DFT+U"): (2.75, None),
(r"$V_{Zr,O}$","LRT", "DFT+U"): (0.00, None),
(r"$U_{Zr}$", "LRT", "DFT+U+V"): (3.06, None),
(r"$V_{Zr,O}$","LRT", "DFT+U+V"): (0.63, 0.82),
(r"$U_{Zr}$", "eACBN0", "DFT+U"): (0.28, None), #0.2775
(r"$V_{Zr,O}$","eACBN0", "DFT+U"): (0.00, None),
(r"$U_{Zr}$", "eACBN0", "DFT+U+V"): (0.36, None),
(r"$V_{Zr,O}$","eACBN0", "DFT+U+V"): (2.32, 2.51),
}
data_eg = {
(r"$E_g$", "LRT", "DFT+U"): (4.07, None),
(r"$E_g$", "LRT", "DFT+U+V"): (4.35, None),
(r"$E_g$", "eACBN0", "DFT+U"): (3.64, None),
(r"$E_g$", "eACBN0", "DFT+U+V"): (4.48, None),
}
params_uv = [r"$U_{Zr}$", r"$V_{Zr,O}$"]
params_eg = [r"$E_g$"]
y_offset = {
r"$U_{Zr}$": 3.2,
r"$V_{Zr,O}$": 2.6,
}
eg_offset = {r"$E_g$": 4.6}
# -----------------------------
# 2) Make the figure
# -----------------------------
#fig, (ax_uv, ax_eg) = plt.subplots(1, 2, figsize=(6, 5), constrained_layout=True)
fig, (ax_uv, ax_eg) = plt.subplots(1, 2, figsize=(6, 5))
barW = 0.18
gap = 0.06
# -- U & V subplot --
ax_uv.set_ylabel("Hubbard parameter (eV)")
ax_uv.grid(axis="y", linestyle="--", alpha=0.6)
ax_uv.set_ylim(0, 4)
ax_uv.set_yticks([0.0, 1.0, 2.0, 3.0, 4.0])
ax_uv.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.1f'))
ax_uv.text(-0.38,1.023,'(a)', transform=ax_uv.transAxes,
fontsize=font+6, ha='left', va='top')
for i, p in enumerate(params_uv):
base = i * (len(comboList) * (barW + gap))
for j, (m, t) in enumerate(comboList):
x = base + j * (barW + gap)
v_s, v_L = data_uv[(p, m, t)]
ax_uv.bar(x, v_s, barW,
color=color_map[m], hatch=hatch_map[t],
edgecolor="black", alpha=0.8, zorder=2)
if v_L is not None:
ax_uv.bar(x, v_L, barW,
color=color_map[m], hatch=hatch_map[t],
edgecolor="black", alpha=0.4, zorder=3)
if abs(v_s) > 1e-3 or (v_L is not None and abs(v_L) > 1e-3):
y = (v_L if v_L is not None else v_s) + 0.05
txt = f"{v_s:.2f}" if v_L is None else f"{v_s:.2f}~{v_L:.2f}"
ax_uv.text(x + barW-0.15, y_offset[p], txt,
ha="center", va="bottom", rotation=90, fontsize=font-6)
centers_uv = [
i * (len(comboList) * (barW + gap))
+ (len(comboList) * (barW )) / 2
for i in range(len(params_uv))
]
ax_uv.set_xticks(centers_uv)
ax_uv.set_xticklabels(params_uv)
# -- Eg subplot --
ax_eg.set_ylabel("Band gap (eV)")
ax_eg.grid(axis="y", linestyle="--", alpha=0.6)
ax_eg.set_ylim(2, 6)
ax_eg.set_yticks([2.0, 3.0, 4.0, 5.0, 6.0])
ax_eg.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.1f'))
for j, (m, t) in enumerate(comboList):
x = j * (barW + gap)
v, _ = data_eg[(params_eg[0], m, t)]
ax_eg.bar(x, v, barW,
color=color_map[m], hatch=hatch_map[t],
edgecolor="black", alpha=0.8, zorder=2)
ax_eg.text(x + barW-0.16, eg_offset[r"$E_g$"], f"{v:.2f}",
ha="center", va="bottom", rotation=90, fontsize=font-6)
exp_val = 5.50 # Phys. Rev. B 78, 085114 (2008)
ax_eg.axhline(y=exp_val,
color='blue',
linestyle='--',
linewidth=3,
label=f"Experiment = {exp_val:.2f} eV")
center_eg = (len(comboList) * (barW)) / 2
ax_eg.set_xticks([center_eg])
#ax_eg.set_xticklabels(params_eg)
ax_eg.set_xticklabels([r"ZrO$_2$"])
ax_eg.text(-0.38,1.023,'(b)', transform=ax_eg.transAxes,
fontsize=font+6, ha='left', va='top')
# -- Legend --
legend_elems = [
Patch(facecolor="green", edgecolor="black", hatch="", label="LRT"),
Patch(facecolor="darkorange", edgecolor="black", hatch="", label="eACBN0"),
Patch(facecolor="white", edgecolor="black", hatch="", label="DFT+U"),
Patch(facecolor="white", edgecolor="black", hatch="//", label="DFT+U+V"),
]
#fig.legend(handles=legend_elems, loc="upper center", ncol=4, fontsize=font)
fig.legend(handles=legend_elems, loc="upper center",
bbox_to_anchor=(0.5, 0.97),
ncol=4, fontsize=font)
plt.subplots_adjust(left=0.1, right=1.01, top = 0.8, bottom=0.12, wspace = 0.4)
plt.savefig('ZrO2_wo_O.pdf', bbox_inches='tight')
plt.show()
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Patch
import matplotlib as mpl
mpl.rcParams['figure.autolayout'] = False
mpl.rcParams['figure.constrained_layout.use'] = False
# Shared styling
font = 16
plt.rc('text', usetex=False)
plt.rc('font', family='Arial', size=font)
plt.rcParams['axes.linewidth'] = 1.5
comboList = [
("LRT", "DFT+U"),
("eACBN0", "DFT+U"),
("LRT", "DFT+U+V"),
("eACBN0", "DFT+U+V"),
]
color_map = {"LRT": "green", "eACBN0": "darkorange"}
hatch_map = {"DFT+U": "", "DFT+U+V": "//"}
# ZnO data
data = {
(r"$U_{Zr}$", "LRT", "DFT+U"): (2.74, None),
(r"$U_{O}$", "LRT", "DFT+U"): (8.84, 9.26),
(r"$V_{Zr,O}$", "LRT", "DFT+U"): (0.0, None),
(r"$E_{g}$", "LRT", "DFT+U"): (5.70, None),
(r"$U_{Zr}$", "LRT", "DFT+U+V"): (2.78, None),
(r"$U_{O}$", "LRT", "DFT+U+V"): (8.89, 9.30),
(r"$V_{Zr,O}$", "LRT", "DFT+U+V"): (0.52, 0.67),
(r"$E_{g}$", "LRT", "DFT+U+V"): (5.88, None),
(r"$U_{Zr}$", "eACBN0", "DFT+U"): (0.20, None),
(r"$U_{O}$", "eACBN0", "DFT+U"): (7.62, 8.15),
(r"$V_{Zr,O}$", "eACBN0", "DFT+U"): (0.0, None),
(r"$E_{g}$", "eACBN0", "DFT+U"): (4.93, None),
(r"$U_{Zr}$", "eACBN0", "DFT+U+V"): (0.27, None),
(r"$U_{O}$", "eACBN0", "DFT+U+V"): (7.48, 7.87),
(r"$V_{Zr,O}$", "eACBN0", "DFT+U+V"): (2.23, 2.42),
(r"$E_{g}$", "eACBN0", "DFT+U+V"): (5.63, None),
}
params_uv = [r"$U_{Zr}$", r"$U_{O}$", r"$V_{Zr,O}$"]
param_eg = [r"$E_{g}$"]
y_offset = {
r"$U_{Zr}$": 3.3,
r"$V_{Zr,O}$": 2.9,
r"$U_{O}$": 9.8
}
eg_offset = {r"$E_g$": 5.95}
barW = 0.18
gap_bar = 0.06
paramEx = 0.2
nC = len(comboList)
subW = nC*(barW+gap_bar) - gap_bar + paramEx
fig, (ax_uv, ax_eg) = plt.subplots(1, 2, figsize=(6,5),
gridspec_kw={'width_ratios':[2,1]})
# U/V subplot
ax_uv.set_ylabel("Hubbard parameter (eV)")
ax_uv.grid(axis='y', linestyle='--', alpha=0.6)
ax_uv.set_ylim(0,13)
ax_uv.set_yticks([0.0, 2.0, 4.0, 6.0, 8.0, 10.0, 12.0])
ax_uv.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.1f'))
ax_uv.set_xticks([])
# after plotting all bars, compute centers_uv:
centers_uv = [
i * subW
+ (len(comboList) * (barW )) / 2
for i in range(len(params_uv))
]
ax_uv.set_xticks(centers_uv)
ax_uv.set_xticklabels(params_uv)
ax_uv.text(-0.33,1.023,'(a)', transform=ax_uv.transAxes,
fontsize=font+6, ha='left', va='top')
for i, p in enumerate(params_uv):
start = i*subW
center = start + (nC*(barW+gap_bar)-gap_bar)/2
for k,(m,t) in enumerate(comboList):
x = start + k*(barW+gap_bar)
vs, vl = data[(p,m,t)]
ax_uv.bar(x, vs, barW, color=color_map[m], hatch=hatch_map[t],
edgecolor='black', alpha=0.8)
if vl is not None:
ax_uv.bar(x, vl, barW, color=color_map[m], hatch=hatch_map[t],
edgecolor='black', alpha=0.4)
if abs(vs) > 1e-3 or (vl is not None and abs(vl) > 1e-3):
ymax = (vl if vl is not None else vs) + 0.5
ax_uv.text(x+barW-0.15, y_offset[p],
f"{vs:.2f}" + (f"~{vl:.2f}" if vl else ""),
ha='center', va='bottom', rotation=90, fontsize=font-6)
# Legend
legs = [
Patch(facecolor='green', edgecolor='black', hatch='', label='LRT'),
Patch(facecolor='darkorange', edgecolor='black', hatch='', label='eACBN0'),
Patch(facecolor='white', edgecolor='black', hatch='', label='DFT+U'),
Patch(facecolor='white', edgecolor='black', hatch='//',label='DFT+U+V'),
]
# E_g subplot
ax_eg.set_ylabel("Band gap (eV)")
ax_eg.grid(axis='y', linestyle='--', alpha=0.6)
ax_eg.set_ylim(4,7)
ax_eg.set_yticks([4.0, 5.0, 6.0, 7.0])
ax_eg.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.1f'))
ax_eg.set_xticks([])
centers_eg = (nC*(barW))/2
ax_eg.set_xticks([centers_eg])
ax_eg.set_xticklabels(params_eg)
for k,(m,t) in enumerate(comboList):
x = k*(barW+gap_bar)
vs, _ = data[(param_eg[0], m, t)]
ax_eg.bar(x, vs, barW, color=color_map[m], hatch=hatch_map[t],
edgecolor='black', alpha=0.8)
ax_eg.text(x+barW-0.16, eg_offset[r"$E_g$"], f"{vs:.2f}",
ha='center', va='bottom', rotation=90, fontsize=font-6)
exp_val = 5.50 # Phys. Rev. B 78, 085114 (2008)
ax_eg.axhline(y=exp_val,
color='blue',
linestyle='--',
linewidth=3,
label=f"Experiment = {exp_val:.2f} eV")
ax_eg.set_xticklabels([r"ZrO$_2$"])
ax_eg.text(-0.56,1.023,'(b)', transform=ax_eg.transAxes,
fontsize=font+6, ha='left', va='top')
fig.legend(handles=legend_elems, loc="upper center",
bbox_to_anchor=(0.5, 0.97),
ncol=4, fontsize=font)
plt.subplots_adjust(left=0.1, right=1.01, top = 0.8, bottom=0.12, wspace = 0.4)
#plt.tight_layout(rect=[0, 0, 1, 0.95])
plt.savefig('ZrO2_with_O.pdf', bbox_inches='tight')
plt.show()
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Patch
from matplotlib.ticker import FormatStrFormatter
import matplotlib as mpl
mpl.rcParams['figure.autolayout'] = False
mpl.rcParams['figure.constrained_layout.use'] = False
# -----------------------------
# 1) Data for BaTiO3
# -----------------------------
comboList = [
("LRT", "DFT+U"),
("eACBN0", "DFT+U"),
("LRT", "DFT+U+V"),
("eACBN0", "DFT+U+V"),
]
color_map = {"LRT": "green", "eACBN0": "darkorange"}
hatch_map = {"DFT+U": "", "DFT+U+V": "//"}
data_uv = {
(r"$U_{Ti}$", "LRT", "DFT+U"): (5.59, None),
(r"$V_{Ti,O}$","LRT", "DFT+U"): (0.00, None),
(r"$U_{Ti}$", "LRT", "DFT+U+V"): (6.14, None),
(r"$V_{Ti,O}$","LRT", "DFT+U+V"): (0.94, 1.14),
(r"$U_{Ti}$", "eACBN0", "DFT+U"): (0.27, None),
(r"$V_{Ti,O}$","eACBN0", "DFT+U"): (0.00, None),
(r"$U_{Ti}$", "eACBN0", "DFT+U+V"): (0.33, None),
(r"$V_{Ti,O}$","eACBN0", "DFT+U+V"): (2.33, 2.61),
}
data_eg = {
(r"$E_g$", "LRT", "DFT+U"): (2.96, None),
(r"$E_g$", "LRT", "DFT+U+V"): (3.42, None),
(r"$E_g$", "eACBN0", "DFT+U"): (2.35, None),
(r"$E_g$", "eACBN0", "DFT+U+V"): (3.37, None),
}
params_uv = [r"$U_{Ti}$", r"$V_{Ti,O}$"]
params_eg = [r"$E_g$"]
y_offset = {
r"$U_{Ti}$": 6.5,
r"$V_{Ti,O}$": 2.8,
}
eg_offset = {r"$E_g$": 3.5}
# -----------------------------
# 2) Make the figure
# -----------------------------
#fig, (ax_uv, ax_eg) = plt.subplots(1, 2, figsize=(6, 5), constrained_layout=True)
fig, (ax_uv, ax_eg) = plt.subplots(1, 2, figsize=(6, 5))
barW = 0.18
gap = 0.06
# -- U & V subplot --
ax_uv.set_ylabel("Hubbard parameter (eV)")
ax_uv.grid(axis="y", linestyle="--", alpha=0.6)
ax_uv.set_ylim(0, 8)
ax_uv.set_yticks([0,2,4,6,8])
ax_uv.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.1f'))
ax_uv.text(-0.38,1.023,'(a)', transform=ax_uv.transAxes,
fontsize=font+6, ha='left', va='top')
for i, p in enumerate(params_uv):
base = i * (len(comboList) * (barW + gap))
for j, (m, t) in enumerate(comboList):
x = base + j * (barW + gap)
v_s, v_L = data_uv[(p, m, t)]
ax_uv.bar(x, v_s, barW,
color=color_map[m], hatch=hatch_map[t],
edgecolor="black", alpha=0.8, zorder=2)
if v_L is not None:
ax_uv.bar(x, v_L, barW,
color=color_map[m], hatch=hatch_map[t],
edgecolor="black", alpha=0.4, zorder=3)
if abs(v_s) > 1e-3 or (v_L is not None and abs(v_L) > 1e-3):
y = (v_L if v_L is not None else v_s) + 0.05
txt = f"{v_s:.2f}" if v_L is None else f"{v_s:.2f}~{v_L:.2f}"
ax_uv.text(x + barW-0.15, y_offset[p], txt,
ha="center", va="bottom", rotation=90, fontsize=font-6)
centers_uv = [
i * (len(comboList) * (barW + gap))
+ (len(comboList) * (barW )) / 2
for i in range(len(params_uv))
]
ax_uv.set_xticks(centers_uv)
ax_uv.set_xticklabels(params_uv)
# -- Eg subplot --
ax_eg.set_ylabel("Band gap (eV)")
ax_eg.grid(axis="y", linestyle="--", alpha=0.6)
ax_eg.set_ylim(2, 4)
ax_eg.yaxis.set_major_formatter(FormatStrFormatter('%.1f'))
for j, (m, t) in enumerate(comboList):
x = j * (barW + gap)
v, _ = data_eg[(params_eg[0], m, t)]
ax_eg.bar(x, v, barW,
color=color_map[m], hatch=hatch_map[t],
edgecolor="black", alpha=0.8, zorder=2)
ax_eg.text(x + barW-0.16, eg_offset[r"$E_g$"], f"{v:.2f}",
ha="center", va="bottom", rotation=90, fontsize=font-6)
exp_val = 3.4 # Phys. Rev. B 2, 2679 (1970)
ax_eg.axhline(y=exp_val,
color='blue',
linestyle='--',
linewidth=3,
label=f"Experiment = {exp_val:.2f} eV")
center_eg = (len(comboList) * (barW)) / 2
ax_eg.set_xticks([center_eg])
ax_eg.set_xticklabels(params_eg)
ax_eg.set_xticklabels([r"BaTiO$_3$"])
ax_eg.set_yticks([2.0,2.5,3.0,3.5,4.0])
ax_eg.text(-0.38,1.023,'(b)', transform=ax_eg.transAxes,
fontsize=font+6, ha='left', va='top')
# -- Legend --
legend_elems = [
Patch(facecolor="green", edgecolor="black", hatch="", label="LRT"),
Patch(facecolor="darkorange", edgecolor="black", hatch="", label="eACBN0"),
Patch(facecolor="white", edgecolor="black", hatch="", label="DFT+U"),
Patch(facecolor="white", edgecolor="black", hatch="//", label="DFT+U+V"),
]
fig.legend(handles=legend_elems, loc="upper center",
bbox_to_anchor=(0.5, 0.97),
ncol=4, fontsize=font)
plt.subplots_adjust(left=0.1, right=1.01, top = 0.8, bottom=0.12, wspace = 0.4)
#plt.tight_layout(rect=[0, 0, 1, 0.95])
plt.savefig('BaTiO3_wo_O.pdf', bbox_inches='tight')
plt.show()
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Patch
import matplotlib as mpl
mpl.rcParams['figure.autolayout'] = False
mpl.rcParams['figure.constrained_layout.use'] = False
# Shared styling
font = 16
plt.rc('text', usetex=False)
plt.rc('font', family='Arial', size=font)
plt.rcParams['axes.linewidth'] = 1.5
comboList = [
("LRT", "DFT+U"),
("eACBN0", "DFT+U"),
("LRT", "DFT+U+V"),
("eACBN0", "DFT+U+V"),
]
color_map = {"LRT": "green", "eACBN0": "darkorange"}
hatch_map = {"DFT+U": "", "DFT+U+V": "//"}
# ZnO data
data = {
(r"$U_{Ti}$", "LRT", "DFT+U"): (5.85, None),
(r"$U_{O}$", "LRT", "DFT+U"): (9.03, None),
(r"$V_{Ti,O}$", "LRT", "DFT+U"): (0.0, None),
(r"$E_{g}$", "LRT", "DFT+U"): (4.26, None),
(r"$U_{Ti}$", "LRT", "DFT+U+V"): (5.92, None),
(r"$U_{O}$", "LRT", "DFT+U+V"): (9.12, None),
(r"$V_{Ti,O}$", "LRT", "DFT+U+V"): (0.88, 1.06),
(r"$E_{g}$", "LRT", "DFT+U+V"): (4.64, None),
(r"$U_{Ti}$", "eACBN0", "DFT+U"): (0.21, None),
(r"$U_{O}$", "eACBN0", "DFT+U"): (7.48, None),
(r"$V_{Ti,O}$", "eACBN0", "DFT+U"): (0.0, None),
(r"$E_{g}$", "eACBN0", "DFT+U"): (3.15, None),
(r"$U_{Ti}$", "eACBN0", "DFT+U+V"): (0.26, None),
(r"$U_{O}$", "eACBN0", "DFT+U+V"): (7.33, None),
(r"$V_{Ti,O}$", "eACBN0", "DFT+U+V"): (2.26, 2.53),
(r"$E_{g}$", "eACBN0", "DFT+U+V"): (4.14, None),
}
params_uv = [r"$U_{Ti}$", r"$U_{O}$", r"$V_{Ti,O}$"]
param_eg = [r"$E_{g}$"]
y_offset = {
r"$U_{Ti}$": 6.2,
r"$V_{Ti,O}$": 2.8,
r"$U_{O}$": 9.3
}
eg_offset = {r"$E_g$": 4.7}
barW = 0.18
gap_bar = 0.06
paramEx = 0.2
nC = len(comboList)
subW = nC*(barW+gap_bar) - gap_bar + paramEx
fig, (ax_uv, ax_eg) = plt.subplots(1, 2, figsize=(6,5),
gridspec_kw={'width_ratios':[2,1]})
# U/V subplot
ax_uv.set_ylabel("Hubbard parameter (eV)")
ax_uv.grid(axis='y', linestyle='--', alpha=0.6)
ax_uv.set_ylim(0,11)
ax_uv.set_yticks([0,2,4,6,8,10])
ax_uv.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.1f'))
ax_uv.set_xticks([])
# after plotting all bars, compute centers_uv:
centers_uv = [
i * subW
+ (len(comboList) * (barW )) / 2
for i in range(len(params_uv))
]
ax_uv.set_xticks(centers_uv)
ax_uv.set_xticklabels(params_uv)
ax_uv.text(-0.33,1.023,'(a)', transform=ax_uv.transAxes,
fontsize=font+6, ha='left', va='top')
for i, p in enumerate(params_uv):
start = i*subW
center = start + (nC*(barW+gap_bar)-gap_bar)/2
for k,(m,t) in enumerate(comboList):
x = start + k*(barW+gap_bar)
vs, vl = data[(p,m,t)]
ax_uv.bar(x, vs, barW, color=color_map[m], hatch=hatch_map[t],
edgecolor='black', alpha=0.8)
if vl is not None:
ax_uv.bar(x, vl, barW, color=color_map[m], hatch=hatch_map[t],
edgecolor='black', alpha=0.4)
if abs(vs) > 1e-3 or (vl is not None and abs(vl) > 1e-3):
ymax = (vl if vl is not None else vs) + 0.5
ax_uv.text(x+barW-0.15, y_offset[p],
f"{vs:.2f}" + (f"~{vl:.2f}" if vl else ""),
ha='center', va='bottom', rotation=90, fontsize=font-6)
# Legend
legs = [
Patch(facecolor='green', edgecolor='black', hatch='', label='LRT'),
Patch(facecolor='darkorange', edgecolor='black', hatch='', label='eACBN0'),
Patch(facecolor='white', edgecolor='black', hatch='', label='DFT+U'),
Patch(facecolor='white', edgecolor='black', hatch='//',label='DFT+U+V'),
]
# E_g subplot
ax_eg.set_ylabel("Band gap (eV)")
ax_eg.grid(axis='y', linestyle='--', alpha=0.6)
ax_eg.set_ylim(2.5,5)
ax_eg.set_xticks([])
centers_eg = (nC*(barW))/2
ax_eg.set_xticks([centers_eg])
ax_eg.set_xticklabels(params_eg)
for k,(m,t) in enumerate(comboList):
x = k*(barW+gap_bar)
vs, _ = data[(param_eg[0], m, t)]
ax_eg.bar(x, vs, barW, color=color_map[m], hatch=hatch_map[t],
edgecolor='black', alpha=0.8)
ax_eg.text(x+barW-0.16, eg_offset[r"$E_g$"], f"{vs:.2f}",
ha='center', va='bottom', rotation=90, fontsize=font-6)
exp_val = 3.4 # Phys. Rev. B 2, 2679 (1970)
ax_eg.axhline(y=exp_val,
color='blue',
linestyle='--',
linewidth=3,
label=f"Experiment = {exp_val:.2f} eV")
ax_eg.set_xticklabels([r"BaTiO$_3$"])
ax_eg.text(-0.56,1.023,'(b)', transform=ax_eg.transAxes,
fontsize=font+6, ha='left', va='top')
fig.legend(handles=legend_elems, loc="upper center",
bbox_to_anchor=(0.5, 0.97),
ncol=4, fontsize=font)
plt.subplots_adjust(left=0.1, right=1.01, top = 0.8, bottom=0.12, wspace = 0.4)
plt.savefig('BaTiO3_with_O.pdf', bbox_inches='tight')
plt.show()
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
from matplotlib import rc, rcParams
from matplotlib.patches import Patch
import matplotlib.ticker as mtick
mpl.rcParams['figure.autolayout'] = False
mpl.rcParams['figure.constrained_layout.use'] = False
# -----------------------------
# -----------------------------
font = 16
rc('text', usetex=False)
rc('font', family='Arial')
rcParams['font.size'] = font
mpl.rcParams['axes.linewidth'] = 1.5
# -----------------------------
# 1) Data for ZnO
# -----------------------------
comboList = [
("LRT", "DFT+U"),
("eACBN0", "DFT+U"),
("LRT", "DFT+U+V"),
("eACBN0", "DFT+U+V"),
]
color_map = {"LRT": "green", "eACBN0": "darkorange"}
hatch_map = {"DFT+U": "", "DFT+U+V": "//"}
# (parameter, method, theory) -> (small_val, large_val)
data_uv = {
(r"$U_{Zn}$", "LRT", "DFT+U"): (106.95, None),
(r"$V_{Zn,O}$","LRT", "DFT+U"): (0.00, None),
(r"$U_{Zn}$", "LRT", "DFT+U+V"): (106.74, None),
(r"$V_{Zn,O}$","LRT", "DFT+U+V"): (-0.45, -0.56),
(r"$U_{Zn}$", "eACBN0", "DFT+U"): (15.98, None),
(r"$V_{Zn,O}$","eACBN0", "DFT+U"): (0.00, None),
(r"$U_{Zn}$", "eACBN0", "DFT+U+V"): (15.94, None),
(r"$V_{Zn,O}$","eACBN0", "DFT+U+V"): (2.90, 2.91),
}
data_eg = {
(r"$E_g$", "LRT", "DFT+U"): (1.94, None),
(r"$E_g$", "LRT", "DFT+U+V"): (1.94, None),
(r"$E_g$", "eACBN0", "DFT+U"): (1.52, None),
(r"$E_g$", "eACBN0", "DFT+U+V"): (1.52, None),
}
params_uv = [r"$U_{Zn}$", r"$V_{Zn,O}$"]
params_eg = [r"$E_g$"]
y_offset = {
r"$U_{Zn}$": 110.0,
r"$V_{Zn,O}$": 5,
}
eg_offset = {r"$E_g$": 2.00}
# -----------------------------
# 2) Make the figure
# -----------------------------
#fig, (ax_uv, ax_eg) = plt.subplots(1, 2, figsize=(6, 5), constrained_layout=True)
fig, (ax_uv, ax_eg) = plt.subplots(1, 2, figsize=(6, 5))
barW = 0.18
gap = 0.06
# -- U & V subplot --
#ax_uv.set_title("ZnO: $U_M$ & $V_{M,O}$")
ax_uv.set_ylabel("Hubbard parameter (eV)")
ax_uv.set_ylim(-5.0, 135)
ax_uv.set_yticks([0,45,90,135])
#ax_uv.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.1f'))
ax_uv.grid(axis="y", linestyle="--", alpha=0.6)
ax_uv.set_xticks([])
for i, p in enumerate(params_uv):
base = i * (len(comboList) * (barW + gap))
for j, (m, t) in enumerate(comboList):
x = base + j * (barW + gap)
v_small, v_large = data_uv[(p, m, t)]
if abs(v_small) > 1e-5:
ax_uv.bar(x, v_small, barW,
color=color_map[m],
hatch=hatch_map[t],
edgecolor="black", alpha=0.8, zorder=2)
if v_large is not None and abs(v_large) > 1e-5:
ax_uv.bar(x, v_large, barW,
color=color_map[m],
hatch=hatch_map[t],
edgecolor="black", alpha=0.4, zorder=3)
if abs(v_small) > 1e-3 or (v_large is not None and abs(v_large) > 1e-3):
y = (v_large if v_large is not None else v_small) + 0.5
txt = f"{v_small:.2f}" if v_large is None else f"{v_small:.2f}~{v_large:.2f}"
ax_uv.text(x + barW-0.15, y_offset[p], txt,
ha="center", va="bottom", rotation=90, fontsize=font-6)
# put param labels under U/V
centers_uv = [
i * (len(comboList) * (barW + gap))
+ (len(comboList) * (barW)) / 2
for i in range(len(params_uv))
]
ax_uv.set_xticks(centers_uv)
ax_uv.set_xticklabels(params_uv)
ax_uv.text(-0.38,1.023,'(a)', transform=ax_uv.transAxes,
fontsize=font+6, ha='left', va='top')
# -- Eg subplot --
ax_eg.set_ylabel("Band gap (eV)")
ax_eg.grid(axis="y", linestyle="--", alpha=0.6)
ax_eg.set_ylim(0, 5)
ax_eg.set_yticks([0,1,2,3,4,5])
ax_eg.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.1f'))
ax_eg.set_xticks([])
for j, (m, t) in enumerate(comboList):
x = j * (barW + gap)
v, _ = data_eg[(params_eg[0], m, t)]
ax_eg.bar(x, v, barW,
color=color_map[m],
hatch=hatch_map[t],
edgecolor="black", alpha=0.8, zorder=2)
#ax_eg.text(x + barW-0.16, v + 0.1, f"{v:.2f}",
ax_eg.text(x + barW-0.16, eg_offset[r"$E_g$"], f"{v:.2f}",
ha="center", va="bottom", rotation=90, fontsize=font-6)
exp_val = 3.3 # J. Appl. Phys. 84, 3912 (1998)
ax_eg.axhline(y=exp_val,
color='blue',
linestyle='--',
linewidth=3,
label=f"Experiment = {exp_val:.2f} eV")
exp_val2 = 3.4 # J. Appl. Phys. 84, 3912 (1998)
ax_eg.axhline(y=exp_val2,
color='blue',
linestyle='--',
linewidth=3,
label=f"Experiment = {exp_val2:.2f} eV")
center_eg = (len(comboList) * (barW)) / 2
ax_eg.set_xticks([center_eg])
#ax_eg.set_xticklabels(params_eg)
ax_eg.set_xticklabels(["ZnO"])
ax_eg.text(-0.38,1.023,'(b)', transform=ax_eg.transAxes,
fontsize=font+6, ha='left', va='top')
# -- Legend on the left plot --
legend_elems = [
Patch(facecolor="green", edgecolor="black", hatch="", label="LRT"),
Patch(facecolor="darkorange", edgecolor="black", hatch="", label="eACBN0"),
Patch(facecolor="white", edgecolor="black", hatch="", label="DFT+U"),
Patch(facecolor="white", edgecolor="black", hatch="//", label="DFT+U+V"),
]
fig.legend(handles=legend_elems, loc="upper center",
bbox_to_anchor=(0.5, 0.97),
ncol=4, fontsize=font)
plt.subplots_adjust(left=0.1, right=1.01, top = 0.8, bottom=0.12, wspace = 0.4)
plt.savefig('ZnO_wo_O.pdf', bbox_inches='tight')
plt.show()
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
from matplotlib import rc, rcParams
from matplotlib.patches import Patch
# Shared styling
font = 16
plt.rc('text', usetex=False)
plt.rc('font', family='Arial', size=font)
plt.rcParams['axes.linewidth'] = 1.5
comboList = [
("LRT", "DFT+U"),
("eACBN0", "DFT+U"),
("LRT", "DFT+U+V"),
("eACBN0", "DFT+U+V"),
]
color_map = {"LRT": "green", "eACBN0": "darkorange"}
hatch_map = {"DFT+U": "", "DFT+U+V": "//"}
# ZnO data
data = {
(r"$U_{Zn}$", "LRT", "DFT+U"): (95.02, None),
(r"$U_{O}$", "LRT", "DFT+U"): (10.55, None),
(r"$V_{Zn,O}$", "LRT", "DFT+U"): (0.0, None),
(r"$E_{g}$", "LRT", "DFT+U"): (4.81, None),
(r"$U_{Zn}$", "LRT", "DFT+U+V"): (95.10, None),
(r"$U_{O}$", "LRT", "DFT+U+V"): (10.55, None),
(r"$V_{Zn,O}$", "LRT", "DFT+U+V"): (-0.41, -0.52),
(r"$E_{g}$", "LRT", "DFT+U+V"): (4.81, None),
(r"$U_{Zn}$", "eACBN0", "DFT+U"): (15.32, None),
(r"$U_{O}$", "eACBN0", "DFT+U"): (7.41, None),
(r"$V_{Zn,O}$", "eACBN0", "DFT+U"): (0.0, None),
(r"$E_{g}$", "eACBN0", "DFT+U"): (3.36, None),
(r"$U_{Zn}$", "eACBN0", "DFT+U+V"): (15.27, None),
(r"$U_{O}$", "eACBN0", "DFT+U+V"): (7.34, None),
(r"$V_{Zn,O}$", "eACBN0", "DFT+U+V"): (2.95, 2.97),
(r"$E_{g}$", "eACBN0", "DFT+U+V"): (3.34, None),
}
params_uv = [r"$U_{Zn}$", r"$U_{O}$", r"$V_{Zn,O}$"]
params_eg = [r"$E_{g}$"]
y_offset = {
r"$U_{Zn}$": 97,
r"$V_{Zn,O}$": 6,
r"$U_{O}$": 12
}
eg_offset = {r"$E_g$": 5}
barW = 0.18
gap_bar = 0.06
paramEx = 0.2
nC = len(comboList)
subW = nC*(barW+gap_bar) - gap_bar + paramEx
fig, (ax_uv, ax_eg) = plt.subplots(1, 2, figsize=(6,5),
gridspec_kw={'width_ratios':[2,1]})
# U/V subplot
ax_uv.set_ylabel("Hubbard parameter (eV)")
ax_uv.grid(axis='y', linestyle='--', alpha=0.6)
ax_uv.set_ylim(-5,120 )
ax_uv.set_yticks([0,30,60,90,120])
#ax_uv.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.1f'))
ax_uv.set_xticks([])
# after plotting all bars, compute centers_uv:
centers_uv = [
i * subW
+ (len(comboList) * (barW )) / 2
for i in range(len(params_uv))
]
ax_uv.set_xticks(centers_uv)
ax_uv.set_xticklabels(params_uv)
ax_uv.text(-0.33,1.023,'(a)', transform=ax_uv.transAxes,
fontsize=font+6, ha='left', va='top')
for i, p in enumerate(params_uv):
start = i*subW
center = start + (nC*(barW+gap_bar)-gap_bar)/2
for k,(m,t) in enumerate(comboList):
x = start + k*(barW+gap_bar)
vs, vl = data[(p,m,t)]
if abs(vs) > 1e-5:
ax_uv.bar(x, vs, barW, color=color_map[m], hatch=hatch_map[t],
edgecolor='black', alpha=0.8)
if vl is not None and abs(vs) > 1e-5:
ax_uv.bar(x, vl, barW, color=color_map[m], hatch=hatch_map[t],
edgecolor='black', alpha=0.4)
if abs(vs) > 1e-3 or (vl is not None and abs(vl) > 1e-3):
ymax = (vl if vl is not None else vs) + 0.5
ax_uv.text(x+barW-0.15, y_offset[p],
f"{vs:.2f}" + (f"~{vl:.2f}" if vl else ""),
ha='center', va='bottom', rotation=90, fontsize=font-6)
# Legend
legs = [
Patch(facecolor='green', edgecolor='black', hatch='', label='LRT'),
Patch(facecolor='darkorange', edgecolor='black', hatch='', label='eACBN0'),
Patch(facecolor='white', edgecolor='black', hatch='', label='DFT+U'),
Patch(facecolor='white', edgecolor='black', hatch='//',label='DFT+U+V'),
]
#ax_uv.legend(handles=legs, loc='upper right', fontsize=font-2)
# E_g subplot
ax_eg.set_ylabel("Band gap (eV)")
ax_eg.grid(axis='y', linestyle='--', alpha=0.6)
ax_eg.set_ylim(0,6)
ax_eg.set_yticks([0,1,2,3,4,5,6])
ax_eg.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.1f'))
ax_eg.set_xticks([])
centers_eg = (nC*(barW))/2
ax_eg.set_xticks([centers_eg])
#ax_eg.set_xticklabels(params_eg)
ax_eg.set_xticklabels(["ZnO"])
for k,(m,t) in enumerate(comboList):
x = k*(barW+gap_bar)
vs, _ = data[(params_eg[0], m, t)]
ax_eg.bar(x, vs, barW, color=color_map[m], hatch=hatch_map[t],
edgecolor='black', alpha=0.8)
ax_eg.text(x+barW-0.16, eg_offset[r"$E_g$"], f"{vs:.2f}",
ha='center', va='bottom', rotation=90, fontsize=font-6)
exp_val = 3.3 # J. Appl. Phys. 84, 3912 (1998)
ax_eg.axhline(y=exp_val,
color='blue',
linestyle='--',
linewidth=3,
label=f"Experiment = {exp_val:.2f} eV")
exp_val2 = 3.4 # J. Appl. Phys. 84, 3912 (1998)
ax_eg.axhline(y=exp_val2,
color='blue',
linestyle='--',
linewidth=3,
label=f"Experiment = {exp_val2:.2f} eV")
ax_eg.text(-0.56,1.023,'(b)', transform=ax_eg.transAxes,
fontsize=font+6, ha='left', va='top')
fig.legend(handles=legend_elems, loc="upper center",
bbox_to_anchor=(0.5, 0.97),
ncol=4, fontsize=font)
plt.subplots_adjust(left=0.1, right=1.01, top = 0.8, bottom=0.12, wspace = 0.4)
plt.savefig('ZnO_with_O.pdf', bbox_inches='tight')
plt.show()
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
from matplotlib import rc, rcParams
from matplotlib.patches import Patch
import matplotlib.ticker as mtick
mpl.rcParams['figure.autolayout'] = False
mpl.rcParams['figure.constrained_layout.use'] = False
# -----------------------------
# 0) font/style
# -----------------------------
font = 16
rc('text', usetex=False)
rc('font', family='Arial')
rcParams['font.size'] = font
mpl.rcParams['axes.linewidth'] = 1.5
#rcParams.update({'figure.autolayout': True})
mpl.rcParams['mathtext.fontset'] = 'custom'
mpl.rcParams['mathtext.rm'] = 'Arial'
mpl.rcParams['mathtext.it'] = 'Arial:italic'
mpl.rcParams['mathtext.bf'] = 'Arial:bold'
# -----------------------------
# 1) data
# -----------------------------
materials = ['MnO','FeO','CoO','NiO']
topParams = [r"$a$", r"$\alpha$"]
middleParams = [r"$U_{TM}$", r"$V_{TM,O}$"]
egParam = [r"E$_{g}$"]
muParam = [r"$\mu_B$"]
#params_eg = [r"E$_g$"]
comboOrder = [
('LRT','DFT+U'),
('eACBN0','DFT+U'),
('LRT','DFT+U+V'),
('eACBN0','DFT+U+V'),
]
color_map = {'LRT':'green','eACBN0':'darkorange'}
hatch_map = {'DFT+U':'','DFT+U+V':'//'}
data = {}
# --- MnO ---
data[('MnO', r"$U_{TM}$")] = {
('LRT','DFT+U'): 4.84, ('eACBN0','DFT+U'):14.29,
('LRT','DFT+U+V'): 4.84, ('eACBN0','DFT+U+V'):5.10,
}
data[('MnO', r"$V_{TM,O}$")] = {
('LRT','DFT+U'): 0.0, ('eACBN0','DFT+U'):0.0,
('LRT','DFT+U+V'): 0.36, ('eACBN0','DFT+U+V'):2.69,
}
data[('MnO', r"$a$")] = {
('LRT','DFT+U'): 4.47, ('eACBN0','DFT+U'):4.57,
('LRT','DFT+U+V'): 4.46, ('eACBN0','DFT+U+V'):4.42,
}
data[('MnO', r"$\alpha$")] = {
('LRT','DFT+U'): 90.74, ('eACBN0','DFT+U'):90.33,
('LRT','DFT+U+V'): 90.74, ('eACBN0','DFT+U+V'):90.76,
}
data[('MnO', "E$_{g}$")] = {
('LRT','DFT+U'): 1.74, ('eACBN0','DFT+U'):1.86,
('LRT','DFT+U+V'): 1.75, ('eACBN0','DFT+U+V'):1.81,
}
data[('MnO', r"$\mu_B$")] = {
('LRT','DFT+U'): 4.77, ('eACBN0','DFT+U'):4.96,
('LRT','DFT+U+V'): 4.75, ('eACBN0','DFT+U+V'):4.64,
}
# --- FeO ---
data[('FeO', r"$U_{TM}$")] = {
('LRT','DFT+U'): 9.34, ('eACBN0','DFT+U'):6.38,
('LRT','DFT+U+V'): 9.04, ('eACBN0','DFT+U+V'):5.96,
}
data[('FeO', r"$V_{TM,O}$")] = {
('LRT','DFT+U'): 0.0, ('eACBN0','DFT+U'):0.0,
('LRT','DFT+U+V'): 0.16, ('eACBN0','DFT+U+V'):2.74,
}
data[('FeO', r"$a$")] = {
('LRT','DFT+U'): 4.40, ('eACBN0','DFT+U'):4.37,
('LRT','DFT+U+V'): 4.40, ('eACBN0','DFT+U+V'):4.32,
}
data[('FeO', r"$\alpha$")] = {
('LRT','DFT+U'): 91.50, ('eACBN0','DFT+U'):91.60,
('LRT','DFT+U+V'): 91.50, ('eACBN0','DFT+U+V'):91.65,
}
data[('FeO', "E$_{g}$")] = {
('LRT','DFT+U'): 2.41, ('eACBN0','DFT+U'):2.22,
('LRT','DFT+U+V'): 2.43, ('eACBN0','DFT+U+V'):2.22,
}
data[('FeO', r"$\mu_B$")] = {
('LRT','DFT+U'): 3.88, ('eACBN0','DFT+U'):3.82,
('LRT','DFT+U+V'): 3.87, ('eACBN0','DFT+U+V'):3.70,
}
# --- CoO ---
data[('CoO', r"$U_{TM}$")] = {
('LRT','DFT+U'): 6.34, ('eACBN0','DFT+U'):7.87,
('LRT','DFT+U+V'): 6.34, ('eACBN0','DFT+U+V'):6.35,
}
data[('CoO', r"$V_{TM,O}$")] = {
('LRT','DFT+U'): 0.0, ('eACBN0','DFT+U'):0.0,
('LRT','DFT+U+V'): 0.36, ('eACBN0','DFT+U+V'):2.85,
}
data[('CoO', r"$a$")] = {
('LRT','DFT+U'): 4.28, ('eACBN0','DFT+U'):4.29,
('LRT','DFT+U+V'): 4.27, ('eACBN0','DFT+U+V'):4.24,
}
data[('CoO', r"$\alpha$")] = {
('LRT','DFT+U'): 90.09, ('eACBN0','DFT+U'):90.12,
('LRT','DFT+U+V'): 90.09, ('eACBN0','DFT+U+V'):90.05,
}
data[('CoO', "E$_{g}$")] = {
('LRT','DFT+U'): 2.61, ('eACBN0','DFT+U'):2.60,
('LRT','DFT+U+V'): 2.64, ('eACBN0','DFT+U+V'):2.76,
}
data[('CoO', r"$\mu_B$")] = {
('LRT','DFT+U'): 2.83, ('eACBN0','DFT+U'):2.87,
('LRT','DFT+U+V'): 2.82, ('eACBN0','DFT+U+V'):2.72,
}
# --- NiO ---
data[('NiO', r"$U_{TM}$")] = {
('LRT','DFT+U'): 7.38, ('eACBN0','DFT+U'):14.13,
('LRT','DFT+U+V'): 7.38, ('eACBN0','DFT+U+V'):7.98,
}
data[('NiO', r"$V_{TM,O}$")] = {
('LRT','DFT+U'): 0.0, ('eACBN0','DFT+U'):0.0,
('LRT','DFT+U+V'): 0.35, ('eACBN0','DFT+U+V'):2.90,
}
data[('NiO', r"$a$")] = {
('LRT','DFT+U'): 4.20, ('eACBN0','DFT+U'):4.27,
('LRT','DFT+U+V'): 4.20, ('eACBN0','DFT+U+V'):4.18,
}
data[('NiO', r"$\alpha$")] = {
('LRT','DFT+U'): 90.05, ('eACBN0','DFT+U'):90.02,
('LRT','DFT+U+V'): 90.06, ('eACBN0','DFT+U+V'):90.06,
}
data[('NiO', "E$_{g}$")] = {
('LRT','DFT+U'): 2.99, ('eACBN0','DFT+U'):2.72,
('LRT','DFT+U+V'): 3.01, ('eACBN0','DFT+U+V'):3.17,
}
data[('NiO', r"$\mu_B$")] = {
('LRT','DFT+U'): 1.84, ('eACBN0','DFT+U'):1.94,
('LRT','DFT+U+V'): 1.83, ('eACBN0','DFT+U+V'):1.75,
}
y_a = {
'MnO': 4.6,
'FeO': 4.5,
'CoO': 4.3,
'NiO': 4.3,
}
y_angle = {
'MnO': 90.85,
'FeO': 91.7,
'CoO': 90.2,
'NiO': 90.2,
}
y_offsets_u = {
'MnO': 14.5,
'FeO': 9.6,
'CoO': 8.1,
'NiO': 14.5,
}
y_offsets_v = {
'MnO': 3,
'FeO': 3,
'CoO': 3.1,
'NiO': 3.1,
}
y_offsets_eg = {
'MnO': 2,
'FeO': 2.6,
'CoO': 3.8,
'NiO': 4.5,
}
y_offsets_mu = {
'MnO': 5.2,
'FeO': 4.4,
'CoO': 4.2,
'NiO': 2.1,
}
# -----------------------------
# 2) 4 subplot
# -----------------------------
fig, (ax_a, ax_uv, ax_eg, ax_mu) = plt.subplots(4,1, figsize=(10,12.5))
barW = 0.12
gapM = 0.6
extra = 0.2
gapB = 0.04
nC = len(comboOrder)
def draw_group(ax, params, ylims, ylabel, label, twin_for=None, val_offset=0.3):
"""Draw grouped bars on ax for given params list."""
ax.set_ylim(*ylims[0])
ax.set_ylabel(ylabel, fontsize=font)
ax.grid(axis='y', linestyle='--', alpha=0.6)
ax.set_xticks([])
ax.text(-0.16,1.1,label, transform=ax.transAxes,
fontsize=font+6, ha='left', va='top')
ax2 = None
if twin_for:
ax2 = ax.twinx()
ax2.set_ylim(*ylims[1])
ax2.set_ylabel(twin_for[1], fontsize=font)
nP = len(params)
sW = nC*(barW+gapB)-gapB+extra
gW = nP*sW + gapM
for i, mat in enumerate(materials):
g0 = i * gW
# material label only on bottommost
if ax is ax_mu:
center = g0 + (nP*sW - extra)/2 - 0.05
ax.text(center, -0.07, mat,
transform=ax.get_xaxis_transform(),
ha='center', va='top', fontsize=font-2)
for j, p in enumerate(params):
sg = g0 + j*sW
for k, combo in enumerate(comboOrder):
x = sg + k*(barW+gapB)
v = data[(mat, p)][combo]
target = ax2 if (ax2 and p==twin_for[0]) else ax
target.bar(x, v, barW,
color=color_map[combo[0]],
hatch=hatch_map[combo[1]],
edgecolor='black', alpha=0.8)
if v>0:
if p == r"$U_{TM}$":
offset = y_offsets_u[mat]
elif p == r"$U_{O}$":
offset = y_offsets_u[mat]
elif p == r"$V_{TM,O}$":
offset = y_offsets_v[mat]
elif p == r"$a$":
offset = y_a[mat]
elif p == r"$\alpha$":
offset = y_angle[mat]
elif ax is ax_eg:
offset = y_offsets_eg[mat]
elif ax is ax_mu:
offset = y_offsets_mu[mat]
else:
offset = v+0.15
#target.text(x+0.02, v+val_offset, f"{v:.2f}",
target.text(x+0.02, offset, f"{v:.2f}",
ha='center', va='bottom',
fontsize=font-6, rotation=90)
return ax, ax2
# (a) a & α
ax_a, ax2 = draw_group(
ax= ax_a,
params= topParams,
ylims=((4,4.8),(89,92.5)),
ylabel=r"Lattice constant (Å)",
label="(a)",
twin_for=(r"$\alpha$", r"Angle (°)"), val_offset=0.03
)
ax_a.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.1f'))
# --- (a) ---
# a
expt_a = {
'MnO': [4.4315], # 1983 Phys. Rev. B 27 6964
#'FeO': [4.334], # 1984 Phys. Chem. Miner. 10 106–13
'FeO': [4.318], # J. Phys. C: Solid State Phys. 12 337
'CoO': [4.254], # 1991 J. Mater. Res. 6 2680–7
'NiO': [4.1705], # 1983 Phys. Rev. B 27 6964
}
# α
expt_alpha = {
'MnO': [90.60], # 1983 Phys. Rev. B 27 6964
'FeO': [89.55], # J. Phys. C: Solid State Phys. 12 337
'CoO': [90.0], #angle? cubic?
'NiO': [90.08], # 1983 Phys. Rev. B 27 6964
}
# layout
barW = 0.12
gapB = 0.04
extra = 0.2
gapM = 0.6
nC = len(comboOrder)
sW = nC*(barW+gapB) - gapB + extra # subgroup width
gW = len(topParams)*sW + gapM # group width
for i, mat in enumerate(materials):
g0 = i * gW
x0 = g0 - 0.05
x1 = g0 + (nC-1)*(barW+gapB) + barW - 0.05
for y in expt_a[mat]:
ax_a.hlines(
y, x0, x1,
colors='blue',
linestyles='--',
linewidth=2,
zorder=2
)
x0 = g0 - 0.05 + sW
x1 = g0 + (nC-1)*(barW+gapB) + barW - 0.05 +sW
if mat != 'FeO':
for y in expt_alpha[mat]:
ax2.hlines(
y, x0, x1,
colors='blue',
linestyles='--',
linewidth=2,
zorder=2
)
# --- Put parameter labels under (a): a and α ---
sW = nC*(barW+gapB) - gapB + extra
gW = len(topParams)*sW + gapM
for i, mat in enumerate(materials):
g0 = i * gW
for j, p in enumerate(topParams):
# center of the j-th sub-group
subCenter = g0 + j*sW + (nC*(barW+gapB)-gapB)/2 - 0.05
ax_a.text(subCenter, -0.03, p,
transform=ax_a.get_xaxis_transform(),
ha='center', va='top', fontsize=font)
# (b) U_{TM}, V_{TM,O}
draw_group(
ax= ax_uv,
params= middleParams,
ylims=((0,18),None),
ylabel="Hubbard parameter (eV)",
label="(b)"
)
ax_uv.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.1f'))
# --- Put parameter labels under (b): U_{TM} and V_{TM,O} ---
gW2 = len(middleParams)*sW + gapM
for i, mat in enumerate(materials):
g0 = i * gW2
for j, p in enumerate(middleParams):
subCenter = g0 + j*sW + (nC*(barW+gapB)-gapB)/2 - 0.05
ax_uv.text(subCenter, -0.03, p,
transform=ax_uv.get_xaxis_transform(),
ha='center', va='top', fontsize=font)
# (c) E_g
draw_group(
ax= ax_eg,
params= egParam,
ylims=((0,5.5),None),
ylabel=r"Band gap (eV)",
label="(c)", val_offset=0.1
)
ax_eg.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.1f'))
# (b) E_g
expt_eg = {
"MnO": [3.9, 4.1, 3.8, 4.2], # 1991 Phys. Rev. B 44 1530, 2008 Phys. Rev. B 77 165127, 1968 Fiz. Tverd. Tela 10 3082
"FeO": [2.4, 2.4], # 1973 J. Solid State. Chem. 12, 355
"CoO": [2.5, 2.6, 3.6], # 1991 Phys. Rev. B 44 6090–103, 2008 Phys. Rev. B 77 165127, 1972 J. Phys. Chem. Solids 33 893
"NiO": [4.3, 4.0, 3.7], # 1984 Phys. Rev. Lett. 53 2339, 2008 Phys. Rev. B 77 165127, 1965 Fiz. Tverd. Tela 7 1884
}
# layout defs
barW = 0.12
gapM = 0.6
extra = 0.2
gapB = 0.04
nC = len(comboOrder)
sW = nC*(barW+gapB) - gapB + extra
gW = len(egParam)*sW + gapM
def draw_expt_lines(ax, expt_dict, materials, gW, nC, barWidth, gap_bar,
x_shift=-0.05, color='blue', linestyle='--',
linewidth=2, zorder=2):
for i, mat in enumerate(materials):
vals = expt_dict.get(mat, [])
if np.isscalar(vals):
vals = [vals]
gStart = i * gW
x0 = gStart + x_shift
x1 = gStart + (nC - 1) * (barWidth + gap_bar) + barWidth + x_shift
for y in vals:
ax.hlines(y, x0, x1,
colors=color,
linestyles=linestyle,
linewidth=linewidth,
zorder=zorder)
draw_expt_lines(ax_eg, expt_eg, materials, gW, nC, barW, gapB)
# (d) μ_B
draw_group(
ax= ax_mu,
params= muParam,
ylims=((0,6),None),
ylabel=r"Mag. moment ($\mu_B$)",
label="(d)", val_offset=0.1
)
ax_mu.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.1f'))
# (c) μ_B
expt_mu = {
"MnO": [4.58, 4.79], #1983 Phys. Rev. B 27 6964, 1968 J. Chem. Phys. 48 990
"FeO": [3.32, 4.20], #1958 Phys. Rev. 110 1333–41, J. Phys. C: Solid State Phys. 12 337
"CoO": [3.35, 3.98], #1970 Phys. Rev. B 1 2243–9, 2001 Phys. Rev. B 64 052102
"NiO": [1.77, 1.90], #1983 Phys. Rev. B 27 6964, 1968 J. Chem. Phys. 48 990
}
for i, mat in enumerate(materials):
gStart = i * gW
x0 = gStart -0.05
x1 = gStart + (nC-1)*(barW+gapB) + barW -0.05
for idx, y in enumerate(expt_mu[mat]):
ax_mu.hlines(y, x0, x1,
colors='blue',
linestyles='--',
linewidth=2,
zorder=2)
# -----------------------------
# 3)
# -----------------------------
legend_elems = [
Patch(facecolor='green', edgecolor='black', hatch='', label='LRT'),
Patch(facecolor='darkorange', edgecolor='black', hatch='', label='eACBN0'),
Patch(facecolor='white', edgecolor='black', hatch='', label='DFT+$U$'),
Patch(facecolor='white', edgecolor='black', hatch='//',label='DFT+$U$+$V$'),
]
#fig.legend(handles=legend_elems, loc="upper center", ncol=4, fontsize=font-2)
fig.legend(handles=legend_elems, loc="upper center",
bbox_to_anchor=(0.5, 0.95),
ncol=4, fontsize=font)
#plt.tight_layout(rect=[0, 0, 1, 0.98])
fig.align_ylabels([ax_a, ax_uv, ax_eg, ax_mu])
plt.subplots_adjust(hspace=0.16, top = 0.9, bottom=0.08)
plt.savefig('SI_TMO_wo_O.pdf', bbox_inches='tight')
plt.show()
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
from matplotlib import rc, rcParams
from matplotlib.patches import Patch
mpl.rcParams['figure.autolayout'] = False
mpl.rcParams['figure.constrained_layout.use'] = False
# -----------------------------
# 0) font
# -----------------------------
font = 16
rc('text', usetex=False)
rc('font', family='Arial')
rcParams['font.size'] = font
mpl.rcParams['axes.linewidth'] = 1.5
mpl.rcParams['mathtext.fontset'] = 'custom'
mpl.rcParams['mathtext.rm'] = 'Arial'
mpl.rcParams['mathtext.it'] = 'Arial:italic'
mpl.rcParams['mathtext.bf'] = 'Arial:bold'
# -----------------------------
# 1) data
# -----------------------------
materials = ['MnO','FeO','CoO','NiO']
topParams = [r"$a$", r"$\alpha$"]
middleParams = [r"$U_{TM}$", r"$U_{O}$", r"$V_{TM,O}$"]
egParam = [r"E$_{g}$"]
muParam = [r"$\mu_B$"]
comboOrder = [
('LRT','DFT+U'),
('eACBN0','DFT+U'),
('LRT','DFT+U+V'),
('eACBN0','DFT+U+V'),
]
color_map = {'LRT':'green','eACBN0':'darkorange'}
hatch_map = {'DFT+U':'','DFT+U+V':'//'}
data = {}
# --- MnO ---
data[('MnO', r"$U_{TM}$")] = {('LRT','DFT+U'):4.75, ('eACBN0','DFT+U'):5.00,
('LRT','DFT+U+V'):4.80,('eACBN0','DFT+U+V'):5.22}
data[('MnO', r"$U_{O}$")] = {('LRT','DFT+U'):10.18, ('eACBN0','DFT+U'):2.94,
('LRT','DFT+U+V'):10.17,('eACBN0','DFT+U+V'):2.86}
data[('MnO', r"$V_{TM,O}$")] = {('LRT','DFT+U'):0.00, ('eACBN0','DFT+U'):0.00,
('LRT','DFT+U+V'):0.33, ('eACBN0','DFT+U+V'):2.71}
data[('MnO', r"$a$")] = {('LRT','DFT+U'):4.44, ('eACBN0','DFT+U'):4.46,
('LRT','DFT+U+V'):4.44, ('eACBN0','DFT+U+V'):4.42}
data[('MnO', r"$\alpha$")] = {('LRT','DFT+U'):90.61, ('eACBN0','DFT+U'):90.68,
('LRT','DFT+U+V'):90.62,('eACBN0','DFT+U+V'):90.71}
data[('MnO', r"E$_{g}$")] = {('LRT','DFT+U'):3.65, ('eACBN0','DFT+U'):2.31,
('LRT','DFT+U+V'):3.67, ('eACBN0','DFT+U+V'):2.34}
data[('MnO', r"$\mu_B$")] = {('LRT','DFT+U'):4.83, ('eACBN0','DFT+U'):4.79,
('LRT','DFT+U+V'):4.82, ('eACBN0','DFT+U+V'):4.67}
# --- FeO ---
data[('FeO', r"$U_{TM}$")] = {('LRT','DFT+U'):12.24, ('eACBN0','DFT+U'):6.06,
('LRT','DFT+U+V'):12.22,('eACBN0','DFT+U+V'):6.02}
data[('FeO', r"$U_{O}$")] = {('LRT','DFT+U'):10.33, ('eACBN0','DFT+U'):2.89,
('LRT','DFT+U+V'):10.33,('eACBN0','DFT+U+V'):2.66}
data[('FeO', r"$V_{TM,O}$")] = {('LRT','DFT+U'):0.00, ('eACBN0','DFT+U'):0.00,
('LRT','DFT+U+V'):0.01, ('eACBN0','DFT+U+V'):2.75}
data[('FeO', r"$a$")] = {('LRT','DFT+U'):4.42, ('eACBN0','DFT+U'):4.36,
('LRT','DFT+U+V'):4.42, ('eACBN0','DFT+U+V'):4.32}
data[('FeO', r"$\alpha$")] = {('LRT','DFT+U'):91.54, ('eACBN0','DFT+U'):91.67,
('LRT','DFT+U+V'):91.54,('eACBN0','DFT+U+V'):91.71}
data[('FeO', r"E$_{g}$")] = {('LRT','DFT+U'):4.80, ('eACBN0','DFT+U'):2.54,
('LRT','DFT+U+V'):4.80, ('eACBN0','DFT+U+V'):2.52}
data[('FeO', r"$\mu_B$")] = {('LRT','DFT+U'):3.95, ('eACBN0','DFT+U'):3.83,
('LRT','DFT+U+V'):3.95, ('eACBN0','DFT+U+V'):3.73}
# --- CoO ---
data[('CoO', r"$U_{TM}$")] = {('LRT','DFT+U'):6.48, ('eACBN0','DFT+U'):6.66,
('LRT','DFT+U+V'):6.52, ('eACBN0','DFT+U+V'):6.98}
data[('CoO', r"$U_{O}$")] = {('LRT','DFT+U'):9.99, ('eACBN0','DFT+U'):2.69,
('LRT','DFT+U+V'):9.98, ('eACBN0','DFT+U+V'):2.35}
data[('CoO', r"$V_{TM,O}$")] = {('LRT','DFT+U'):0.00, ('eACBN0','DFT+U'):0.00,
('LRT','DFT+U+V'):0.32, ('eACBN0','DFT+U+V'):2.87}
data[('CoO', r"$a$")] = {('LRT','DFT+U'):4.27, ('eACBN0','DFT+U'):4.28,
('LRT','DFT+U+V'):4.26, ('eACBN0','DFT+U+V'):4.25}
data[('CoO', r"$\alpha$")] = {('LRT','DFT+U'):89.96, ('eACBN0','DFT+U'):90.06,
('LRT','DFT+U+V'):89.96,('eACBN0','DFT+U+V'):90.02}
data[('CoO', r"E$_{g}$")] = {('LRT','DFT+U'):4.42, ('eACBN0','DFT+U'):3.15,
('LRT','DFT+U+V'):4.45, ('eACBN0','DFT+U+V'):3.26}
data[('CoO', r"$\mu_B$")] = {('LRT','DFT+U'):2.90, ('eACBN0','DFT+U'):2.86,
('LRT','DFT+U+V'):2.89, ('eACBN0','DFT+U+V'):2.76}
# --- NiO ---
data[('NiO', r"$U_{TM}$")] = {('LRT','DFT+U'):7.72, ('eACBN0','DFT+U'):8.19,
('LRT','DFT+U+V'):7.74, ('eACBN0','DFT+U+V'):7.64}
data[('NiO', r"$U_{O}$")] = {('LRT','DFT+U'):9.78, ('eACBN0','DFT+U'):2.78,
('LRT','DFT+U+V'):9.76, ('eACBN0','DFT+U+V'):2.22}
data[('NiO', r"$V_{TM,O}$")] = {('LRT','DFT+U'):0.00, ('eACBN0','DFT+U'):0.00,
('LRT','DFT+U+V'):0.28, ('eACBN0','DFT+U+V'):2.92}
data[('NiO', r"$a$")] = {('LRT','DFT+U'):4.21, ('eACBN0','DFT+U'):4.21,
('LRT','DFT+U+V'):4.21, ('eACBN0','DFT+U+V'):4.18}
data[('NiO', r"$\alpha$")] = {('LRT','DFT+U'):90.07, ('eACBN0','DFT+U'):90.06,
('LRT','DFT+U+V'):90.07,('eACBN0','DFT+U+V'):90.07}
data[('NiO', r"E$_{g}$")] = {('LRT','DFT+U'):5.08, ('eACBN0','DFT+U'):3.52,
('LRT','DFT+U+V'):5.09, ('eACBN0','DFT+U+V'):3.57}
data[('NiO', r"$\mu_B$")] = {('LRT','DFT+U'):1.91, ('eACBN0','DFT+U'):1.88,
('LRT','DFT+U+V'):1.91, ('eACBN0','DFT+U+V'):1.76}
y_a = {
'MnO': 4.5,
'FeO': 4.45,
'CoO': 4.3,
'NiO': 4.25,
}
y_angle = {
'MnO': 90.85,
'FeO': 91.8,
'CoO': 90.2,
'NiO': 90.2,
}
y_offsets_u = {
'MnO': 10.5,
'FeO': 12.6,
'CoO': 10.3,
'NiO': 10.3,
}
y_offsets_v = {
'MnO': 3,
'FeO': 3,
'CoO': 3.1,
'NiO': 3.1,
}
y_offsets_eg = {
'MnO': 4.4,
'FeO': 5.0,
'CoO': 4.6,
'NiO': 5.2,
}
y_offsets_mu = {
'MnO': 5.0,
'FeO': 4.4,
'CoO': 4.2,
'NiO': 2.1,
}
# -----------------------------
# 2) 4 subplot
# -----------------------------
fig, (ax_a, ax_U, ax_Eg, ax_mu) = plt.subplots(4,1, figsize=(10,12.5))
barW = 0.12
gapM = 0.6
extra = 0.2
gapB = 0.04
nC = len(comboOrder)
def draw_group(ax, params, ylims, ylabel, label,
twin_for=None, val_offset=0.2):
ax.set_ylim(*ylims[0])
ax.set_ylabel(ylabel, fontsize=font)
ax.grid(axis='y', linestyle='--', alpha=0.6)
ax.set_xticks([])
ax.text(-0.16,1.1,label, transform=ax.transAxes,
fontsize=font+6, ha='left', va='top')
ax2 = None
if twin_for:
ax2 = ax.twinx()
ax2.set_ylim(*ylims[1])
ax2.set_ylabel(twin_for[1], fontsize=font)
sW = nC*(barW+gapB)-gapB+extra
gW = len(params)*sW + gapM
for i, mat in enumerate(materials):
g0 = i*gW
if ax is ax_mu:
center = g0 + (len(params)*sW-extra)/2 - 0.05
ax.text(center, -0.07, mat,
transform=ax.get_xaxis_transform(),
ha='center', va='top', fontsize=font-2)
for j,p in enumerate(params):
sg = g0 + j*sW
for k,combo in enumerate(comboOrder):
x = sg + k*(barW+gapB)
v = data[(mat,p)][combo]
tgt = ax2 if (ax2 and p==twin_for[0]) else ax
tgt.bar(x, v, barW,
color=color_map[combo[0]],
hatch=hatch_map[combo[1]],
edgecolor='black', alpha=0.8)
if v>0:
if p == r"$U_{TM}$":
offset = y_offsets_u[mat]
elif p == r"$U_{O}$":
offset = y_offsets_u[mat]
elif p == r"$V_{TM,O}$":
offset = y_offsets_v[mat]
elif p == r"$a$":
offset = y_a[mat]
elif p == r"$\alpha$":
offset = y_angle[mat]
elif ax is ax_Eg:
offset = y_offsets_eg[mat]
elif ax is ax_mu:
offset = y_offsets_mu[mat]
else:
offset = v+0.15
#tgt.text(x+0.02, v+val_offset, f"{v:.2f}",
tgt.text(x+0.02, offset, f"{v:.2f}",
ha='center', va='bottom',
fontsize=font-6, rotation=90)
return ax, ax2
# (a) a & α
ax_a, ax2 = draw_group(ax_a, topParams,
((4.0,4.6),(89,92.5)),
r"Lattice constant (Å)", "(a)",
twin_for=(r"$\alpha$",r"Angle (°)"),
val_offset=0.03)
ax_a.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.1f'))
# --- (a) ---
# a
expt_a = {
'MnO': [4.4315], # 1983 Phys. Rev. B 27 6964
#'FeO': [4.334], # 1984 Phys. Chem. Miner. 10 106–13
'FeO': [4.318], # J. Phys. C: Solid State Phys. 12 337
'CoO': [4.254], # 1991 J. Mater. Res. 6 2680–7
'NiO': [4.1705], # 1983 Phys. Rev. B 27 6964
}
# α
expt_alpha = {
'MnO': [90.60], # 1983 Phys. Rev. B 27 6964
'FeO': [89.55], # J. Phys. C: Solid State Phys. 12 337
'CoO': [90.0], #angle? cubic?
'NiO': [90.08], # 1983 Phys. Rev. B 27 6964
}
# layout
barW = 0.12
gapB = 0.04
extra = 0.2
gapM = 0.6
nC = len(comboOrder)
sW = nC*(barW+gapB) - gapB + extra # subgroup width
gW = len(topParams)*sW + gapM # group width
for i, mat in enumerate(materials):
g0 = i * gW
x0 = g0 - 0.05
x1 = g0 + (nC-1)*(barW+gapB) + barW - 0.05
for y in expt_a[mat]:
ax_a.hlines(
y, x0, x1,
colors='blue',
linestyles='--',
linewidth=2,
zorder=2
)
x0 = g0 - 0.05 + sW
x1 = g0 + (nC-1)*(barW+gapB) + barW - 0.05 +sW
if mat != 'FeO':
for y in expt_alpha[mat]:
ax2.hlines(
y, x0, x1,
colors='blue',
linestyles='--',
linewidth=2,
zorder=2
)
# --- Put parameter labels under (a): a and α ---
sW = nC*(barW+gapB) - gapB + extra
gW = len(topParams)*sW + gapM
for i, mat in enumerate(materials):
g0 = i * gW
for j, p in enumerate(topParams):
# center of the j-th sub-group
subCenter = g0 + j*sW + (nC*(barW+gapB)-gapB)/2 - 0.05
ax_a.text(subCenter, -0.03, p,
transform=ax_a.get_xaxis_transform(),
ha='center', va='top', fontsize=font)
# (b) U_TM, U_O, V_TM,O
# --- panel (b): U_TM, U_O, V_TM,O with bigger bar-gap ---
old_gapB = gapB # remember the old barGap
gapB = 0.1 # make it larger (e.g. 0.1 instead of 0.04)
# recompute subgroup width with the new gapB
sW_b = nC*(barW+gapB) - gapB + extra
gW_b = len(middleParams)*sW_b + gapM
# draw it
draw_group(
ax= ax_U,
params= middleParams,
ylims=((0,15), None),
ylabel="Hubbard parameter (eV)",
label="(b)",
twin_for=None,
val_offset=0.3
)
ax_U.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.1f'))
# now put the param-names under (b), using ax_U not ax_uv!
for i, mat in enumerate(materials):
g0 = i * gW_b
for j, p in enumerate(middleParams):
sub_c = g0 + j*sW_b + (nC*(barW+gapB) - gapB)/2 - 0.05
ax_U.text(sub_c, -0.03, p,
transform=ax_U.get_xaxis_transform(),
ha='center', va='top', fontsize=font)
gapB = old_gapB # restore your default spacing
# (c) E_g
draw_group(ax_Eg, egParam,
((0,6),None),
r"Band gap (eV)", "(c)",
val_offset=0.1)
ax_Eg.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.1f'))
# (b) E_g
expt_eg = {
"MnO": [3.9, 4.1, 3.8, 4.2], # 1991 Phys. Rev. B 44 1530, 2008 Phys. Rev. B 77 165127, 1968 Fiz. Tverd. Tela 10 3082
"FeO": [2.4, 2.4], # 1973 J. Solid State. Chem. 12, 355
"CoO": [2.5, 2.6, 3.6], # 1991 Phys. Rev. B 44 6090–103, 2008 Phys. Rev. B 77 165127, 1972 J. Phys. Chem. Solids 33 893
"NiO": [4.3, 4.0, 3.7], # 1984 Phys. Rev. Lett. 53 2339, 2008 Phys. Rev. B 77 165127, 1965 Fiz. Tverd. Tela 7 1884
}
# layout defs
barW = 0.12
gapM = 0.6
extra = 0.2
gapB = 0.04
nC = len(comboOrder)
sW = nC*(barW+gapB) - gapB + extra
gW = len(egParam)*sW + gapM
def draw_expt_lines(ax, expt_dict, materials, gW, nC, barWidth, gap_bar,
x_shift=-0.05, color='blue', linestyle='--',
linewidth=2, zorder=2):
for i, mat in enumerate(materials):
vals = expt_dict.get(mat, [])
if np.isscalar(vals):
vals = [vals]
gStart = i * gW
x0 = gStart + x_shift
x1 = gStart + (nC - 1) * (barWidth + gap_bar) + barWidth + x_shift
for y in vals:
ax.hlines(y, x0, x1,
colors=color,
linestyles=linestyle,
linewidth=linewidth,
zorder=zorder)
draw_expt_lines(ax_Eg, expt_eg, materials, gW, nC, barW, gapB)
# (d) μ_B
draw_group(ax_mu, muParam,
((0,6),None),
r"Mag. moment ($\mu_B$)", "(d)",
val_offset=0.1)
ax_mu.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.1f'))
# (c) μ_B
expt_mu = {
"MnO": [4.58, 4.79], #1983 Phys. Rev. B 27 6964, 1968 J. Chem. Phys. 48 990
"FeO": [3.32, 4.20], #1958 Phys. Rev. 110 1333–41, J. Phys. C: Solid State Phys. 12 337
"CoO": [3.35, 3.98], #1970 Phys. Rev. B 1 2243–9, 2001 Phys. Rev. B 64 052102
"NiO": [1.77, 1.90], #1983 Phys. Rev. B 27 6964, 1968 J. Chem. Phys. 48 990
}
for i, mat in enumerate(materials):
gStart = i * gW
x0 = gStart -0.05
x1 = gStart + (nC-1)*(barW+gapB) + barW -0.05
for idx, y in enumerate(expt_mu[mat]):
ax_mu.hlines(y, x0, x1,
colors='blue',
linestyles='--',
linewidth=2,
zorder=2)
# -----------------------------
# 3)
# -----------------------------
legend_elems = [
Patch(facecolor='green', edgecolor='black', hatch='', label='LRT'),
Patch(facecolor='darkorange', edgecolor='black', hatch='', label='eACBN0'),
Patch(facecolor='white', edgecolor='black', hatch='', label='DFT+$U$'),
Patch(facecolor='white', edgecolor='black', hatch='//',label='DFT+$U$+$V$'),
]
fig.legend(handles=legend_elems, loc="upper center",
bbox_to_anchor=(0.5, 0.95),
ncol=4, fontsize=font)
#plt.tight_layout(rect=[0, 0, 1, 0.98])
fig.align_ylabels([ax_a, ax_U, ax_Eg, ax_mu])
plt.subplots_adjust(hspace=0.16, top = 0.9, bottom=0.08)
plt.savefig('SI_TMO_with_O.pdf', bbox_inches='tight')
plt.show()
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
from matplotlib import rc, rcParams
from matplotlib.patches import Patch
from matplotlib.gridspec import GridSpec
import matplotlib.ticker as mtick
mpl.rcParams['figure.autolayout'] = False
mpl.rcParams['figure.constrained_layout.use'] = False
# ─────────────────────────────────────────────────────────────────────────────
# Styling
font = 16
rc('text', usetex=False)
rc('font', family='Arial', size=font)
rcParams['axes.linewidth'] = 1.5
#rcParams.update({'figure.autolayout': True})
mpl.rcParams['mathtext.fontset'] = 'custom'
mpl.rcParams['mathtext.rm'] = 'Arial'
mpl.rcParams['mathtext.it'] = 'Arial:italic'
mpl.rcParams['mathtext.bf'] = 'Arial:bold'
# ─────────────────────────────────────────────────────────────────────────────
# Combo definitions
comboList = [
("LRT", "DFT+U"),
("eACBN0", "DFT+U"),
("LRT", "DFT+U+V"),
("eACBN0", "DFT+U+V"),
]
color_map = {"LRT": "green", "eACBN0": "darkorange"}
hatch_map = {"DFT+U": "", "DFT+U+V": "//"}
barW = 0.2
gap = 0.05
paramEx = 0.3
nC = len(comboList)
subW = nC * (barW + gap) - gap + paramEx
# ─────────────────────────────────────────────────────────────────────────────
# Data: self-consistent ZnO without O
data_top1 = {
("ZnO", r"$a$", m,t): (v, None)
for (m,t), v in zip(comboList, [3.313, 3.271, 3.314, 3.271])
}
data_top1.update({
("ZnO", r"$c$", m,t): (v, None)
for (m,t), v in zip(comboList, [5.259, 5.227, 5.259, 5.227])
})
data_bot1 = {
("ZnO", r"$U_{Zn}$", m,t): (v, None)
for (m,t), v in zip(comboList, [106.69, 16.09, 106.45, 16.06])
}
data_bot1.update({
("ZnO", r"$V_{Zn,O}$", m,t): (vs,vl)
for (m,t), (vs,vl) in zip(comboList, [(0.0,None), (0.0,None), (-0.53,-0.45), (2.87,2.88)])
})
data_bot1.update({
("ZnO", r"$E_g$", m,t): (v, None)
for (m,t), v in zip(comboList, [1.66, 1.47, 1.66, 1.46])
})
ac_off1 = {r"$a$":3.35, r"$c$":5.30}
y_off1 = {r"$U_{Zn}$":108, r"$V_{Zn,O}$":5.5}
eg_off1 = {r"$E_g$":1.75}
params_top = [r"$a$", r"$c$"]
params_uv = [r"$U_{Zn}$", r"$V_{Zn,O}$"]
#param_eg = [r"$E_g$"]
param_eg = [r"ZnO"]
# ─────────────────────────────────────────────────────────────────────────────
# Data: self-consistent ZnO with O
data_top2 = {
("ZnO", r"$a$", m,t): (v, None)
for (m,t), v in zip(comboList, [3.264, 3.233, 3.264, 3.232])
}
data_top2.update({
("ZnO", r"$c$", m,t): (v, None)
for (m,t), v in zip(comboList, [5.157, 5.152, 5.157, 5.153])
})
data_bot2 = {
("ZnO", r"$U_{Zn}$", m,t): (v, None)
for (m,t), v in zip(comboList, [97.30, 15.17, 97.37, 15.14])
}
data_bot2.update({
("ZnO", r"$U_{O}$", m,t): (v, None)
for (m,t), v in zip(comboList, [10.60, 7.34, 10.60, 7.30])
})
data_bot2.update({
("ZnO", r"$V_{Zn,O}$", m,t): (vs,vl)
for (m,t), (vs,vl) in zip(comboList, [(0.0,None), (0.0,None), (-0.50,-0.43), (2.97,2.98)])
})
data_bot2.update({
("ZnO", r"$E_g$", m,t): (v, None)
for (m,t), v in zip(comboList, [4.78, 3.40, 4.78, 3.39])
})
ac_off2 = {r"$a$":3.30, r"$c$":5.25}
y_off2 = {r"$U_{Zn}$":100, r"$U_{O}$":12, r"$V_{Zn,O}$":5.5}
eg_off2 = {r"$E_g$":5.00}
# ─────────────────────────────────────────────────────────────────────────────
# Build 2-row, 3-col grid
#fig = plt.figure(figsize=(10, 12.5))
fig = plt.figure(figsize=(12, 10))
gs = GridSpec(2, 5, figure=fig)#, height_ratios=[1, 1], width_ratios=[1,1,1], hspace=0.2, wspace=0.35)
# Top-left: lattice without O (a)
ax1 = fig.add_subplot(gs[0, 0:2])
ax1.set_ylabel("Lattice constant (Å)",fontsize=font+2)
ax1.set_ylim(3.0, 5.6)
ax1.grid(axis='y', linestyle='--', alpha=0.6)
ax1.set_xticks([])
for j, p in enumerate(params_top):
base = j * subW
for k,(m,t) in enumerate(comboList):
x = base + k*(barW+gap)
vs,_ = data_top1[("ZnO", p, m, t)]
ax1.bar(x, vs, barW, color=color_map[m], hatch=hatch_map[t], edgecolor='black', alpha=0.8)
ax1.text(x + barW/8, ac_off1[p], f"{vs:.3f}", ha='center', va='bottom', rotation=90, fontsize=font-6)
ax1.set_xticks([j*subW + (nC*barW-gap)/2 for j in range(len(params_top))])
ax1.set_xticklabels(params_top)
ax1.text(-0.22, 1.023, '(a)', transform=ax1.transAxes, fontsize=font+6, ha='left', va='top')
# Top-right: lattice with O (d)
ax2 = fig.add_subplot(gs[1, 0:2])
ax2.set_ylabel("Lattice constant (Å)",fontsize=font+2)
ax2.set_ylim(3.0, 5.6)
ax2.grid(axis='y', linestyle='--', alpha=0.6)
ax2.set_xticks([])
for j, p in enumerate(params_top):
base = j * subW
for k,(m,t) in enumerate(comboList):
x = base + k*(barW+gap)
vs,_ = data_top2[("ZnO", p, m, t)]
ax2.bar(x, vs, barW, color=color_map[m], hatch=hatch_map[t], edgecolor='black', alpha=0.8)
ax2.text(x + barW/8, ac_off2[p], f"{vs:.3f}", ha='center', va='bottom', rotation=90, fontsize=font-6)
ax2.set_xticks([j*subW + (nC*barW-gap)/2 for j in range(len(params_top))])
ax2.set_xticklabels(params_top)
ax2.text(-0.22, 1.023, '(d)', transform=ax2.transAxes, fontsize=font+6, ha='left', va='top')
# Bottom-left 4 panels: (b) UV without O, (c) Eg without O, (e) UV with O, (f) Eg with O
# (b) UV without O
ax3 = fig.add_subplot(gs[0, 2:4])
ax3.set_ylabel("Hubbard parameter (eV)",fontsize=font+2)
ax3.set_ylim(-5, 140)
ax3.set_yticks([0,25,50,75,100,125])
ax3.grid(axis='y', linestyle='--', alpha=0.6)
ax3.set_xticks([])
for j, p in enumerate(params_uv):
base = j * subW
for k,(m,t) in enumerate(comboList):
x = base + k*(barW+gap)
vs,vl = data_bot1[("ZnO", p, m, t)]
if abs(vs) > 1e-5:
ax3.bar(x, vs, barW, color=color_map[m], hatch=hatch_map[t], edgecolor='black', alpha=0.8)
if vl is not None and abs(vs) > 1e-5:
ax3.bar(x, vl, barW, color=color_map[m], hatch=hatch_map[t], edgecolor='black', alpha=0.4)
if abs(vs) > 1e-3 or (vl is not None and abs(vl) > 1e-3):
txt = f"{vs:.2f}" + (f"~{vl:.2f}" if vl else "")
ax3.text(x + barW/8, y_off1[p], txt, ha='center', va='bottom', rotation=90, fontsize=font-6)
ax3.set_xticks([j*subW + (nC*barW-gap)/2 for j in range(len(params_uv))])
ax3.set_xticklabels(params_uv, fontsize=font)
ax3.text(-0.22, 1.023, '(b)', transform=ax3.transAxes, fontsize=font+6, ha='left', va='top')
# (c) Eg without O
ax4 = fig.add_subplot(gs[0, 4])
ax4.set_ylabel("Band gap (eV)",fontsize=font+2)
ax4.set_ylim(0, 4)
ax4.set_yticks([0,1,2,3,4])
ax4.grid(axis='y', linestyle='--', alpha=0.6)
ax4.set_xticks([])
for k,(m,t) in enumerate(comboList):
x = k*(barW+gap)
vs,_ = data_bot1[("ZnO", r"$E_g$", m, t)]
ax4.bar(x, vs, barW, color=color_map[m], hatch=hatch_map[t], edgecolor='black', alpha=0.8)
ax4.text(x + barW/10, eg_off1[r"$E_g$"], f"{vs:.2f}", ha='center', va='bottom', rotation=90, fontsize=font-6)
ax4.set_xticks([(nC*barW-gap)/2])
ax4.set_xticklabels(param_eg, fontsize=font)
ax4.axhline(3.3, linestyle='--', color = 'blue', linewidth=3)
ax4.axhline(3.4, linestyle='--', color = 'blue', linewidth=3)
ax4.text(-0.55, 1.023, '(c)', transform=ax4.transAxes, fontsize=font+6, ha='left', va='top')
ax4.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.1f'))
# (e) UV with O
ax5 = fig.add_subplot(gs[1, 2:4])
ax5.set_ylabel("Hubbard parameter (eV)",fontsize=font+2)
ax5.set_ylim(-5, 140)
ax5.set_yticks([0,25,50,75,100,125])
ax5.grid(axis='y', linestyle='--', alpha=0.6)
ax5.set_xticks([])
for j, p in enumerate([r"$U_{Zn}$", r"$U_{O}$", r"$V_{Zn,O}$"]):
base = j * subW
for k,(m,t) in enumerate(comboList):
x = base + k*(barW+gap)
vs,vl = data_bot2[("ZnO", p, m, t)]
if abs(vs) > 1e-5:
ax5.bar(x, vs, barW, color=color_map[m], hatch=hatch_map[t], edgecolor='black', alpha=0.8)
if vl is not None and abs(vs) > 1e-5:
ax5.bar(x, vl, barW, color=color_map[m], hatch=hatch_map[t], edgecolor='black', alpha=0.4)
if abs(vs) > 1e-3 or (vl is not None and abs(vl) > 1e-3):
txt = f"{vs:.2f}" + (f"~{vl:.2f}" if vl else "")
ax5.text(x + barW/8, y_off2[p], txt, ha='center', va='bottom', rotation=90, fontsize=font-6)
ax5.set_xticks([j*subW + (nC*barW-gap)/2 for j in range(3)])
ax5.set_xticklabels([r"$U_{Zn}$", r"$U_{O}$", r"$V_{Zn,O}$"], fontsize=font)
ax5.text(-0.22, 1.023, '(e)', transform=ax5.transAxes, fontsize=font+6, ha='left', va='top')
# (f) Eg with O
ax6 = fig.add_subplot(gs[1, 4])
ax6.set_ylabel("Band gap (eV)",fontsize=font+2)
ax6.set_ylim(0, 6)
ax6.grid(axis='y', linestyle='--', alpha=0.6)
ax6.set_xticks([])
for k,(m,t) in enumerate(comboList):
x = k*(barW+gap)
vs,_ = data_bot2[("ZnO", r"$E_g$", m, t)]
ax6.bar(x, vs, barW, color=color_map[m], hatch=hatch_map[t], edgecolor='black', alpha=0.8)
ax6.text(x + barW/10, eg_off2[r"$E_g$"], f"{vs:.2f}", ha='center', va='bottom', rotation=90, fontsize=font-6)
ax6.set_xticks([(nC*barW-gap)/2])
ax6.set_xticklabels(param_eg, fontsize=font)
ax6.axhline(3.3, linestyle='--', color = 'blue', linewidth=3) # J. Appl. Phys. 84, 3912 (1998)
ax6.axhline(3.4, linestyle='--', color = 'blue', linewidth=3) # J. Appl. Phys. 84, 3912 (1998)
ax6.text(-0.55, 1.023, '(f)', transform=ax6.transAxes, fontsize=font+6, ha='left', va='top')
ax6.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.1f'))
exp_vals = {r"$a$":3.249, r"$c$":5.207}
subGroupWidth = nC*(barW+gap) - gap*0.5
for ax in (ax1, ax2):
for j, p in enumerate(params_top):
x0 = j*subW - gap*2
x1 = x0 + subGroupWidth
y = exp_vals[p]
ax.hlines(y, x0, x1,
colors='blue',
linestyle='--',
linewidth=3)
# Legend
legend_elems = [
Patch(facecolor="green", edgecolor="black", hatch="", label="LRT"),
Patch(facecolor="darkorange", edgecolor="black", hatch="", label="eACBN0"),
Patch(facecolor="white", edgecolor="black", hatch="", label="DFT+$U$"),
Patch(facecolor="white", edgecolor="black", hatch="//", label="DFT+$U$+$V$"),
]
#plt.subplots_adjust(top=0.9)
fig.legend(handles=legend_elems, loc="upper center",
bbox_to_anchor=(0.5, 1.015),
ncol=4, fontsize=font)
plt.subplots_adjust(
left=0.05, right=0.98, top=0.95, bottom=0.05,
hspace=0.12, wspace=0.65
)
#plt.tight_layout(rect=[0, 0, 1, 0.98])
plt.savefig('SI_ZnO.pdf', bbox_inches='tight')
plt.show()
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import rc, rcParams
from matplotlib.patches import Patch
from matplotlib.gridspec import GridSpec
# ─────────────────────────────────────────────────────────────────────────────
# Styling
font = 16
rc('text', usetex=False)
rc('font', family='Arial', size=font)
rcParams['axes.linewidth'] = 1.5
#rcParams.update({'figure.autolayout': False})
# ─────────────────────────────────────────────────────────────────────────────
# Combo definitions
comboList = [
("LRT", "DFT+U"),
("eACBN0", "DFT+U"),
("LRT", "DFT+U+V"),
("eACBN0", "DFT+U+V"),
]
color_map = {"LRT": "green", "eACBN0": "darkorange"}
hatch_map = {"DFT+U": "", "DFT+U+V": "//"}
barW = 0.2
gap = 0.05
paramEx = 0.3
nC = len(comboList)
subW = nC * (barW + gap) - gap + paramEx
# ─────────────────────────────────────────────────────────────────────────────
# Data set 1: ZrO2 without U_O
data1_top = {
("ZrO2", r"$a$", "LRT", "DFT+U"): (5.169, None),
("ZrO2", r"$a$", "eACBN0", "DFT+U"): (5.132, None),
("ZrO2", r"$a$", "LRT", "DFT+U+V"): (5.159, None),
("ZrO2", r"$a$", "eACBN0", "DFT+U+V"): (5.118, None),
("ZrO2", r"$b$", "LRT", "DFT+U"): (5.223, None),
("ZrO2", r"$b$", "eACBN0", "DFT+U"): (5.213, None),
("ZrO2", r"$b$", "LRT", "DFT+U+V"): (5.218, None),
("ZrO2", r"$b$", "eACBN0", "DFT+U+V"): (5.192, None),
("ZrO2", r"$c$", "LRT", "DFT+U"): (5.322, None),
("ZrO2", r"$c$", "eACBN0", "DFT+U"): (5.297, None),
("ZrO2", r"$c$", "LRT", "DFT+U+V"): (5.329, None),
("ZrO2", r"$c$", "eACBN0", "DFT+U+V"): (5.327, None),
}
data1_bottom = {
("ZrO2", r"$U_{Zr}$", "LRT", "DFT+U"): (2.76, None),
("ZrO2", r"$U_{Zr}$", "eACBN0", "DFT+U"): (0.28, None),
("ZrO2", r"$U_{Zr}$", "LRT", "DFT+U+V"): (3.06, None),
("ZrO2", r"$U_{Zr}$", "eACBN0", "DFT+U+V"): (0.36, None),
("ZrO2", r"$V_{Zr,O}$", "LRT", "DFT+U"): (0.00, None),
("ZrO2", r"$V_{Zr,O}$", "eACBN0", "DFT+U"): (0.00, None),
("ZrO2", r"$V_{Zr,O}$", "LRT", "DFT+U+V"): (0.62, 0.82),
("ZrO2", r"$V_{Zr,O}$", "eACBN0", "DFT+U+V"): (2.28, 2.54),
("ZrO2", r"$E_g$", "LRT", "DFT+U"): (4.04, None),
("ZrO2", r"$E_g$", "eACBN0", "DFT+U"): (3.63, None),
("ZrO2", r"$E_g$", "LRT", "DFT+U+V"): (4.33, None),
("ZrO2", r"$E_g$", "eACBN0", "DFT+U+V"): (4.53, None),
}
ac_off1 = {r"$a$": 5.18, r"$b$": 5.23, r"$c$": 5.34}
y_off1 = {r"$U_{Zr}$": 3.15, r"$V_{Zr,O}$": 2.60}
eg_off1 = {r"$E_g$": 4.60}
# ─────────────────────────────────────────────────────────────────────────────
# Data set 2: ZrO2 including U_O
data2_top = {
("ZrO2", r"$a$", "LRT", "DFT+U"): (5.197, None),
("ZrO2", r"$a$", "eACBN0", "DFT+U"): (5.152, None),
("ZrO2", r"$a$", "LRT", "DFT+U+V"): (5.185, None),
("ZrO2", r"$a$", "eACBN0", "DFT+U+V"): (5.129, None),
("ZrO2", r"$b$", "LRT", "DFT+U"): (5.195, None),
("ZrO2", r"$b$", "eACBN0", "DFT+U"): (5.192, None),
("ZrO2", r"$b$", "LRT", "DFT+U+V"): (5.192, None),
("ZrO2", r"$b$", "eACBN0", "DFT+U+V"): (5.183, None),
("ZrO2", r"$c$", "LRT", "DFT+U"): (5.328, None),
("ZrO2", r"$c$", "eACBN0", "DFT+U"): (5.290, None),
("ZrO2", r"$c$", "LRT", "DFT+U+V"): (5.326, None),
("ZrO2", r"$c$", "eACBN0", "DFT+U+V"): (5.299, None),
}
data2_bottom = {
("ZrO2", r"$U_{Zr}$", "LRT", "DFT+U"): (2.75, None),
("ZrO2", r"$U_{Zr}$", "eACBN0", "DFT+U"): (0.20, None),
("ZrO2", r"$U_{Zr}$", "LRT", "DFT+U+V"): (2.79, None),
("ZrO2", r"$U_{Zr}$", "eACBN0", "DFT+U+V"): (0.27, None),
("ZrO2", r"$U_{O}$", "LRT", "DFT+U"): (8.85, 9.27),
("ZrO2", r"$U_{O}$", "eACBN0", "DFT+U"): (7.68, 8.18),
("ZrO2", r"$U_{O}$", "LRT", "DFT+U+V"): (8.91, 9.31),
("ZrO2", r"$U_{O}$", "eACBN0", "DFT+U+V"): (7.50, 7.87),
("ZrO2", r"$V_{Zr,O}$", "LRT", "DFT+U"): (0.00, None),
("ZrO2", r"$V_{Zr,O}$", "eACBN0", "DFT+U"): (0.00, None),
("ZrO2", r"$V_{Zr,O}$", "LRT", "DFT+U+V"): (0.51, 0.68),
("ZrO2", r"$V_{Zr,O}$", "eACBN0", "DFT+U+V"): (2.22, 2.42),
("ZrO2", r"$E_g$", "LRT", "DFT+U"): (5.75, None),
("ZrO2", r"$E_g$", "eACBN0", "DFT+U"): (5.00, None),
("ZrO2", r"$E_g$", "LRT", "DFT+U+V"): (5.94, None),
("ZrO2", r"$E_g$", "eACBN0", "DFT+U+V"): (5.68, None),
}
ac_off2 = {r"$a$": 5.21, r"$b$": 5.22, r"$c$": 5.335}
y_off2 = {r"$U_{Zr}$": 3.00, r"$U_{O}$": 9.50, r"$V_{Zr,O}$": 2.60}
eg_off2 = {r"$E_g$": 6.05}
params_top = [r"$a$", r"$b$", r"$c$"]
params_uv1 = [r"$U_{Zr}$", r"$V_{Zr,O}$"]
params_uv2 = [r"$U_{Zr}$", r"$U_{O}$", r"$V_{Zr,O}$"]
#param_eg = [r"$E_g$"]
param_eg = [r"ZrO$_2$"]
# ─────────────────────────────────────────────────────────────────────────────
# Build 2x4 layout
fig = plt.figure(figsize=(12, 10))
gs = GridSpec(2, 5, figure=fig)
# (a) top-left: lattice without U_O
ax1 = fig.add_subplot(gs[0, 0:2])
ax1.set_ylabel("Lattice constant (Å)",fontsize=font+2)
ax1.set_ylim(5.0, 5.4)
ax1.set_yticks([5.4,5.3,5.2,5.1,5.0])
ax1.grid(axis='y', linestyle='--', alpha=0.6)
ax1.set_xticks([])
for j, p in enumerate(params_top):
base = j * subW
for k, (m, t) in enumerate(comboList):
x = base + k*(barW+gap)
vs, _ = data1_top[("ZrO2", p, m, t)]
ax1.bar(x, vs, barW, color=color_map[m], hatch=hatch_map[t], edgecolor='black', alpha=0.8)
ax1.text(x + barW/8, ac_off1[p], f"{vs:.3f}", ha='center', va='bottom', rotation=90, fontsize=font-6)
ax1.set_xticks([j*subW + (nC*barW-gap)/2 for j in range(len(params_top))])
ax1.set_xticklabels(params_top)
ax1.text(-0.23, 1.023, '(a)', transform=ax1.transAxes, fontsize=font+6, ha='left', va='top')
ax1.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.1f'))
# (d) top-right: lattice with U_O
ax2 = fig.add_subplot(gs[1, 0:2])
ax2.set_ylabel("Lattice constant (Å)",fontsize=font+2)
ax2.set_ylim(5.0, 5.4)
ax2.set_yticks([5.4,5.3,5.2,5.1,5.0])
ax2.grid(axis='y', linestyle='--', alpha=0.6)
ax2.set_xticks([])
for j, p in enumerate(params_top):
base = j * subW
for k, (m, t) in enumerate(comboList):
x = base + k*(barW+gap)
vs, _ = data2_top[("ZrO2", p, m, t)]
ax2.bar(x, vs, barW, color=color_map[m], hatch=hatch_map[t], edgecolor='black', alpha=0.8)
ax2.text(x + barW/8, ac_off2[p], f"{vs:.3f}", ha='center', va='bottom', rotation=90, fontsize=font-6)
ax2.set_xticks([j*subW + (nC*barW-gap)/2 for j in range(len(params_top))])
ax2.set_xticklabels(params_top)
ax2.text(-0.22, 1.023, '(d)', transform=ax2.transAxes, fontsize=font+6, ha='left', va='top')
ax2.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.1f'))
# draw experimental dashed lines on both top panels
exp_vals = {r"$a$": 5.145, r"$b$": 5.2075, r"$c$": 5.3107}
subGroupWidth = nC*(barW + gap) - gap
for ax, off in [(ax1, 0), (ax2, 2)]:
for j, p in enumerate(params_top):
x0 = j*subW - gap * 2
x1 = x0 + subGroupWidth + gap * 0.5
y = exp_vals[p]
ax.hlines(y, x0, x1, colors='blue', linestyle='--', linewidth=3)
# (b) bottom-left: UV without U_O
ax3 = fig.add_subplot(gs[0, 2:4])
ax3.set_ylabel("Hubbard parameter (eV)",fontsize=font+2)
ax3.set_ylim(0, 4)
ax3.set_yticks([4,3,2,1,0])
ax3.grid(axis='y', linestyle='--', alpha=0.6)
ax3.set_xticks([])
for j, p in enumerate(params_uv1):
base = j * subW
for k, (m, t) in enumerate(comboList):
x = base + k*(barW+gap)
vs, vl = data1_bottom[("ZrO2", p, m, t)]
ax3.bar(x, vs, barW, color=color_map[m], hatch=hatch_map[t], edgecolor='black', alpha=0.8)
if vl is not None:
ax3.bar(x, vl, barW, color=color_map[m], hatch=hatch_map[t], edgecolor='black', alpha=0.4)
if abs(vs) > 1e-3 or (vl is not None and abs(vl) > 1e-3):
txt = f"{vs:.2f}" + (f"~{vl:.2f}" if vl else "")
ax3.text(x + barW/8, y_off1[p], txt, ha='center', va='bottom', rotation=90, fontsize=font-6)
ax3.set_xticks([j*subW + (nC*barW-gap)/2 for j in range(len(params_uv1))])
ax3.set_xticklabels(params_uv1, fontsize=font)
ax3.text(-0.24, 1.023, '(b)', transform=ax3.transAxes, fontsize=font+6, ha='left', va='top')
ax3.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.1f'))
# (c) Eg without U_O
ax4 = fig.add_subplot(gs[0, 4])
ax4.set_ylabel("Band gap (eV)",fontsize=font+2)
ax4.set_ylim(2, 6)
ax4.set_yticks([2,3,4,5,6])
ax4.grid(axis='y', linestyle='--', alpha=0.6)
ax4.set_xticks([])
for k, (m, t) in enumerate(comboList):
x = k*(barW+gap)
vs, _ = data1_bottom[("ZrO2", r"$E_g$", m, t)]
ax4.bar(x, vs, barW, color=color_map[m], hatch=hatch_map[t], edgecolor='black', alpha=0.8)
ax4.text(x + barW/10, eg_off1[r"$E_g$"], f"{vs:.2f}", ha='center', va='bottom', rotation=90, fontsize=font-6)
ax4.set_xticks([(nC*barW-gap)/2])
ax4.set_xticklabels(param_eg, fontsize=font)
ax4.axhline(5.50, linestyle='--', color='blue', linewidth=3) # Phys. Rev. B 78, 085114 (2008)
ax4.text(-0.55, 1.023, '(c)', transform=ax4.transAxes, fontsize=font+6, ha='left', va='top')
ax4.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.1f'))
# (e) bottom-left of two: UV with U_O
ax5 = fig.add_subplot(gs[1, 2:4])
ax5.set_ylabel("Hubbard parameter (eV)",fontsize=font+2)
ax5.set_ylim(0, 12)
ax5.grid(axis='y', linestyle='--', alpha=0.6)
ax5.set_xticks([])
for j, p in enumerate(params_uv2):
base = j * subW
for k, (m, t) in enumerate(comboList):
x = base + k*(barW+gap)
vs, vl = data2_bottom[("ZrO2", p, m, t)]
ax5.bar(x, vs, barW, color=color_map[m], hatch=hatch_map[t], edgecolor='black', alpha=0.8)
if vl is not None:
ax5.bar(x, vl, barW, color=color_map[m], hatch=hatch_map[t], edgecolor='black', alpha=0.4)
if abs(vs) > 1e-3 or (vl is not None and abs(vl) > 1e-3):
txt = f"{vs:.2f}" + (f"~{vl:.2f}" if vl else "")
ax5.text(x + barW/8, y_off2[p], txt, ha='center', va='bottom', rotation=90, fontsize=font-6)
ax5.set_xticks([j*subW + (nC*barW-gap)/2 for j in range(len(params_uv2))])
ax5.set_xticklabels(params_uv2, fontsize=font)
ax5.text(-0.24, 1.023, '(e)', transform=ax5.transAxes, fontsize=font+6, ha='left', va='top')
ax5.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.1f'))
# (f) Eg with U_O
ax6 = fig.add_subplot(gs[1, 4])
ax6.set_ylabel("Band gap (eV)",fontsize=font+2)
ax6.set_ylim(4, 7)
ax6.set_yticks([4,5,6,7])
ax6.grid(axis='y', linestyle='--', alpha=0.6)
ax6.set_xticks([])
for k, (m, t) in enumerate(comboList):
x = k*(barW+gap)
vs, _ = data2_bottom[("ZrO2", r"$E_g$", m, t)]
ax6.bar(x, vs, barW, color=color_map[m], hatch=hatch_map[t], edgecolor='black', alpha=0.8)
ax6.text(x + barW/10, eg_off2[r"$E_g$"], f"{vs:.2f}", ha='center', va='bottom', rotation=90, fontsize=font-6)
ax6.set_xticks([(nC*barW-gap)/2])
ax6.set_xticklabels(param_eg, fontsize=font)
ax6.axhline(5.50, linestyle='--', color='blue', linewidth=3) # Phys. Rev. B 78, 085114 (2008)
ax6.text(-0.55, 1.023, '(f)', transform=ax6.transAxes, fontsize=font+6, ha='left', va='top')
ax6.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.1f'))
# Legend
legend_elems = [
Patch(facecolor="green", edgecolor="black", hatch="", label="LRT"),
Patch(facecolor="darkorange", edgecolor="black", hatch="", label="eACBN0"),
Patch(facecolor="white", edgecolor="black", hatch="", label="DFT+$U$"),
Patch(facecolor="white", edgecolor="black", hatch="//", label="DFT+$U$+$V$"),
]
fig.legend(handles=legend_elems, loc="upper center",
bbox_to_anchor=(0.5, 1.015),
ncol=4, fontsize=font)
plt.subplots_adjust(
left=0.05, right=0.98, top=0.95, bottom=0.05,
hspace=0.12, wspace=0.65
)
fig.align_ylabels([ax3, ax5])
#plt.tight_layout(rect=[0, 0, 1, 0.96])
plt.savefig('SI_ZrO2.pdf', dpi=300, bbox_inches='tight')
plt.show()
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Patch
from matplotlib import rc, rcParams
from matplotlib.gridspec import GridSpec
mpl.rcParams['figure.autolayout'] = False
mpl.rcParams['figure.constrained_layout.use'] = False
# -----------------------------
# 0) Font/style
# -----------------------------
font = 16
rc('text', usetex=False)
rc('font', family='Arial')
rcParams['font.size'] = font
rcParams['axes.linewidth'] = 1.5
# -----------------------------
# 1) combolist + styling
# -----------------------------
comboList = [
("LRT", "DFT+U"),
("eACBN0", "DFT+U"),
("LRT", "DFT+U+V"),
("eACBN0", "DFT+U+V"),
]
color_map = {"LRT":"green","eACBN0":"darkorange"}
hatch_map = {"DFT+U":"", "DFT+U+V":"//"}
barW = 0.25
gap = 0.05
nC = len(comboList)
# -----------------------------
# 2) data dicts
# -----------------------------
data_top = {
(r"$a$", m, t): v for (r, m, t), v in [
( (r"$a$", "LRT","DFT+U"), (3.994, None) ),
( (r"$a$", "LRT","DFT+U+V"), (4.006, None) ),
( (r"$a$", "eACBN0","DFT+U"), (3.998, None) ),
( (r"$a$", "eACBN0","DFT+U+V"),(4.048, None) ),
]
}
data_top.update({
(r"$\alpha$", m, t): v for (r, m, t), v in [
( (r"$\alpha$", "LRT","DFT+U"), (90.00, None) ),
( (r"$\alpha$", "LRT","DFT+U+V"), (89.89, None) ),
( (r"$\alpha$", "eACBN0","DFT+U"), (89.87, None) ),
( (r"$\alpha$", "eACBN0","DFT+U+V"),(89.34, None) ),
]
})
data_bottom = {
(r"$U_{Ti}$", m, t): v for (r, m, t), v in [
( (r"$U_{Ti}$", "LRT","DFT+U"), (5.60, None) ),
( (r"$U_{Ti}$", "LRT","DFT+U+V"), (6.20, None) ),
( (r"$U_{Ti}$", "eACBN0","DFT+U"), (0.27, None) ),
( (r"$U_{Ti}$", "eACBN0","DFT+U+V"),(0.33, None) ),
]
}
data_bottom.update({
(r"$V_{Ti,O}$", m, t): v for (r, m, t), v in [
( (r"$V_{Ti,O}$","LRT","DFT+U"), (0.00, None) ),
( (r"$V_{Ti,O}$","LRT","DFT+U+V"), (0.97, 1.12) ),
( (r"$V_{Ti,O}$","eACBN0","DFT+U"), (0.00, None) ),
( (r"$V_{Ti,O}$","eACBN0","DFT+U+V"),(2.21, 2.71) ),
]
})
data_bottom.update({
(r"$E_{g}$", m, t): v for (r, m, t), v in [
( (r"$E_{g}$", "LRT","DFT+U"), (2.48, None) ),
( (r"$E_{g}$", "LRT","DFT+U+V"), (3.20, None) ),
( (r"$E_{g}$", "eACBN0","DFT+U"), (2.33, None) ),
( (r"$E_{g}$", "eACBN0","DFT+U+V"),(4.25, None) ),
]
})
# -----------------------------
# 2-2) data dicts
# -----------------------------
data_top2 = {
(r"$a$", m, t): v for (r, m, t), v in [
( (r"$a$", "LRT","DFT+U"), (4.006, None) ),
( (r"$a$", "LRT","DFT+U+V"), (4.003, None) ),
( (r"$a$", "eACBN0","DFT+U"), (3.986, None) ),
( (r"$a$", "eACBN0","DFT+U+V"),(4.034, None) ),
]
}
data_top2.update({
(r"$\alpha$", m, t): v for (r, m, t), v in [
( (r"$\alpha$", "LRT","DFT+U"), (90.00, None) ),
( (r"$\alpha$", "LRT","DFT+U+V"), (90.00, None) ),
( (r"$\alpha$", "eACBN0","DFT+U"), (90.00, None) ),
( (r"$\alpha$", "eACBN0","DFT+U+V"),(89.70, None) ),
]
})
data_bottom2 = {
(r"$U_{Ti}$", m, t): v for (r, m, t), v in [
( (r"$U_{Ti}$", "LRT","DFT+U"), (5.99, None) ),
( (r"$U_{Ti}$", "LRT","DFT+U+V"), (6.06, None) ),
( (r"$U_{Ti}$", "eACBN0","DFT+U"), (0.23, None) ),
( (r"$U_{Ti}$", "eACBN0","DFT+U+V"),(0.25, None) ),
]
}
data_bottom2.update({
(r"$U_{O}$", m, t): v for (r, m, t), v in [
( (r"$U_{O}$", "LRT","DFT+U"), (9.04, None) ),
( (r"$U_{O}$", "LRT","DFT+U+V"), (9.13, None) ),
( (r"$U_{O}$", "eACBN0","DFT+U"), (7.52, None) ),
( (r"$U_{O}$", "eACBN0","DFT+U+V"),(7.36, None) ),
]
})
data_bottom2.update({
(r"$V_{Ti,O}$", m, t): v for (r, m, t), v in [
( (r"$V_{Ti,O}$","LRT","DFT+U"), (0.00, None) ),
( (r"$V_{Ti,O}$","LRT","DFT+U+V"), (0.99, None) ),
( (r"$V_{Ti,O}$","eACBN0","DFT+U"), (0.00, None) ),
( (r"$V_{Ti,O}$","eACBN0","DFT+U+V"),(2.19, 2.59) ),
]
})
data_bottom2.update({
(r"$E_{g}$", m, t): v for (r, m, t), v in [
( (r"$E_{g}$", "LRT","DFT+U"), (3.84, None) ),
( (r"$E_{g}$", "LRT","DFT+U+V"), (4.15, None) ),
( (r"$E_{g}$", "eACBN0","DFT+U"), (2.64, None) ),
( (r"$E_{g}$", "eACBN0","DFT+U+V"),(4.67, None) ),
]
})
y_offset={
r"$U_{Ti}$": 6.4,
r"$V_{Ti,O}$": 2.9,
r"$U_{O}$": 9.3,
}
# -----------------------------
# 3) Make figure / grids
# -----------------------------
from matplotlib.gridspec import GridSpec
def draw_row(ax_a, ax_alpha, ax_uv, ax_eg,
data_top_row, data_bottom_row,
has_UO=False,
y_offsets=None,
a_ylim=(3.98, 4.075),
alpha_ylim=(89.2, 90.5),
uv_ylim=(0, 11),
eg_ylim=(0, 6),
a_text_y=None,
alpha_text_y=None,
eg_text_y=None,
row_label_prefix=''):
barW = 0.25
gap = 0.05
nC = len(comboList)
groupW = nC*barW + (nC-1)*gap
cx = groupW/2 - barW/2
# ---------- (a) a(Å) ----------
ax_a.set_ylabel(r"Lattice constant (Å)",fontsize=font+2)
ax_a.set_ylim(*a_ylim)
ax_a.grid(axis='y', linestyle='--', alpha=0.6)
for k, (m, t) in enumerate(comboList):
x = k*(barW+gap)
vs, _ = data_top_row[(r"$a$", m, t)]
ax_a.bar(x, vs, barW, color=color_map[m], hatch=hatch_map[t],
edgecolor='black', alpha=0.8, zorder=2)
if a_text_y is not None:
ax_a.text(x+barW/10, a_text_y, f"{vs:.3f}",
ha='center', va='bottom', rotation=90, fontsize=font-6)
exp_a = 4.004 # J. Phys. Chem. 97, 2368 (1993)
ax_a.axhline(y=exp_a, color='blue', linestyle='--', linewidth=3)
ax_a.set_xticks([cx])
ax_a.set_xticklabels([r"$a$"], fontsize=font)
# ---------- (b) alpha(°) ----------
ax_alpha.set_ylabel(r"Angle (°)",fontsize=font+2)
ax_alpha.set_ylim(*alpha_ylim)
ax_alpha.grid(axis='y', linestyle='--', alpha=0.6)
for k, (m, t) in enumerate(comboList):
x = k*(barW+gap)
vs, _ = data_top_row[(r"$\alpha$", m, t)]
ax_alpha.bar(x, vs, barW, color=color_map[m], hatch=hatch_map[t],
edgecolor='black', alpha=0.8, zorder=2)
if alpha_text_y is not None:
ax_alpha.text(x+barW/10, alpha_text_y, f"{vs:.2f}",
ha='center', va='bottom', rotation=90, fontsize=font-6)
exp_alpha = 89.84 # J. Phys. Chem. 97, 2368 (1993)
ax_alpha.axhline(y=exp_alpha, color='blue', linestyle='--', linewidth=3)
ax_alpha.set_xticks([cx])
ax_alpha.set_xticklabels([r"$\alpha$"], fontsize=font)
# ---------- (c) U/V ----------
ax_uv.set_ylabel("Hubbard parameter (eV)",fontsize=font+2)
ax_uv.set_ylim(*uv_ylim)
ax_uv.grid(axis='y', linestyle='--', alpha=0.6)
if has_UO:
params_uv = [r"$U_{Ti}$", r"$U_{O}$", r"$V_{Ti,O}$"]
else:
params_uv = [r"$U_{Ti}$", r"$V_{Ti,O}$"]
groupW_uv = nC*barW + (nC-1)*gap
extra_gap = gap*2
for j, p in enumerate(params_uv):
base = j * (groupW_uv + extra_gap)
for k, (m, t) in enumerate(comboList):
x = base + k*(barW+gap)
vs, vl = data_bottom_row[(p, m, t)]
ax_uv.bar(x, vs, barW, color=color_map[m], hatch=hatch_map[t],
edgecolor='black', alpha=0.8, zorder=2)
if vl is not None:
ax_uv.bar(x, vl, barW, color=color_map[m], hatch=hatch_map[t],
edgecolor='black', alpha=0.4, zorder=3)
if (abs(vs) > 1e-3) or (vl is not None and abs(vl) > 1e-3):
txt = f"{vs:.2f}" + (f"~{vl:.2f}" if vl else "")
if y_offsets and p in y_offsets:
ax_uv.text(x+barW/10, y_offsets[p], txt,
ha='center', va='bottom', rotation=90, fontsize=font-6)
centers_uv = [j*(groupW_uv + extra_gap) + (nC*barW)/2 - gap for j in range(len(params_uv))]
ax_uv.set_xticks(centers_uv)
ax_uv.set_xticklabels(params_uv, fontsize=font)
# ---------- (d) Eg ----------
ax_eg.set_ylabel("Band gap (eV)",fontsize=font+2)
ax_eg.set_ylim(*eg_ylim)
ax_eg.grid(axis='y', linestyle='--', alpha=0.6)
base = len(params_uv)*(groupW_uv + extra_gap) - extra_gap # 마지막 그룹 다음 위치
for k, (m, t) in enumerate(comboList):
x = base + k*(barW+gap)
vs, _ = data_bottom_row[(r"$E_{g}$", m, t)]
ax_eg.bar(x, vs, barW, color=color_map[m], hatch=hatch_map[t],
edgecolor='black', alpha=0.8, zorder=2)
if eg_text_y is not None:
ax_eg.text(x+barW/10, eg_text_y, f"{vs:.2f}",
ha='center', va='bottom', rotation=90, fontsize=font-6)
exp_eg = 3.4 # Phys. Rev. B 2, 2679 (1970)
ax_eg.axhline(y=exp_eg, color='blue', linestyle='--', linewidth=3)
center_eg = base + (nC*barW)/2 - gap
ax_eg.set_xticks([center_eg])
ax_eg.set_xticklabels(["BaTiO$_{3}$"], fontsize=font)
# ==============================
# ==============================
fig = plt.figure(figsize=(12, 10))
outer = GridSpec(2, 4, figure=fig, width_ratios=[1,1,2,1], height_ratios=[1,1])
ax_a1 = fig.add_subplot(outer[0, 0]) # (a)
ax_alpha1 = fig.add_subplot(outer[0, 1]) # (b)
ax_uv1 = fig.add_subplot(outer[0, 2]) # (c)
ax_eg1 = fig.add_subplot(outer[0, 3]) # (d)
ax_a2 = fig.add_subplot(outer[1, 0]) # (e)
ax_alpha2 = fig.add_subplot(outer[1, 1]) # (f)
ax_uv2 = fig.add_subplot(outer[1, 2]) # (g)
ax_eg2 = fig.add_subplot(outer[1, 3]) # (h)
# without_O
draw_row(
ax_a1, ax_alpha1, ax_uv1, ax_eg1,
data_top_row=data_top,
data_bottom_row=data_bottom,
has_UO=False,
y_offsets=y_offset,
a_ylim=(3.99, 4.06),
alpha_ylim=(89.2, 90.4),
uv_ylim=(0, 8),
eg_ylim=(0, 6),
a_text_y=4.050,
alpha_text_y=90.05,
eg_text_y=4.40
)
ax_a1.text(-0.58, 1.023, '(a)', transform=ax_a1.transAxes, fontsize=font+6, ha='left', va='top')
ax_a1.set_yticks([3.99,4.01,4.03,4.05])
ax_alpha1.text(-0.60, 1.023, '(b)', transform=ax_alpha1.transAxes, fontsize=font+6, ha='left', va='top')
ax_alpha1.set_yticks([89.2,89.6,90.0,90.4])
ax_uv1.text(-0.30, 1.023, '(c)', transform=ax_uv1.transAxes, fontsize=font+6, ha='left', va='top')
ax_uv1.set_yticks([0,2,4,6,8])
ax_eg1.text(-0.52, 1.023, '(d)', transform=ax_eg1.transAxes, fontsize=font+6, ha='left', va='top')
ax_eg1.set_yticks([0,2,4,6])
ax_uv1.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.1f'))
ax_eg1.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.1f'))
# with_O
draw_row(
ax_a2, ax_alpha2, ax_uv2, ax_eg2,
data_top_row=data_top2,
data_bottom_row=data_bottom2,
has_UO=True,
y_offsets=y_offset,
a_ylim=(3.98, 4.05),
alpha_ylim=(89.2, 90.4),
uv_ylim=(0, 10),
eg_ylim=(0, 6),
a_text_y=4.035,
alpha_text_y=90.05,
eg_text_y=4.85
)
ax_a2.text(-0.58, 1.023, '(e)', transform=ax_a2.transAxes, fontsize=font+6, ha='left', va='top')
ax_a2.set_yticks([3.98,4.00,4.02,4.04])
ax_alpha2.text(-0.60, 1.023, '(f)', transform=ax_alpha2.transAxes, fontsize=font+6, ha='left', va='top')
ax_alpha2.set_yticks([89.2,89.6,90.0,90.4])
ax_uv2.text(-0.30, 1.023, '(g)', transform=ax_uv2.transAxes, fontsize=font+6, ha='left', va='top')
ax_eg2.text(-0.52, 1.023, '(h)', transform=ax_eg2.transAxes, fontsize=font+6, ha='left', va='top')
ax_eg2.set_yticks([0,2,4,6])
ax_uv2.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.1f'))
ax_eg2.yaxis.set_major_formatter(mtick.FormatStrFormatter('%.1f'))
legend_elems = [
Patch(facecolor='green', edgecolor='black', hatch='', label='LRT'),
Patch(facecolor='darkorange', edgecolor='black', hatch='', label='eACBN0'),
Patch(facecolor='white', edgecolor='black', hatch='', label='DFT+$U$'),
Patch(facecolor='white', edgecolor='black', hatch='//', label='DFT+$U$+$V$'),
]
fig.legend(handles=legend_elems, loc="upper center",
bbox_to_anchor=(0.5, 1.015),
ncol=4, fontsize=font)
plt.subplots_adjust(
left=0.05, right=0.98, top=0.95, bottom=0.05,
hspace=0.12, wspace=0.5
)
fig.align_ylabels([ax_uv1, ax_uv2])
plt.savefig('SI_BaTiO3.pdf', dpi=300, bbox_inches='tight')
plt.show()
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
import matplotlib.ticker as mtick
from matplotlib import rc, rcParams
from matplotlib.patches import Patch
plt.close("all")
# -----------------------------
# 0) Font & style
# -----------------------------
font = 16
rc("text", usetex=False)
rc("font", family="Arial")
rcParams["font.size"] = font
mpl.rcParams["axes.linewidth"] = 1.5
mpl.rcParams["figure.autolayout"] = False
mpl.rcParams["figure.constrained_layout.use"] = False
# -----------------------------
# 1) Common settings
# -----------------------------
materials = ["MnO", "FeO", "CoO", "NiO"]
comboOrder = [
("LRT", "DFT+U"),
("eACBN0", "DFT+U"),
("LRT", "DFT+U+V"),
("eACBN0", "DFT+U+V"),
]
color_map = {"LRT": "green", "eACBN0": "darkorange"}
hatch_map = {"DFT+U": "", "DFT+U+V": "//"}
# -----------------------------
# 2) Data: without O
# -----------------------------
params_wo_O = [r"$U_{TM}$", r"$V_{TM,O}$"]
data_wo_O = {
("MnO", r"$U_{TM}$"): {("LRT", "DFT+U"): 4.19, ("eACBN0", "DFT+U"): 4.96,
("LRT", "DFT+U+V"): 4.45, ("eACBN0", "DFT+U+V"): 5.10},
("MnO", r"$V_{TM,O}$"): {("LRT", "DFT+U"): 0.0, ("eACBN0", "DFT+U"): 0.0,
("LRT", "DFT+U+V"): 0.67, ("eACBN0", "DFT+U+V"): 2.93},
("FeO", r"$U_{TM}$"): {("LRT", "DFT+U"): 5.80, ("eACBN0", "DFT+U"): 6.05,
("LRT", "DFT+U+V"): 5.90, ("eACBN0", "DFT+U+V"): 6.01},
("FeO", r"$V_{TM,O}$"): {("LRT", "DFT+U"): 0.0, ("eACBN0", "DFT+U"): 0.0,
("LRT", "DFT+U+V"): 0.46, ("eACBN0", "DFT+U+V"): 2.86},
("CoO", r"$U_{TM}$"): {("LRT", "DFT+U"): 5.51, ("eACBN0", "DFT+U"): 6.51,
("LRT", "DFT+U+V"): 5.91, ("eACBN0", "DFT+U+V"): 6.34},
("CoO", r"$V_{TM,O}$"): {("LRT", "DFT+U"): 0.0, ("eACBN0", "DFT+U"): 0.0,
("LRT", "DFT+U+V"): 0.74, ("eACBN0", "DFT+U+V"): 3.13},
("NiO", r"$U_{TM}$"): {("LRT", "DFT+U"): 6.41, ("eACBN0", "DFT+U"): 8.18,
("LRT", "DFT+U+V"): 6.60, ("eACBN0", "DFT+U+V"): 7.67},
("NiO", r"$V_{TM,O}$"): {("LRT", "DFT+U"): 0.0, ("eACBN0", "DFT+U"): 0.0,
("LRT", "DFT+U+V"): 0.54, ("eACBN0", "DFT+U+V"): 3.02},
}
# -----------------------------
# 3) Data: with O
# -----------------------------
params_with_O = [r"$U_{TM}$", r"$U_{O}$", r"$V_{TM,O}$"]
data_with_O = {
("MnO", r"$U_{TM}$"): {("LRT", "DFT+U"): 3.97, ("eACBN0", "DFT+U"): 4.97,
("LRT", "DFT+U+V"): 4.06, ("eACBN0", "DFT+U+V"): 5.40},
("MnO", r"$U_{O}$"): {("LRT", "DFT+U"): 12.44, ("eACBN0", "DFT+U"): 3.37,
("LRT", "DFT+U+V"): 12.44, ("eACBN0", "DFT+U+V"): 3.51},
("MnO", r"$V_{TM,O}$"): {("LRT", "DFT+U"): 0.0, ("eACBN0", "DFT+U"): 0.0,
("LRT", "DFT+U+V"): 0.65, ("eACBN0", "DFT+U+V"): 2.94},
("FeO", r"$U_{TM}$"): {("LRT", "DFT+U"): 6.02, ("eACBN0", "DFT+U"): 5.98,
("LRT", "DFT+U+V"): 6.05, ("eACBN0", "DFT+U+V"): 6.06},
("FeO", r"$U_{O}$"): {("LRT", "DFT+U"): 10.35, ("eACBN0", "DFT+U"): 2.86,
("LRT", "DFT+U+V"): 10.31, ("eACBN0", "DFT+U+V"): 2.70},
("FeO", r"$V_{TM,O}$"): {("LRT", "DFT+U"): 0.0, ("eACBN0", "DFT+U"): 0.0,
("LRT", "DFT+U+V"): 0.40, ("eACBN0", "DFT+U+V"): 2.87},
("CoO", r"$U_{TM}$"): {("LRT", "DFT+U"): 5.60, ("eACBN0", "DFT+U"): 6.10,
("LRT", "DFT+U+V"): 5.70, ("eACBN0", "DFT+U+V"): 6.31},
("CoO", r"$U_{O}$"): {("LRT", "DFT+U"): 11.42, ("eACBN0", "DFT+U"): 2.57,
("LRT", "DFT+U+V"): 11.14, ("eACBN0", "DFT+U+V"): 2.45},
("CoO", r"$V_{TM,O}$"): {("LRT", "DFT+U"): 0.0, ("eACBN0", "DFT+U"): 0.0,
("LRT", "DFT+U+V"): 0.69, ("eACBN0", "DFT+U+V"): 3.13},
("NiO", r"$U_{TM}$"): {("LRT", "DFT+U"): 6.32, ("eACBN0", "DFT+U"): 7.72,
("LRT", "DFT+U+V"): 6.41, ("eACBN0", "DFT+U+V"): 7.62},
("NiO", r"$U_{O}$"): {("LRT", "DFT+U"): 10.24, ("eACBN0", "DFT+U"): 2.43,
("LRT", "DFT+U+V"): 10.20, ("eACBN0", "DFT+U+V"): 2.04},
("NiO", r"$V_{TM,O}$"): {("LRT", "DFT+U"): 0.0, ("eACBN0", "DFT+U"): 0.0,
("LRT", "DFT+U+V"): 0.47, ("eACBN0", "DFT+U+V"): 3.03},
}
# -----------------------------
# 4) Plot helper
# -----------------------------
def plot_hubbard_panel(ax, params, data, ylim, panel_label, show_material_labels, y_offsets):
ax.set_ylabel("Hubbard parameter (eV)", fontsize=font)
ax.grid(axis="y", linestyle="--", alpha=0.6)
ax.set_xticks([])
ax.set_ylim(*ylim)
ax.text(-0.12, 1.08, panel_label, transform=ax.transAxes,
fontsize=font + 4, ha="left", va="top")
barW = 0.12
gapM = 0.6
extra = 0.2
gapB = 0.06
nC = len(comboOrder)
sW = nC * (barW + gapB) - gapB + extra
gW = len(params) * sW + gapM
for i, mat in enumerate(materials):
start = i * gW
center = start + (len(params) * sW - extra) / 2 - 0.05
if show_material_labels:
ax.text(center, -0.14, mat, transform=ax.get_xaxis_transform(),
ha="center", va="top", fontsize=font)
for j, p in enumerate(params):
sg = start + j * sW
sgc = sg + (nC * (barW + gapB) - gapB) / 2 - 0.05
ax.text(sgc, -0.03, p, transform=ax.get_xaxis_transform(),
ha="center", va="top", fontsize=font)
for k, combo in enumerate(comboOrder):
x = sg + k * (barW + gapB)
v = data[(mat, p)][combo]
ax.bar(
x, v, barW,
color=color_map[combo[0]],
hatch=hatch_map[combo[1]],
edgecolor="black",
alpha=0.8,
zorder=2,
)
if v > 0:
offset = y_offsets[p][mat]
dx_list = [-0.015, 0.0075, 0.0325, 0.06]
dx = dx_list[k % len(dx_list)]
ax.text(
x + dx, offset, f"{v:.2f}",
ha="center", va="bottom",
fontsize=font - 6, rotation=90, zorder=3
)
ax.yaxis.set_major_formatter(mtick.FormatStrFormatter("%.1f"))
# -----------------------------
# 5) Build figure
# -----------------------------
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10, 7))
y_offsets_wo_O = {
r"$U_{TM}$": {"MnO": 5.5, "FeO": 6.5, "CoO": 7.0, "NiO": 8.5},
r"$V_{TM,O}$": {"MnO": 3.2, "FeO": 3.2, "CoO": 3.5, "NiO": 3.5},
}
y_offsets_with_O = {
r"$U_{TM}$": {"MnO": 13.0, "FeO": 11.0, "CoO": 12.0, "NiO": 10.8},
r"$U_{O}$": {"MnO": 13.0, "FeO": 11.0, "CoO": 12.0, "NiO": 10.8},
r"$V_{TM,O}$": {"MnO": 3.5, "FeO": 3.5, "CoO": 3.7, "NiO": 3.7},
}
plot_hubbard_panel(
ax1,
params_wo_O,
data_wo_O,
ylim=(0, 10.5),
panel_label="(a)",
show_material_labels=False,
y_offsets=y_offsets_wo_O,
)
plot_hubbard_panel(
ax2,
params_with_O,
data_with_O,
ylim=(0, 15.5),
panel_label="(b)",
show_material_labels=True,
y_offsets=y_offsets_with_O
)
legend_elems = [
Patch(facecolor="green", edgecolor="black", hatch="", label="LRT"),
Patch(facecolor="darkorange", edgecolor="black", hatch="", label="eACBN0"),
Patch(facecolor="white", edgecolor="black", hatch="", label="DFT+$U$"),
Patch(facecolor="white", edgecolor="black", hatch="//", label="DFT+$U$+$V$"),
]
fig.legend(
handles=legend_elems,
loc="upper center",
bbox_to_anchor=(0.5, 0.98),
ncol=4,
fontsize=font,
)
fig.align_ylabels([ax1, ax2])
plt.subplots_adjust(hspace=0.18, top=0.90, bottom=0.08)
plt.savefig("SI_TMO_Hubbard_ps.pdf", bbox_inches="tight")
plt.show()