Core Visualization

Min-Hsuan Peng, Wolfram
minhsuanp@wolfram.com

Join the Conversation #WolframTechConf

Overview

• Exclusions
	• ScalingFunctions
	• Labeled and Callout
	• PlotLabels
	• LablingFunction

Exclusions

({{      , None, no exclusions}, {▪, All, all computed exclusions}, {      , Automatic, automatically computed exclusions}, {▪, "Discontinuities", computed jump discontinuities}, {▪, "Singularities", computed singularities}, {      , lhs==rhs, explicitly defined by an equation}, {      , {lhs==rhs,cond}, explicitly defined by an equation and a condition}, {      , {(Subscript[spec, 1]),(Subscript[spec, 2]),…}, union of exclusions given by (Subscript[spec, i])}})

Singularities(Poles and Essential)

Plot[Tan[x],{x,0,4Pi},Exclusions->None,Evaluate@opts]

Plot[Tan[x],{x,0,4Pi},ExclusionsStyle->Directive[Thick,Red],Evaluate@opts]

Removable discontinuity

rmf[x_]:=Piecewise[{{x^2,x<1},{0,Floor[x]==x},{2-x,x>1}}]

Plot[rmf[x],{x,0,5},Evaluate@opts]

Plot[rmf[x],{x,0,5},ExclusionsStyle->Directive[Thickness[0.02],Red],Evaluate@opts]

Jump discontinuity

jmpf[x_]:=Piecewise[{{x^2,x<1},{-x,x>1}}]

Plot[jmpf[x],{x,0,2},ExclusionsStyle->Directive[Thick,Red],Evaluate@opts]

Automation

allf[x_]:=Piecewise[{{x^2,x<1},{0,Floor[x]==x},{-x,3>x>1},{Tan[x],5Pi/2>x≥3},{0, x==5Pi/2},{Sin[25/(x-5Pi/2)],x≥5Pi/2}}]

TraditionalForm[allf[x]]

Plot[allf[x],{x,0,10},ExclusionsStyle->Directive[Thickness[0.01],Red],Exclusions->All,Evaluate@opts]

Presets

Plot[allf[x],{x,0,10},ExclusionsStyle->Directive[Thickness[0.01],Red],Exclusions->"Discontinuities",PlotLabel->"Piecesewise jumps",Evaluate@opts]

Plot[allf[x],{x,0,10},ExclusionsStyle->Directive[Thickness[0.01],Red],Exclusions->"Singularities",PlotLabel->"Essential and Poles",Evaluate@opts]

Branch cut

Plot3D[Im[ArcSin[(x+I y)^4]],{x,-2,2},{y,-2,2},Mesh->None,ExclusionsStyle->{None,Directive[Thickness[0.01],Darker@Red]},Evaluate@opts]

DensityPlot[Im[ArcSin[(x+I y)^4]],{x,-2,2},{y,-2,2},Mesh->None,ExclusionsStyle->{None,Directive[Thickness[0.004],Darker@Red]},Evaluate@opts]

ScalingFunctions

ScalingFunctions → {x, y}

({{      , None, no scaling function}, {      , "Log", use logarithmic scaling}, {      , "Reverse", reverse the coordinate direction}, {      , "Reciprocal", use reciprocal scaling}, {      , "Log10", use logarithmic scaling with base 10}, {      , "Log2", use logarithmic scaling with base 2}, {      , {f,(f^(-1))}, use the scaling function f and its inverse (f^(-1))}, {      , {(Subscript[s, 1]),(Subscript[s, 2]),…}, use several scaling functions (Subscript[s, i]) for direction i}})

V10.4

data=Table[{i^3,Sin[i]},{i,0,10,0.1}];

ListLinePlot[data,ScalingFunctions->{"Log",None},PlotMarkers->{Automatic, 10}]

DateListPlot[TimeSeries[],ScalingFunctions->"Reverse",PlotLabel->"US Rate of Inflation"]

• Aliases: ListLogPlot, ListLogLogPlot, ListLogLinearPlot, DateListLogPlot

V11

