从笛卡尔坐标系到极坐标直方图:使用Mathematica

8

请注意:

dalist={{21, 22}, {26, 13}, {32, 17}, {31, 11}, {30, 9}, 
        {25, 12}, {12, 16}, {18, 20}, {13, 23}, {19, 21}, 
        {14, 16}, {14, 22}, {18,22}, {10, 22}, {17, 23}}


ScreenCenter = {20, 15}

FrameXYs = {{4.32, 3.23}, {35.68, 26.75}}

Graphics[{EdgeForm[Thick], White, Rectangle @@ FrameXYs, 
          Black, Point@dalist, Red, Disk[ScreenCenter, .5]}]

我希望能够计算每个点在坐标系中的角度,例如:
上图是期望的输出结果,这些是给定特定“角度区间”的点的频率计数。一旦我知道如何计算角度,我就能做到这一点。
3个回答

12

Mathematica有一个专门用于此目的的绘图函数:ListPolarPlot。您需要将您的x,y对转换为theta,r对,例如如下:

ListPolarPlot[{ArcTan[##], EuclideanDistance[##]} & @@@ (#-ScreenCenter & /@ dalist), 
          PolarAxes -> True, 
          PolarGridLines -> Automatic, 
          Joined -> False, 
          PolarTicks -> {"Degrees", Automatic}, 
          BaseStyle -> {FontFamily -> "Arial", FontWeight -> Bold,FontSize -> 12}, 
          PlotStyle -> {Red, PointSize -> 0.02}
]

enter image description here


更新

根据评论的要求,可以按照以下方式制作极地直方图:

maxScale = 100;
angleDivisions = 20;
dAng = (2 \[Pi])/angleDivisions;

一些测试数据:
(counts = Table[RandomInteger[{0, 100}], {ang, angleDivisions}]) // BarChart

enter image description here

ListPolarPlot[{{0, maxScale}}, 
    PolarAxes -> True, PolarGridLines -> Automatic, 
    PolarTicks -> {"Degrees", Automatic}, 
    BaseStyle -> {FontFamily -> "Arial", FontWeight -> Bold, FontSize -> 12}, 
    PlotStyle -> {None}, 
    Epilog -> {Opacity[0.7], Blue, 
               Table[
                 Polygon@
                  {
                   {0, 0}, 
                   counts[[ang + 1]] {Cos[ang dAng - dAng/2],Sin[ang dAng- dAng/2]}, 
                   counts[[ang + 1]] {Cos[ang dAng + dAng/2],Sin[ang dAng+ dAng/2]}
                  },   
                 {ang, 0, angleDivisions - 1}
               ]}
]

enter image description here

使用磁盘扇区而不是多边形,进行小的视觉改进:

ListPolarPlot[{{0, maxScale}}, 
    PolarAxes -> True, PolarGridLines -> Automatic, 
    PolarTicks -> {"Degrees", Automatic}, 
    BaseStyle -> {FontFamily -> "Arial", FontWeight -> Bold, 
    FontSize -> 12}, PlotStyle -> {None}, 
    Epilog -> {Opacity[0.7], Blue, 
               Table[
                 Disk[{0,0},counts[[ang+1]],{ang dAng-dAng/2,ang dAng+dAng/2}],       
                 {ang, 0, angleDivisions - 1}
               ]
              }
]

enter image description here

通过在Epilog中添加EdgeForm[{Black, Thickness[0.005]}],可以更清晰地分离“条形图”。现在标记环的数字仍然有不必要的小数点。使用替换/. Style[num_?MachineNumberQ, List[]] -> Style[num // Round, List[]]跟踪绘图可消除这些问题。最终结果如下:

enter image description here

上面的图表也可以使用SectorChart生成,尽管此图表主要用于显示数据的宽度和高度变化,并且未经过精细调整,不适用于您具有固定宽度部分并且想要突出显示这些方向和数据计数的情况。但是可以通过使用SectorOrigin来完成。问题是我认为扇形的中点代表其方向,因此要使一个扇形的中点为0度,我必须将原点偏移\[Pi]/angleDivisions并手动指定刻度,因为它们也会被旋转:
SectorChart[
   {ConstantArray[1, Length[counts]], counts}\[Transpose], 
   SectorOrigin -> {-\[Pi]/angleDivisions, "Counterclockwise"}, 
   PolarAxes -> True, PolarGridLines -> Automatic, 
   PolarTicks -> 
    {
     Table[{i \[Degree] + \[Pi]/angleDivisions, i \[Degree]}, {i, 0, 345, 15}], 
     Automatic
    }, 
   ChartStyle -> {Directive[EdgeForm[{Black, Thickness[0.005]}], Blue]},
   BaseStyle -> {FontFamily -> "Arial", FontWeight -> Bold, 
   FontSize -> 12}
 ]

enter image description here

故事情节几乎相同,但更具互动性(包括工具提示等)。

谢谢您,Sjoerd。极坐标直方图是否存在? - 500
http://t0.gstatic.com/images?q=tbn:ANd9GcTQrKELoYtiEuAElJwl6ocF60URjADZNW1KrFQ8q4npE3mxtMWP - Dr. belisarius
@Simon 是的!我有一段时间看到过那个。我从来没有理解过画一个蝙蝠函数为什么会得到250个赞:) - Dr. belisarius
@belisarius:炫耀啊!这是一个很好的答案,显然对那些没有见过基本数学的程序员非常有用。 - Simon
@Simon 但是,将那里讨论的概念问题与任何优秀的Leonid(例如)的答案进行比较...真是可惜。 - Dr. belisarius
显示剩余13条评论

5

5
除了Blender的回答之外,使用ArcTan的两参数形式,因为它会自动考虑象限。 - rcollyer
谢谢您,设置ScreenCenter = {20, 15}作为我的转换原点的最佳方法是什么? - 500
1
将所有的 y 替换为 y + ScreenCenter.y,对于 x 也做类似的操作。 - Blender

5

This

N@ArcTan[#[[1]], #[[2]]] & /@ (# - ScreenCenter & /@ dalist)

返回从 屏幕中心 到每个点的射线角度列表,以弧度为单位,范围在 -pi 和 pi 之间。

也就是说,我假设您想要绘图中每个点与红点之间的角度。

请注意使用 ArcTan[x,y] 而不是 ArcTan[y/x],它会自动选择适当的符号(否则您将不得不像 @Blender 的答案中那样手动选择)。


很抱歉,我有点疯了。当我尝试使用您的解决方案或Sjoerd的解决方案在我的实际数据上绘制直方图时,象限的可视化位置都是错误的。我感到非常困惑,您能给我展示一个例子吗?对于我来说,左上角应该是右下角,右上角应该是左下角。 - 500
@500 我不明白你在问什么!这里的“implement”是什么意思?你明白这些是弧度制下从-x轴开始,范围为-pi到pi的角度吗? - acl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接