cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Discussions

Solve problems, and share tips and tricks with other JMP users.
Choose Language Hide Translation Bar
Yo_ITO
Level I

How to Add/Customize a Border (Outline) to Bar Charts

Hello 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.

example.png

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!

9 REPLIES 9
jthi
Super User

Re: How to Add/Customize a Border (Outline) to Bar Charts

I 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

jthi_0-1763186233232.png

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]})}
		)
	)
);
-Jarmo
txnelson
Super User

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.

Jim
jthi
Super User

Re: How to Add/Customize a Border (Outline) to Bar Charts

Other (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

-Jarmo
jthi
Super User

Re: How to Add/Customize a Border (Outline) to Bar Charts

Had 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);
	);
));

jthi_0-1763187474845.png

 

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);
	)
);

jthi_1-1763187791955.png

 

-Jarmo
txnelson
Super User

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);
	)
);
Jim
hogi
Level XIII

Re: How to Add/Customize a Border (Outline) to Bar Charts

If 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.

hogi_0-1763218979649.png

 


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 )
				)
			)}
		)
	)
);
   

 

Yo_ITO
Level I

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?

hogi
Level XIII

Re: How to Add/Customize a Border (Outline) to Bar Charts

you can adjust the oder of the individual element: 
right click into the graph and change the order:

hogi_0-1763305559416.png

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.

txnelson
Super User

Re: How to Add/Customize a Border (Outline) to Bar Charts

Draw 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.

Jim

Recommended Articles