How to Add/Customize a Border (Outline) to Bar ChartsHello JMP Community,
I would like to add an outline/border around each bar in a bar chart and customize its width. How can I achieve this in JMP?
As shown in the image below , I would like to add a border or outline around each bar.

I've heard of a workaround that involves overlaying two bar charts to simulate an outline. However, this method doesn't seem to allow for customization of the outline's width.
Is there a way, either through the Graph Builder interface or by editing a script, to apply an outline to each bar and independently change its color and width?
I am currently using JMP Student Edition 19.
Thank you in advance for your help!
Basic Data Analysis and ModelingData Exploration and VisualizationRe: How to Add/Customize a Border (Outline) to Bar ChartsI think using second bar chart should be ok solution, but it will require some work as you would have to create extra column to get heights correct and then modify width proportion. This has been done with that method

Here is exmple script you can run and then explore how the graph has been built (order of barcharts has been changed, width proportion is modified, color is changed and so on...)
View more...
Names Default To Here(1);
dt = Open("$SAMPLE_DATA/Big Class.jmp");
dt << New Column("Mean[height][age]",
Numeric,
"Continuous",
Formula(Col Mean(:height, :age) + 1)
);
gb = dt << Graph Builder(
Size(656, 549),
Show Control Panel(0),
Variables(
X(:age),
Y(:height),
Y(:"Mean[height][age]"n, Position(1)),
Overlay(:age)
),
Elements(
Bar(X, Y(1), Legend(6), Bar Style("Stacked")),
Bar(X, Y(2), Legend(7), Bar Style("Stacked"))
),
SendToReport(
Dispatch({}, "400", ScaleBox,
{Legend Model(
7,
Base(0, 0, 0, Item ID("12", 1)),
Base(1, 0, 1, Item ID("13", 1)),
Base(2, 0, 2, Item ID("14", 1)),
Base(3, 0, 3, Item ID("15", 1)),
Base(4, 0, 4, Item ID("16", 1)),
Base(5, 0, 5, Item ID("17", 1)),
Type Properties(0, "Bar", {Fill Color(0)}),
Properties(0, {Fill Color(0)}, Item ID("12", 1)),
Properties(1, {Fill Color(0)}, Item ID("13", 1)),
Properties(2, {Fill Color(0)}, Item ID("14", 1)),
Properties(3, {Fill Color(0)}, Item ID("15", 1)),
Properties(4, {Fill Color(0)}, Item ID("16", 1)),
Properties(5, {Fill Color(0)}, Item ID("17", 1))
)}
),
Dispatch({}, "Graph Builder", FrameBox,
{Reorder Segs({1, 2, 4}), DispatchSeg(
BarSeg(1),
{Set Width Proportion(0.7)}
)}
),
Dispatch({}, "400", LegendBox,
{Legend Position({6, [0, 1, 2, 3, 4, 5], 7, [-1, -1, -1, -1, -1, -1]})}
)
)
);
Re: How to Add/Customize a Border (Outline) to Bar Charts@jthi has a good solution. I have a tendency to use the JMP graphic primitives that allow you to directly draw lines and rectangles with the ability to color and define thicknesses.
See Add Graphic Script in the Scripting Index and Scripting Guide for documentation and examples of how to do this.
Re: How to Add/Customize a Border (Outline) to Bar ChartsOther (good) options would be:
- Using Graphic Script. You have to know how many bars you have, and I think you cannot get that information from BarSeg object. So, it is easier to do with supporting marker added to graph (it can be hidden from final plot)
- Use Marker Draw Expression. Does require adding marker, it is more difficult to implement, but is most likely more robust option
I don't have time to write-out these options now, but they do exist
Re: How to Add/Customize a Border (Outline) to Bar ChartsHad time to create the graphic script
Names Default To Here(1);
dt = Open("$SAMPLE_DATA/Big Class.jmp");
gb = dt << Graph Builder(
Size(656, 549),
Show Control Panel(0),
Variables(X(:age), Y(:height)),
Elements(
Bar(X, Y, Legend(4)),
Points(X, Y, Legend(5), Summary Statistic("Mean"))
),
SendToReport(
Dispatch({}, "400", ScaleBox,
{Legend Model(
5,
Type Properties(0, "Marker", {Transparency(0)}),
Properties(0, {Transparency(0)}, Item ID("Mean", 1))
)}
)
)
);
fb = Report(gb)[FrameBox(1)];
fb << Add Graphics Script(Function({this}, // can be laggy as it is a graphic script with a loop
ms = this << Find Seg(MarkerSeg(1));
xs = ms << Get X Values;
ys = ms << Get Y Values;
sideshift = 0.27;
For(i = 1, i <= N Items(xs), i++,
Pen Size(10); // Width of the line
Pen Color("Black");
Rect(xs[i] - sideshift, ys[i], xs[i] + sideshift, -1, 0);
);
));