ClearAll[sfControl1];Attributes[sfControl1]=HoldAll;sfControl1[Dynamic[{sf_,ysf_}]]:=Dynamic[Style[Row[{larger@"Plot[x^4, {x, 0, 10}, ScalingFunctions -> {",PopupMenu[Dynamic[sf],{None,"Log","Reverse"}],larger@",", PopupMenu[Dynamic[ysf],{None,"Log","Reverse"}],larger@"}]"}]]]
Manipulate[
Plot[x^4,{x,0,10},ScalingFunctions->{sf,ysf},Evaluate@opts],
{{sf,None},ControlType->None},
{{ysf,None},ControlType->None},
Dynamic@sfControl1[Dynamic[{sf,ysf}]]
,SaveDefinitions->True
]

• Aliases: LogPlot, LogLogPlot, LogLinearPlot

• More to come in the future

ScalingFucntions (how it works)(optional slide)

Plot[Sec[x],{x,0,2Pi},PlotTheme->"Scientific",Evaluate@opts]

how it works, conceptually...

• function/data → ScalingFunction[function/data]

scaling=1/#&;

inverse=1/#&;

Plot[scaling@Sec[x],{x,0,2Pi},PlotTheme->"Scientific",Evaluate@opts]

• ticks → inverseSF[ticks]

ticks=FindDivisions[{-1,0},6]~Join~FindDivisions[{0,1},6]

Quiet@DeleteCases[Transpose@{ticks,inverse@ticks},{0,_}]

Plot[scaling[Sec[x]],{x,0,2Pi},FrameTicks->{{Quiet@DeleteCases[Transpose@{ticks,InputForm/@inverse@ticks},{0,_}],Automatic},{Automatic,Automatic}},PlotTheme->"Scientific",LabelStyle->16]

• CoordinatesToolOptions -> "DisplayFunction" -> Function[ {point}, {inverseSF[point_x], inverseSF[point_y]}]]

• Other options handling

Labeled - V10.4

Labeled[data,"label"]

• Charting

