> 
CustomColumnGraph := proc(
data
, BarColors
, GroupTitles
, BarWidth
, GroupOffset
, LegendBarHeight
, VerticalShiftFactor
, BarFont
, GroupFont
, LegendFont
, BarTitleFormat
)
local Ni, Nj, W, DX, LH, LW, SF, L, DL:
local SingleBar := (w, h, c) > rectangle([0, 0], [w, h], color=c):
local BarGraph, Legends:
uses plots, plottools:
Ni := numelems(data[..,1]):
Nj := numelems(data[1]):
W := BarWidth:
DX := GroupOffset:
LH := LegendBarHeight:
SF := VerticalShiftFactor;
L := DX*(Ni1) + W*(Nj1) + DX/2 + DX/4:
LW := L / Ni / Nj / 2; # LegendBarWidth
DL := solve(dl*(Nj+1) + Nj*(3*LW) = L, dl);
BarGraph := display(
seq(
seq(
translate(SingleBar(W, data[i, j], BarColors[j]), DX/4 + DX*(i1) + W*(j1), 0)
, i=1..Ni
)
, j=1..Nj
)
, axis[1] = [gridlines = [], tickmarks = []]
, axis[2] = [gridlines = [11, linestyle = dot, thickness = 0, color = "LimeGreen"]]
):
Legends := display(
seq(
translate(SingleBar(LW, LH, BarColors[j]), DL/2 + LW + (3*LW+DL)*(j1), min(data)*(2*SF1))
, j=1..Nj
)
,
seq(
translate(
textplot([0, LH/2, GroupTitles[j]], align=right, font = LegendFont)
, DL/2 + 2*LW + (3*LW+DL)*(j1), min(data)*1.4)
, j=1..Nj
)
):
display(
BarGraph
, Legends
# X base line
, plot(0, x=0..DX*(Ni1)+W*(Nj1)+DX/2 + DX/4)
# Left bar group boundaries
,
seq(
line(
[DX/4 + DX*(i1)  W/2, min(data)*SF],
[DX/4 + DX*(i1)  W/2, max(data)*SF]
, color="LightGray"
)
, i=1..Ni
)
# Right bar group boundaries
,
seq(
line(
[DX/4 + DX*(i1) + W*Nj + W/2, min(data)*SF],
[DX/4 + DX*(i1) + W*Nj + W/2, max(data)*SF]
, color="LightGray"
)
, i=1..Ni
)
# Top bar group boundaries
,
seq(
line(
[DX/4 + DX*(i1)  W/2, max(data)*SF],
[DX/4 + DX*(i1) + W*Nj + W/2, max(data)*SF]
, color="LightGray"
)
, i=1..Ni
)
# Bar titles
,
seq(
seq(
textplot(
# [DX/4 + DX*(i1) + W*(j1) +W/2, data[i, j], evalf[3](data[i, j])]
[DX/4 + DX*(i1) + W*(j1) +W/2, data[i, j], sprintf(BarTitleFormat, data[i, j])]
, font=BarFont
, align=`if`(data[i, j] > 0, above, below)
)
, i=1..Ni
)
, j=1..Nj
)
# Bar group titles
,
seq(
textplot(
[DX/4 + DX*(i1) + W*(Nj/2), max(data)*SF, cat("B", i)]
, font=GroupFont
, align=above
)
, i=1..Ni
)
, labels=["", ""]
, size=[800, 400]
, view=[0..DX*(Ni1) + W*(Nj1) + DX/2 + DX/4, default]
);
end proc:

Data from AHSAN
> 
A := [0.1, 0.5, 0.9]:
B := [0.5, 2.5, 4.5]:
Nu_A := [0.013697, 0.002005, 0.017707, 0.013697, 0.002005, 0.017707, 0.013697, 0.002005, 0.017707]:
Nu_B := [0.010827, 0.011741, 0.012655, 0.013967, 0.014881, 0.015795, 0.017107, 0.018021, 0.018935]:
i:=4:
data := Matrix([[Nu_A[i], Nu_B[i]], [Nu_A[i + 1], Nu_B[i + 1]], [Nu_A[i + 2], Nu_B[i + 2]]]):

Column Graph
> 
Ni, Nj := LinearAlgebra:Dimensions(data):
CustomColumnGraph(
data # data
, ["Salmon", "LightGreen"] # BarColors
, ["Sensitivity to A", "Sensitivity to B"] # GroupTitles
, 1/(numelems(data[1])+2) # BarWidth
, 1 # GroupOffset
, max(abs~(data))/10 # LegendBarHeight
, 1.2 # VerticalShiftFactor
, [Tahoma, bold, 10] # BarFont
, [Tahoma, bold, 14] # GroupFont
, [Tahoma, bold, 12] # LegendFont
, "%1.5f" # BarTitleFormat
)

Column Graph of an extended set of data
> 
ExtentedData := < data  Statistics:Mean(data^+)^+ >:
ExtentedData := < ExtentedData, Statistics:Mean(ExtentedData) >:
interface(displayprecision=6):
data, ExtentedData;
Ni, Nj := LinearAlgebra:Dimensions(ExtentedData):
CustomColumnGraph(
ExtentedData
, ["Salmon", "LightGreen", "Moccasin"]
, ["Sensitivity to A", "Sensitivity to B", "Mean Sensitivity to A and B"]
, 1/(numelems(data[1])+2) # BarWidth
, 1 # GroupOffset
, max(abs~(data))/10 # LegendBarHeight
, 1.2 # VerticalShiftFactor
, [Tahoma, 10] # BarFont
, [Tahoma, bold, 14] # GroupFont
, [Tahoma, 12] # LegendFont
, "%1.3f" # BarTitleFormat
)

