BarLegend ขีดผิดเพี้ยนใน MatrixPlot
ตามที่ปรากฏในกระทู้มากมายที่นี่ ( นี้ , นี้ , ... ), เป็นตัวเลือกที่ถูกต้องTicks แต่ก็ไม่ได้ดูเหมือนจะทำงานได้ดีในที่เรียบง่ายนี้BarLegend MatrixPlotเห็บบางตัวหายไปและเห็นได้ชัดว่า 0.5 ไม่อยู่ในตำแหน่งที่ถูกต้อง (สี) โปรดทราบว่าฉันต้องการพล็อตเริ่มต้นด้วยเห็บที่กำหนดเอง ฉันขาดอะไรที่นี่หรือวิธีแก้ปัญหาใด ๆ
data = Table[Sin[x] Cos[y], {x, 0, 2 Pi, 0.01}, {y, 0, 2 Pi, 0.01}];
MatrixPlot[data,
PlotLegends -> BarLegend[Automatic, "Ticks" -> {-0.5, 0, 0.5}],
LabelStyle -> Large]
อัปเดต:
กรณีทั่วไปที่มีช่วงข้อมูลไม่สมมาตร
data = Table[Sin[x] Cos[y] + 0.05 x y, {x, 0, 2 Pi, 0.01}, {y, 0, 2 Pi, 0.01}];
MatrixPlot[data, PlotLegends -> BarLegend[Automatic, "Ticks" -> {-0.2, 0.5, 1.1}],
LabelStyle -> Large]
คำตอบ
ปรับปรุง:ฟังก์ชั่นGraphics`ArrayPlotDump`Private`HybridRankingAndNaturalScaleการดำเนินลึกลับ"การปรับขึ้นอยู่กับส่วนผสมของค่าสัมพัทธ์และการจัดอันดับสำหรับแต่ละองค์ประกอบเมทริกซ์" เราสร้างฟังก์ชัน re-scaling แบบทีละชิ้น ( reScale) โดยใช้mpReScaleและใช้เพื่อระบุค่าตัวเลือกสำหรับ"Ticks":
ClearAll[reScale, cfMinMax]
reScale[{min_, max_}, {cfmin_, cfmax_}] :=
If[# < 0, Rescale[#, {min, 0}, {cfmin, 1/2}], Rescale[#, {0, max}, {1/2, cfmax}]] &;
cfMinMax = MinMax @ Graphics`ArrayPlotDump`Private`HybridRankingAndNaturalScale[
Union @ SparseArray[#]["NonzeroValues"], 0., {0, 1}, .5] &;
ตัวอย่าง:
data = {{1, 2, 1}, {2, 0, 1}, {0, -5, -1}};
ticks = {-4, -2, 3/2, 2};
cfminmax = cfMinMax[data];
minmax = MinMax @ data;
Row[{MatrixPlot[data, ImageSize -> 400,
PlotLegends -> BarLegend[Automatic], LabelStyle -> 16,
PlotLabel -> "default"],
MatrixPlot[data, ImageSize -> 400,
PlotLegends -> BarLegend[Automatic,
"Ticks" -> (Transpose[{reScale[minmax, cfminmax] /@ #, #}] & @ ticks)],
LabelStyle -> 16,
PlotLabel -> Row[{"Ticks : ", ticks}]]}, Spacer[10]]
กัน:เราสามารถใช้ตัวเลือกอื่นที่ไม่มีเอกสารเพื่อระบุป้ายกำกับ
BarLegend[Automatic, "TickLabels" -> ticks,
"Ticks" -> (reScale[minmax, cfminmax] /@ ticks)]
เพื่อรับภาพในพล็อตที่สองด้านบน
เปลี่ยนdataและticksเป็น
data = Table[Sin[x] Cos[y], {x, 0, 2 Pi, 0.01}, {y, 0, 2 Pi, 0.01}];
ticks = {-0.5, 0, 0.5};
ที่จะได้รับ
ใช้ตัวอย่างที่สองใน OP:
data = Table[Sin[x] Cos[y] + 0.05 x y, {x, 0, 2 Pi, 0.01}, {y, 0, 2 Pi, 0.01}];
ticks = {-0.2, 0.5, 1.1};
เราได้รับ
ด้วย
data = 1. + Table[Sin[x] Cos[y] + 0.05 x y, {x, 0, 2 Pi, 0.01}, {y, 0, 2 Pi, 0.01}] ;
ticks = {0.1, 0.5, 1.1, 2};
เราได้รับ
คำตอบเดิม:
สิ่งนี้ดูเหมือนจะเกี่ยวข้องกับวิธีการปรับขนาดพิเศษMatrixPlotดังที่กล่าวไว้ในMatrixPlot >> รายละเอียดและตัวเลือก
การแก้ไขที่ง่ายที่สุดในกรณีของ OP คือการเปลี่ยนข้อกำหนดเห็บเป็นTranspose[{Rescale[#, {-1, 1}, {0, 1}], #} &@{-0.5, 0, 0.5}]:
MatrixPlot[data,
PlotLegends ->
BarLegend[Automatic,
"Ticks" -> Transpose[{Rescale[#, {-1, 1}, {0, 1}], #} & @ {-0.5, 0, 0.5}]],
LabelStyle -> Large]
ทางเลือกอื่น (ทั่วไปกว่า) ใช้ฟังก์ชันสีเริ่มต้นกับอาร์กิวเมนต์ที่ปรับขนาดใหม่และตัวเลือกColorFunctionScaling -> False:
defaultCF = "DefaultColorFunction" /.
(Method /. Charting`ResolvePlotTheme[Automatic, MatrixPlot])
Blend[System`PlotThemeDump`$ThemeDefaultMatrix, #1] &
MatrixPlot[data,
ColorFunction -> (defaultCF[Rescale[#, {-1, 1}]] &),
ColorFunctionScaling -> False,
PlotLegends -> BarLegend[Automatic, "Ticks" -> {-0.5, 0, 0.5}],
LabelStyle -> Large]
หรือระบุฟังก์ชันสีในBarLegend:
MatrixPlot[data,
PlotLegends -> BarLegend[{defaultCF[Rescale[#, {-1, 1}]] &, {-1, 1}},
ColorFunctionScaling -> False, "Ticks" -> {-0.5, 0, 0.5}],
LabelStyle -> Large]
kglrได้แก้ไขปัญหาแล้วนี่เป็นเพียงการวิเคราะห์เพิ่มเติมและวิธีแก้ไขปัญหาอื่น ๆ ที่เป็นไปได้
ก่อนอื่นฉันไม่คิดว่านี่เป็นข้อบกพร่องเนื่องจากโดยค่าเริ่มต้นMatrixPlotรู้วิธีตั้งค่าที่เหมาะสมTicksสำหรับBarLegend:
plot = MatrixPlot[data, ImageSize -> 400, PlotLegends -> Automatic]
เมื่อมองเข้าไปplotเราพบว่า:
plot[[2, 1]] // InputForm
(*
BarLegend[{Blend[System`PlotThemeDump`$ThemeDefaultMatrix, #1] & ,
{0.2889327547713697, 1.}}, LabelStyle -> {},
LegendLayout -> "Column", LegendMarkerSize -> 400,
Ticks -> {{0.39446607623278385, -0.5}, {0.5, 0.}, {0.3100389372190109,
-0.9}, {0.626985112913238, 0.5}, {0.753970225826476, 1.},
{0.880955338739714, 1.5}, {0.9825434290703043, 1.9000000000000001}},
"PinningPoint" -> 0.5, "SmoothRange" -> False,
Charting`TickSide -> Right, ColorFunctionScaling -> False]
*)
อย่างที่เราเห็นเห็บBarLegendถูกกำหนดโดยTicksตัวเลือกที่ไม่มีเอกสารเราจะพล็อตเห็บ:
autotick = Cases[plot[[2, 1]], (Ticks -> a_) :> a][[1]] // Sort
ListLinePlot[autotick]
{0.5, 0.}ไม่ยากที่จะแจ้งให้ทราบว่าเส้นค่ที่แยกที่ เราสามารถตรวจสอบเพิ่มเติมได้ด้วยLinearModelFit:
LinearModelFit[autotick[[#]], {1, x}, x]["RSquared"] & /@ {;; 3, 3 ;;}
(* {1., 1.} *)
ดังนั้นแม้ว่าเราจะไม่ทราบถึงเรื่องGraphics`ArrayPlotDump`Private`HybridRankingAndNaturalScaleนี้เราก็ยังสามารถขายเห็บได้ในลักษณะต่อไปนี้:
ticks = {-0.2, 0.5, 1.1}
Clear[rescale]
rescale[tick_List, rest__] := rescale[#, rest] & /@ tick
rescale[tick_?Positive, mysteryminmax_, {min_, max_}] :=
Rescale[tick, {0, max}, {1/2, mysteryminmax[[2]]}]
rescale[tick_, mysteryminmax_, {min_, max_}] :=
Rescale[tick, {min, 0}, {mysteryminmax[[1]], 1/2}]
plot /. (Ticks -> _) :> (Ticks -> {rescale[ticks,
Sequence @@ (autotick[[{1, -1}]]\[Transpose])], ticks}\[Transpose])