And here is Marker Draw Expr
Names Default To Here(1);
dt = Open("$SAMPLE_DATA/Big Class.jmp");
gb = dt << Graph Builder(
Size(656, 549),
Show Control Panel(0),
Variables(X(:age), Y(:height)),
Elements(
Bar(X, Y, Legend(4)),
Points(X, Y, Legend(5), Summary Statistic("Mean"))
),
SendToReport(
Dispatch({}, "400", ScaleBox,
{Legend Model(
5,
Type Properties(0, "Marker", {Transparency(0)}),
Properties(0, Item ID("Mean", 1))
)}
)
)
);
fb = Report(gb)[FrameBox(1)];
seg = (fb << FindSeg(Marker Seg(1)));
seg << Set Marker Draw Expr(
Function({this seg, this row, x, y, size, row state},
Pen Size(10); // Width of the line
Pen Color("Black");
Rect(x - 0.27, y, x + 0.27, -1, 0);
)
);

Re: How to Add/Customize a Border (Outline) to Bar Charts@jthi ,
The Marker Draw Expr example does not work correctly in my install of JMP 19. The Transparency default appears to be set to 0 for the marker. The below simple change allows for the rectangle to be displayed properly.
Names Default To Here(1);
dt = Open("$SAMPLE_DATA/Big Class.jmp");
gb = dt << Graph Builder(
Size(656, 549),
Show Control Panel(0),
Variables(X(:age), Y(:height)),
Elements(
Bar(X, Y, Legend(4)),
Points(X, Y, Legend(5), Summary Statistic("Mean"))
),
SendToReport(
Dispatch({}, "400", ScaleBox,
{Legend Model(
5,
Type Properties(0, "Marker", {Transparency(0)}),
Properties(0, Item ID("Mean", 1))
)}
)
)
);
fb = Report(gb)[FrameBox(1)];
seg = (fb << FindSeg(Marker Seg(1)));
seg << Set Marker Draw Expr(
Function({this seg, this row, x, y, size, row state},
show(x,y);
Pen Size(10); // Width of the line
Pen Color("Black");
transparency(1); // Needed for JMP 19
Rect(x - 0.27, y, x + 0.27, -1, 0);
)
);Re: How to Add/Customize a Border (Outline) to Bar ChartsIf a thin line is OK for you as border, it's super easy: just add a second bar graph with pattern = "none" and adjust the color to e.g. black.

Names Default to Here(1);
dt = Open( "$SAMPLE_DATA/Big Class.jmp" );
Graph Builder(
Size( 469, 365 ),
Summary Statistic( "Median" ),
Variables( X( :age ), Y( :height ), Overlay( :sex ), Color( :sex ) ),
Elements(
Bar( X, Y, Bar Style( "Stacked" ) ),
Bar( X, Y, Legend( 2 ), Bar Style( "Stacked" ) )
),
SendToReport(
Dispatch( {}, "400", ScaleBox,
{Legend Model(
2,
Properties(
0,
{Fill Color( 0 ), Fill Pattern( "none" )},
Item ID( "F", 1 )
),
Properties(
1,
{Fill Color( 0 ), Fill Pattern( "none" )},
Item ID( "M", 1 )
)
)}
)
)
);
Re: How to Add/Customize a Border (Outline) to Bar Charts@txnelson
Thank you so much for your detailed responses. It was very helpful. But there is one more thing I'd like to do.
When I use Set Marker Draw Expr to draw a bar border, it is drawn on the top layer.
Consequently, when I add error bars or individual data points (via a dot plot), the custom border is drawn over them.
Is there a way to control the drawing order (layer) of the border so that it appears behind the data points?
For highly customized graphing, do people typically use scripting languages like R, or dedicated software such as GraphPad Prism?
Re: How to Add/Customize a Border (Outline) to Bar Chartsyou can adjust the oder of the individual element:
right click into the graph and change the order:

If there is just one plot type, just add 20 and customize them.
Graph Builder is orders of magnitude more flexible / powerful than people might think at first glance. This is the trick:
a smooth transition from very easy drag and drop to highly customized graphs.
With Set Marker Draw Expr you already got in tough with one very elaborate feature - but there are many more features.
No need to use another plotting tool.
Re: How to Add/Customize a Border (Outline) to Bar ChartsDraw your chart with the new borders and the error bars. Then right click on the graph and select Custom. It will bring up a dialog box where you can select the error bars and move them to the front. Close the dialog box and then go to the red triangle and select save script. You can then examine the script it produced and you will see what is necessary to move the error bars to the front using jsl.