BarChart[Labeled[#,#]&/@Range[4],ImageSize->360]

• ListPlot

ListPlot[Table[Labeled[{ElementData[z,"AbsoluteBoilingPoint"],ElementData[z,"VaporizationHeat"]},Style[ElementData[z,"Name"],Background->Directive[White,Opacity[0.7]]]],{z,20,35}],LabelStyle->12,Evaluate@opts,FrameLabel->{"AbsoluteBoilingPoint","VaporizationHeat"}]

• ListLinePlot

ListLinePlot[MapIndexed[Labeled[#,#2[[1]]]&,Accumulate[RandomReal[{-1,1},30]]],Evaluate@opts,PlotMarkers->{Automatic, 12}]

Labeled and Callout in V11

• Wrapper Labeled for the curves

Labeled[curve,"label",position]

Plot[Evaluate@Fold[Labeled[#,"x="<>ToString[InputForm[#2]],#2]&,Sin[x]/x,Range[0,10,2]],{x,0,10},Evaluate@opts]

• Wrapper Callout for the points and curves

Callout[curve,"label",position]

Plot[Evaluate@Fold[Callout[#,"x="<>ToString[InputForm[#2]],#2,copts]&,Sin[x]/x,Range[0,10,2]],{x,0,10},Evaluate@opts]

Callout[data,"label"]

ListPlot[Table[Callout[{ElementData[z,"AbsoluteBoilingPoint"],ElementData[z,"VaporizationHeat"]},ElementData[z,"Name"],copts],{z,20,35}],LabelStyle->13,Evaluate@opts,FrameLabel->{"AbsoluteBoilingPoint","VaporizationHeat"}]

Labeled and Callout

Specifying callout label position...

• Automatic vertical position
   • Automatic leader position

Plot[Callout[Sin[x],"callout label",2.5,copts],{x,0,2Pi},Evaluate@opts]

Plot[Evaluate@Fold[Callout[#,ToString[InputForm[#2]],#2,#2,Appearance->"Frame",FrameMargins->4,copts]&,Sin[x],Range[0,2Pi,2Pi/8]],{x,0,2Pi},LabelStyle->12,Evaluate@opts]

Fine control

ClearAll[calloutControl];Attributes[calloutControl]=HoldAll;calloutControl[Dynamic[{y_,z_,app_}]]:=Dynamic[Style[Row[{larger@"Plot[Callout[Sin[x],label,",larger@InputField[Dynamic[y],FieldSize->6],larger@",",larger@InputField[Dynamic[z],FieldSize->6],larger@", Appearance -> ",PopupMenu[Dynamic[app],{"Leader","CurvedLeader","Balloon","LineBalloon","Line","Frame","Corners"}],larger@"],{x,0,2π}]"}],"Program"]]
Manipulate[
Plot[Callout[Sin[x],"label",pos,apos,Appearance->app],{x,0,2π},Evaluate@opts],
{{app,"Leader"},ControlType->None},
{{pos,3, Magnify["label position",2]},0,2Pi},
{{apos,3,Magnify["leader position",2]},0,2Pi},
Delimiter,
Dynamic@calloutControl[Dynamic[{pos,apos,app}]]
,SaveDefinitions->True
]

Manipulate[ListPlot[{1,Callout[3,"label",LeaderSize->{{length,rotation,gap},{nl,N[nr]/. 0.->Automatic}}],2,6},Evaluate@opts],
{{length,25,larger@"length"},5,80},
{{rotation,0,larger@"rotation"},0,2Pi},
{{gap,5,larger@"gap"},0,20},
Delimiter,
{{nl,15,larger@"neck length"},5,60},
{{nr,0,larger@"neck rotation"},0,2Pi},
Delimiter,
Dynamic[With[{length=length,rotation=rotation,gap=gap,nl=nl,nr=N[nr]/. 0.->Automatic},larger@HoldForm[ListPlot[{1,Callout[3,"label",LeaderSize->Style[{{length,rotation,gap},{nl,nr}},Bold]],2,6}]]]]
]

PlotLabels

Usage

({{      , None, no labels}, {      , Automatic, automatic labels}, {      , {(Subscript[lbl, 1]),(Subscript[lbl, 2]),…}, use (Subscript[lbl, i]) for the i(^th) label}, {      , Placed[labels,pos], labels at position pos}, {      , Placed[labels,pos,f], labels formatted with f}})

Examples

Put labels after the curves

sol=DSolve[{y'[x]-3z[x]==Sin[x], y[x]+z[x]==1/5, y[Pi/2]==1/2},{y,z},x];
Plot[Evaluate[{y[x],z[x],y[x]+z[x]}/.sol], {x,2,16},PlotLabels->{y[x],z[x],y[x]+z[x]},Evaluate@opts]

💡 Try PlotLabels->Automatic with the above example to see why I didn’t use it.

Put labels along the curves

Plot[Evaluate[{y[x],z[x],y[x]+z[x]}/.sol], {x,2,16},PlotLabels->{Placed[y[x],{9,Above},Framed],Placed[z[x],14],y[x]+z[x]},Evaluate@opts]

Use Callout

Plot[Evaluate[{y[x],z[x],y[x]+z[x]}/.sol], {x,2,16},PlotLabels->{Callout[y[x],{9,Above},copts],Callout[z[x],{11,Above},Appearance->"Balloon",copts],Callout[y[x]+z[x],{8,0.1},8,copts]},Evaluate@opts]

LabelingFunction

Data Visualization
   - Charts
   - ListPlot, ListLinePlot
   - ListStepPlot, DateListStepPlot

LabelingFunction -> Top|Bottom|Left|Right|Center|Tooltip|StatusArea|Automatic
LabelingFunction -> Placed[makelabel[#1,#2,#3], pos]&

LabelingFunction -> Callout[Automatic,Top|Bottom|Left|Right|Center|Automatic]
LabelingFunction -> Callout[makelabel[#1,#2,#3], pos]&

Automation on data

ListLinePlot[
<|
"data1"-><|"A"->24,"B"->9,"C"->5,"D"->15,"E"->2,"F"->14,"G"->7|>,
"data2"-><|"A"->4,"B"->18,"C"->25,"D"->20,"E"->8,"F"->5,"G"->21|>
|>,
PlotMarkers->{Automatic, 15},Evaluate@opts]

Automation

ClearAll[lblcontrol1];Attributes[lblcontrol1]=HoldAll;lblcontrol1[Dynamic[{f_,p_}]]:=Dynamic[Style[Row[{PopupMenu[Dynamic[f],{ListPlot,ListLinePlot,ListStepPlot}],"[<|a->1, aah->4, aardvark->2, aback->6, abacus->4, abaft->8|>, LabelingFunction->",PopupMenu[Dynamic[p],{Automatic,Left,Right,Bottom,Top,Center}],"]"}],"Program",Bold]]
Manipulate[
f[<|"a"->1,"aah"->4,"aardvark"->2,"aback"->6,"abacus"->4,"abaft"->8|>,LabelingFunction->pos,PlotMarkers->{Automatic,10},LabelStyle->14,Evaluate@opts],
{{f,ListPlot},ControlType->None},
{{pos,Top},ControlType->None},
Dynamic@lblcontrol1[Dynamic[{f,pos}]]
,SaveDefinitions->True
]

lfdata1=<|"a"->1,"aah"->4,"aardvark"->2,"aback"->6,"abacus"->4,"abaft"->8|>;

ClearAll[lblingfunctionControl];Attributes[lblingfunctionControl]=HoldAll;lblingfunctionControl[Dynamic[{f_,a_,p_,type_}]]:=Dynamic[Style[Row[{PopupMenu[Dynamic[f],{ListPlot,ListLinePlot,ListStepPlot}],"[lfdata1, LabelingFunction -> (",PopupMenu[Dynamic[type],{Placed,Callout}],"[",PopupMenu[Dynamic[a],{Slot[1],Slot[2],Slot[3]}],",",PopupMenu[Dynamic[p],{Automatic,Left,Right,Bottom,Top,If[type===Callout,Nothing,Center]}],"]&)]"}],"Program",Bold]]
Manipulate[
f[lfdata1,LabelingFunction->(Function[{value,index,label},type[{value,index,label[[3,1]]}[[First[arg]]],pos]]),LabelStyle->16,Evaluate@opts],
{{f,ListPlot},ControlType->None},
{{arg,Slot[1]},ControlType->None},
{{pos,Top},ControlType->None},
{{type,Placed},ControlType->None},
Dynamic@lblingfunctionControl[Dynamic[{f,arg,pos,type}]]
,SaveDefinitions->True
]

Example

lfdata2=EntityValue[CountryData["G10"],{"Name","Area","Population"}];

lfdata2=AssociationThread[lfdata2[[All,1]]->lfdata2[[All,2;;3]]]

ListLogLogPlot[lfdata2,FrameLabel->Automatic,LabelingFunction->(Callout[#3[[3,1]],Automatic,copts]&),ImageSize->600]

Initialization

$PlotTheme={"Presentation","Large","ThickLine","Business"};
larger[f_, s_:2]:=Magnify[f,s]
opts={LabelStyle->16,ImageSize->460};
copts={CalloutStyle->Directive[Thick,Gray]};
fopts={Appearance->"Frame",RoundingRadius->2,FrameMargins->6,Background->Opacity[1],CalloutStyle->GrayLevel[0.8]};
pwFunc[x_]:=Piecewise[{{x^2,x<1},{0,Floor[x]==x},{-x,3>x>1},{Tan[x],5Pi/2>x≥3},{0, x==5Pi/2},{Sin[25/(x-5Pi/2)],x≥5Pi/2}}]
showcase=Plot[Callout[Callout[Callout[pwFunc[x],"removable",{3.5,4.5},{{2},{4},{7}}],"jump",{2,2},{{1.05,0.5},{2.95,-1}}],"singularities",{6.5,-3},{{5Pi/2-0.05,3},{3Pi/2+0.05,-2}}],{x,0,10},ExclusionsStyle->Directive[Thickness[0.01],Red],Exclusions->All,PlotLabels->Automatic];