
스케일링된 응답 오버레이 그래프가 있는 다중 Y축
멈추다! 스크립트만 원하시면 포스트 하단에 첨부합니다.
이것은 모든 y축 변수를 스케일링하고 중첩한 다음 변수의 단위 및 범위에서 y축 스케일을 제공하는 특수 그래프입니다. 이것은 모두 다른 범위에 있는 3개 또는 4개의 변수를 오버레이하려는 경우에 유용합니다. 위의 그림에서 유속은 0-40 범위에 있고 전력은 200-1000 및 100-500 범위에 있습니다. 이 유형의 그래프는 여러 센서가 동시에 데이터를 기록하지만 각 센서의 범위가 상당히 다른 과학 및 엔지니어링 응용 프로그램에서 자주 사용됩니다. 예를 들어, 발효 예에서 포도당은 1-5g/dl, pH는 6.8-7.8, 젖산은 10-50mmol이며 세포 수 또는 탁도는 훨씬 더 큽니다. 시간 경과에 따른 모든 변수 간의 관계를 그래프로 표시하는 간단한 방법은 프로세스의 역학(또는 비정상적인 패턴 감지)을 이해하는 데 매우 유용합니다.
이 특정 그래프는 꽤 오랫동안 나의 천적이었습니다. 합리적으로 좋아 보이는 것을 얻으려면 일반적으로 JMP 또는 PowerPoint 내에서 창의적인 복사 및 붙여넣기가 필요합니다. 그렇다면 이 그래프는 왜 그렇게 어려운 것일까요? 어떻게든 데이터를 스케일링하고 하나의 그래프로 결합한 다음 스케일링되지 않은 모든 y축 구성요소를 스케일링된 데이터 그래프와 결합해야 합니다. 내가 보고 시도한 모든 방법에는 너무 많은 복사 및 붙여넣기 단계가 포함되며 Powerpoint에서 그래프 요소를 그룹 해제하고 다시 형식을 지정하는 방법은 모든 요소를 올바르게 정렬하려는 지루함 때문에 때때로 좋지 않은 결과를 생성할 수 있습니다. 내 슬라이드에. 지저분하고 수동적이며 지루하고 반복적인 프로세스는 JSL 자동화를 요구합니다.
솔루션 스크립팅 전략에 대해 생각할 때 고려해야 할 몇 가지 단계가 있습니다.
1. 각 변수/열에 대해 y축 상자를 만듭니다.
2. 각 열의 값을 동일한 범위로 조정
3. 오버레이 플롯에서 작동하도록 데이터의 형태를 변경합니다.
4. y 역할과 x 역할에 대한 열을 선택하기 위한 시작 대화 상자가 있으면(또는 그냥 행 번호를 사용하여) 또한 좋을 것입니다.
5. 그리고 마지막으로, 그래프는 원래 척도의 각 변수와 함께 축 상자를 포함해야 합니다.
나는 JSL 연필을 날카롭게 깎고 이 그림을 자동으로 만들려고 노력했습니다. 나는 여기서 내가 한 일을 설명하려고 노력할 것이고, 그것을 더 기능적으로 만드는 방법에 대한 추가 토론에 감사드립니다. 현재 상태는 한 가지 유형의 고정된 숫자를 생성할 수 있는 스크립트이며 뒤에 남겨진 중간 테이블을 정리하는 데 신경쓰지 않습니다. (글에 전체 스크립트를 첨부하겠습니다)
첫 번째 단계: 시작 대화 상자
cd = Column Dialog(
ylist = ColList( "Y", Min Col( 2 ), Max Col( 8 ), Data Type( "Numeric" ), Modeling Type( {"Continuous"} ) ),
xlist = ColList( "X", Max Col( 1 ), Modeling Type( {"Continuous", "Multiple Response"} ) )
);
Eval( Eval Expr( cd[1] ) ); //eval expr, returns what is in cd[1], and the eval makes it execute
Eval( Eval Expr( cd[2] ) ); //separately run just cd[1], then run evalexpr)cd[1], this is how I get the ylist and xlist variables
시작 대화 상자를 작성하기 시작할 때마다 스크립팅 인덱스에서 뻔뻔하게 복사하여 필요하지 않은 것을 삭제하거나 필요에 따라 추가합니다. 목표는 Y와 X를 잡는 것입니다. 여기에는 열이 숫자 연속이어야 하고 최소한 2개의 Y가 있어야 하는 것과 같은 몇 가지 규칙이 있습니다. ?) Y 응답도 8개로 제한됩니다. 자유롭게 편집하세요. 8개 이상은 너무 지저분해 보입니다.
eval(eval expr())이 있는 마지막 두 줄은 열 대화 상자에서 "cd"로 반환된 항목에서 ylist 및 xlist 변수를 생성하는 방법입니다.
데이터 테이블 1: 표준화된 데이터 테이블
dt1 = New Table( "multiple y-axis table" ); //this is the table where the standardized values go
If( N Items( xlist ) == 1, //note that if there is a column selected for xlist, then it doesn't get scaled
Insert Into( ylist, xlist, 1 ), //call me crazy, but the first value in ylist is the "X", if it exists
dt1 << New Column( "Row", formula( Row() ) )
);
DT1은 표준화된 후 데이터를 포함할 테이블입니다. 대화 상자에서 X를 선택하지 않은 경우 첫 번째 열은 "행"이고 그래프에서 x축으로 사용할 행 번호가 있습니다. X가 있으면 ylist의 첫 번째 위치에 추가됩니다. 네 맞습니다. 변수 ylist에는 X와 Y가 모두 있습니다.
dt1 채우기 및 "축 상자" 만들기
For(
<FONT color="#FF6600"> If( N Items( xlist ) == 1, //yep, that's an "if" argument inside a "for" loop
i = 2; //if an "x" is specified, then start with the second thing in the list
ycol = As Column( dt, ylist[1] ) << get values;
dt1 << New Column( Munger( ylist[1], 1, ":", "" ), set values( ycol ) );//this is soooo ugly
,i = 1), i <= N Items( ylist ), i++, //end of setup for the For loop</FONT>
<FONT color="#008000"> ycol = As Column( dt, ylist[i] ) << get values;
yycol = ((ycol - Min( ycol )) / (Max( ycol ) - Min( ycol )));
dt1 << New Column( Munger( ylist[i], 1, ":", "" ), set values( yycol ) ); //this is soooo ugly, very sorry</FONT>
<FONT color="#0000FF"> amin = Min( ycol ); //this second part of this script is getting values to make the y-axis boxes
amax = Max( ycol ); //I need the min and max values from each of the unscaled columns, along with their names
ymin = amin - ((amax - amin) * .1); //The y-axis box axis range is 10% higher and lower than the min and max.
ymax = amax + ((amax - amin) * .1); //It looks better and is more closely aligned with the scaled data in gb
obj1 = Graph Box( Framesize( 0, 230 ), yName( Char( ylist[i] ) ), Y Scale( ymin, ymax ) ); </FONT><BR /><FONT color="#0000FF"> //its not a true axis box, just a squished graph box. the axis box was free
Insert Into( objhlb1, Name Expr( obj1 ) ); </FONT><BR /><FONT color="#0000FF"> //there is a lot of inserting of name expr() here. its part of building expressions from the inside out.</FONT>
);
이 다음 부분은 Y에 대해 선택된 열 목록을 반복합니다. X가 지정된 경우 목록의 두 번째 항목부터 시작합니다.
첫 번째 부분은 루프를 설정하고 결과에 대한 테이블을 만드는 데 일부 논리를 사용하므로 계속 진행합니다. 테이블 변형은 x축 변수가 지정되었는지 여부에 따라 다릅니다.
스크립트의 중간 부분은 비록 짧지만 정말 중요합니다. 원본 테이블(dt)의 각 열에서 값을 가져와서 스케일링된 값을 dt1에 넣습니다. 저는 이 라인이 자랑스럽지 않습니다: dt1 << 새 열 ( 멍거 ( 일리스트[i], 1 , ":" , "" ), 값 설정( yycol ) ); 그러나 여기에 문제가 있습니다. New 열은 "colname" 또는 colname을 원하고 :colname은 이 단계를 종료하므로 방금 콜론을 제거했습니다. (댓글에 더 나은 방법을 보내주세요.)
마지막 부분에서는 각 열 값 집합을 살펴보고 그래프 상자의 크기를 조정하는 데 사용했습니다. 그래프 상자는 멋진 축 상자를 만들고 그래프 상자의 너비를 0으로 설정하면 y축 상자만 나타납니다. 이 단계는 그래프의 형식을 지정하는 데 중요합니다. 마지막 줄은 그래프 상자에 대한 표현식을 끝에 평가되는 표시 상자에 삽입합니다. obj1(그래프 상자)을 참조하기 위해 이름 expr을 사용하여 스크립트를 만들고 스크립트의 모든 변수가 평가되지만 스크립트는 평가되지 않습니다. 각 그래프 상자는 가로 목록 상자(objhlb1)에 삽입됩니다. 나중에 이 상자는 다른 상자에 삽입됩니다.
그래프를 만들기 위한 테이블 작성:
For(
If( N Items( xlist ) == 1,
i = 2,
i = 1
), i <= N Items( ylist ), i++,
Insert Into( dt2stackcols, ylist[i] )
);
Insert Into( dt2stack, Name Expr( dt2stackcols ), 1 );
Eval(
Substitute( Expr( dt2 = dt1 << ping ),
Expr( ping ), Eval Expr( dt2stack )
)
); //This is tricky!
dt2 << set name( "multiple y-axis stack" );
위에서 나는 최소한 두 개의 y 변수를 선택해야 한다는 제약 조건을 언급했습니다. 하나의 변수만 쌓을 수 없다는 것이 밝혀졌습니다(이미 쌓였기 때문에). 변수가 하나만 있으면 스크립트가 충돌합니다. 여기서 흥미로운 점은 지정된 X를 갖는지 여부를 처리하는 논리입니다. X가 있으면 이미 크기를 조정하고 싶지 않았으며 이제는 X 레이블로 원하기 때문에 스택에 포함하고 싶지 않습니다. 지정된 X가 없으면 ylist의 모든 변수를 사용하고 싶습니다.
빨간색으로 표시된 마지막 부분은 설명하기 어렵습니다. 한 줄에 스택을 수행하는 스크립트가 빌드되고 실행/평가됩니다. '핑'이 대체되는 패턴인데, 이 표현들을 펑펑 펑펑 쏟아낼까 고민하다가 가장 먼저 떠오른 단어가 바로 핑(Ping)이다.
dt2stackcols에 대한 표현식은 어디에 있습니까? 이 작업을 할 때 명확성과 제정신을 위해 정의된 모든 표현식을 스크립트 시작 부분으로 옮겼습니다. 이것은 스크립트의 순서를 변경함에 따라 표현식이 모두 필요하기 전에 존재했기 때문에 도움이 되었습니다. 스크립트에 흩어져 있는 상태로 두면 나중에 스크립트에서 정의된 표현식에 삽입하려고 시도하는 경우가 종종 있습니다. 이것이 어떻게 배치되는지 보려면 첨부된 전체 스크립트를 살펴보십시오. 최선의 방법은 아닐 수도 있지만, 나는 내 네미시스 그래프에 대한 모든 중지를 꺼내고 있습니다.
모든 부품 조립
Insert Into( objout, Name Expr( objhlb1 ) );
Insert Into( objvlb, Name Expr( objout ) );
Insert Into( objhlb2, Name Expr( objvlb ) );
Insert Into( objhlb2, Name Expr( obj ) );
Insert Into( objwin, Name Expr( objhlb2 ) );
Eval( Eval Expr( objwin ) ); //Evaluating all the assembled parts after all the expressions are evaluated
gb << size( 600, 285 ); //if you want to format the graph, send messages to gb
JSL의 가장 좋은 점 중 하나는 그것이 함수 기반 언어라는 것입니다. 이것은 두 가지 중요한 일을 달성합니다. 첫 번째는 바퀴를 재발명하지 않고도 특정 작업을 쉽게 수행할 수 있게 하고 두 번째는 복잡한 구조를 구축하는 방법에 대해 쉽게 생각할 수 있게 해줍니다. (당신이 그들을 안쪽에서 바깥쪽으로 만들고 있는 양파로 생각하는 한. 예를 들어, 일반적인 사고 방식은 다음과 같습니다. 먼저 땅을 많이 사서 그 땅에 건물을 짓고, 그 건물에 방을 만들고, 방에 사무실 의자 같은 것들을 놓고, 그 다음에는 의자에 앉고, 마지막으로, 나는 일을 시작한다. 기능적 사고는 다음과 같이 작동합니다. 처음에는 의자가 있었고 나는 그 안에 Byron을 넣었습니다. 그런 다음 의자(여전히 Byron이 있음)를 사무실에 놓고 건물에 넣고 부지에 넣고 구매하고 마침내 Byron이 작동합니다.
첫 번째 단계는 그래프 상자를 objhlb1에 넣은 다음 개요 상자(objout)와 objhlb1이 삽입되는 세로 목록 상자(objvlb)가 있습니다. 이것은 그래프의 왼쪽입니다. 왼쪽에 있기 때문에 ovjvlb는 두 번째 수평 목록 상자(objhlb2)에 먼저 삽입되고 그 다음 그래프 빌더 차트(obj)에 삽입됩니다. 마지막으로 objhlb2(이제 모든 것을 포함함)가 새 창 상자에 삽입되어 표시될 수 있습니다. 그런 다음 모든 것이 작동하도록 평가됩니다. Eval만 사용했다면.. 무슨 일이 일어나는지 확실하지 않지만 작동하지 않으므로 Eval Expr을 먼저 수행하여 모든 평가된 스크립트 전체가 표시되도록 했습니다(스크립트에서 Eval Expr( objwin )만 실행하여 의미를 확인함). Eval을 사용하여 해당 부분을 실행했습니다.
그래프 빌더 플롯인 obj의 형식이 약간 있습니다. 제목이 꺼지고 프레임 크기가 다시 조정되며 y축이 꺼집니다. 이것은 모두 y축 상자의 크기와 모양과 일치하도록 하기 위한 것입니다. 그래프 빌더 플롯을 사용하는 것이 편리합니다. x축을 계속 편집할 수 있고 범례를 이동할 수 있으며 모든 GB 옵션을 추가 형식화에 사용할 수 있기 때문입니다.
현재 끝점
대본에 따르면 7번째 주요 개정판에서는 그다지 깔끔하지 않고 주변에 많은 테이블이 남아 있습니다. 그것과 몇 가지 다른 것들이 고쳐져야 합니다. 따라서 추가할 아이디어가 있으면 함께 보내주십시오. 예를 들어 그래프의 데이터가 원래 데이터 테이블에 동적으로 연결되지 않고 Y축 상자가 Scaled Response Graph 개요 상자에 연결되지 않습니다. 각자 독립적으로. 그것이 효과가 있다면 좋을 것입니다. 마지막으로, 스크립트를 중단시키거나 불행한 결과를 반환하는 방법이 있다고 거의 100% 확신합니다. 따라서 특수 열 이름과 극단적인 이상값 또는 누락된 데이터가 많이 있는지 확인하십시오.
이 스크립트를 작동시키는 더 나은 방법에 대한 의견을 듣고 싶습니다. (작동에 대해 말하자면, 나는 이것을 PC와 Mac의 v13과 v14에서 테스트했고 게시하기 위해 잘 실행되었습니다.)
저자의 마지막 메모:
이것은 마치 우리가 이것에 대해 이야기하는 것처럼 가장 비격식적인 어조로 작성되었습니다.
이는 코딩의 공식적인 전문 용어인 IMHO가 의사소통을 방해하기 때문에 의도된 것입니다. 대신 난독화를 피합니다.