cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Choose Language Hide Translation Bar
jcummings
Level I

how to create dynamic background regimes in graph builder

Hello,

 

I am trying to create background regions for a graph where the regions represent areas of certain slope, as shown below:

 

jcummings_0-1655230905554.png

where the colored regions are based on the value X/Y (ffc in graph), ranging from <1 to >10. Because the ranges of X and Y vary with observations, I have the regions or contours mapped using the polygon function and pulling the resultant axes min and max as inputs like so:

 

Polygon( {0, 0}, {XMin, YMax}, {XMax, YMax}, {XMax, XMax * 10} )

 

which works well enough. My problem is specifying the text locations which label each region, I have yet to find a way such that the text moves dynamically based on the data similar to the polygons such that i do not have to go in after the fact and specify the exact coordinates. If anyone could provide ideas/recommendations on achieving some sort of dynamic text within the graph it would be much appreciated. I am sure there is a better way to do this rather than using the polygon and text functions, but I cannot seem to figure it out, or if there is a good way to do this at all. I also realize this is purely for aesthetics, but i have spent too much time trying to find a solution so I am determined to find something that works. 

 

Thank you to anyone who provides a response.

 

1 ACCEPTED SOLUTION

Accepted Solutions
XanGregg
Staff

Re: how to create dynamic background regimes in graph builder

I assume you found the Text() function to draw the region labels but are just having trouble with the math for placing them. Below is some code that works reasonably well. It may need adjustment if the first or last labels get clipped by the xmin/ymin edges since this code doesn't test for those. I computed the text location as being on the middle angle of the region, but you might want to hard-code those instead. That is, have a list of text angles that goes along with the list of stop angles for each zone.

XanGregg_0-1655310847616.png

xmin = 400;
xmax = 1800;
ymin = 0;
ymax = 3600;
New Window( "fills",
	gb = Graph Box(
		Frame Size( 500, 500 ),
		X Scale( xmin, xmax ),
		Y Scale( ymin, ymax ),
		Marker(
			Marker State( 8 ),
			J( 20, 1, Random Normal( 1000, 50 ) ),
			J( 20, 1, Random Normal( 1000, 300 ) )
		)
	)
);
framebox = gb[frame box( 1 )];
framebox << Add Graphics Script(
	max diagonal = Max( xmax, ymax ) * Sqrt( 2 );
	Fill Color( "red" );
	stops = {0, 1, 2, 4, 10};
	For( i = 2, i <= N Items( stops ), i++,
		// fill wedge
		Transparency( 0.07 * i );
		a1 = ATan( stops[i] );
		a0 = ATan( stops[i - 1] );
		Polygon( {0, 0},
			{Cos( a1 ) * max diagonal, Sin( a1 ) * max diagonal},
			{Cos( a0 ) * max diagonal, Sin( a0 ) * max diagonal} );
		// text label in center of wedge, constrained to graph bounds
		text angle = Mean( a0, a1 );
		xt = Cos( text angle ) * max diagonal;
		yt = Sin( text angle ) * max diagonal;
		scale to fit = Min( xmax / xt, ymax / yt ) * 0.9;
		Transparency( 0.9 );
		Text(
			Center justified,
			{xt * scale to fit, yt * scale to fit},
			Char( stops[i - 1] ) || " < r < " || Char( stops[i] )
		);
	);
);

View solution in original post

1 REPLY 1
XanGregg
Staff

Re: how to create dynamic background regimes in graph builder

I assume you found the Text() function to draw the region labels but are just having trouble with the math for placing them. Below is some code that works reasonably well. It may need adjustment if the first or last labels get clipped by the xmin/ymin edges since this code doesn't test for those. I computed the text location as being on the middle angle of the region, but you might want to hard-code those instead. That is, have a list of text angles that goes along with the list of stop angles for each zone.

XanGregg_0-1655310847616.png

xmin = 400;
xmax = 1800;
ymin = 0;
ymax = 3600;
New Window( "fills",
	gb = Graph Box(
		Frame Size( 500, 500 ),
		X Scale( xmin, xmax ),
		Y Scale( ymin, ymax ),
		Marker(
			Marker State( 8 ),
			J( 20, 1, Random Normal( 1000, 50 ) ),
			J( 20, 1, Random Normal( 1000, 300 ) )
		)
	)
);
framebox = gb[frame box( 1 )];
framebox << Add Graphics Script(
	max diagonal = Max( xmax, ymax ) * Sqrt( 2 );
	Fill Color( "red" );
	stops = {0, 1, 2, 4, 10};
	For( i = 2, i <= N Items( stops ), i++,
		// fill wedge
		Transparency( 0.07 * i );
		a1 = ATan( stops[i] );
		a0 = ATan( stops[i - 1] );
		Polygon( {0, 0},
			{Cos( a1 ) * max diagonal, Sin( a1 ) * max diagonal},
			{Cos( a0 ) * max diagonal, Sin( a0 ) * max diagonal} );
		// text label in center of wedge, constrained to graph bounds
		text angle = Mean( a0, a1 );
		xt = Cos( text angle ) * max diagonal;
		yt = Sin( text angle ) * max diagonal;
		scale to fit = Min( xmax / xt, ymax / yt ) * 0.9;
		Transparency( 0.9 );
		Text(
			Center justified,
			{xt * scale to fit, yt * scale to fit},
			Char( stops[i - 1] ) || " < r < " || Char( stops[i] )
		);
	);
);