От декартовой диаграммы к полярной гистограмме с использованием Mathematica - PullRequest
8 голосов
/ 14 сентября 2011

Обратите внимание:

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]}]

enter image description here

Я хотел бы рассчитать для каждой точки ее угол в такой системе координат, как:

enter image description here

Выше - выход Deisred, это частотный отсчет точки, заданной конкретной «Угловой корзиной». Как только я знаю, как вычислить угол, я смогу это сделать.

Ответы [ 3 ]

12 голосов
/ 14 сентября 2011

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

Небольшое визуальное улучшение с использованием Disk секторов вместо Polygon s:

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

Более четкое разделение «баров» достигается с добавлением EdgeForm[{Black, Thickness[0.005]}] в Epilog. Теперь числа, обозначающие кольца, все еще имеют ненужную десятичную точку, идущую за ними. После сюжета с заменой /. 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

Сюжет почти такой же, но он более интерактивный (всплывающие подсказки и т. Д.).

5 голосов
/ 14 сентября 2011

Это

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

возвращает список углов луча от ScreenCenter до каждой точки в радианах и между -pi и pi.

То есть я предположил, что вам нужен угол между каждой точкой на вашем графике и красной точкой.

Обратите внимание на использование ArcTan[x,y] вместо ArcTan[y/x], которое автоматически выбирает соответствующий знак (в противном случае вам придется делать это вручную, как в ответе @ Blender).

5 голосов
/ 14 сентября 2011

Кажется, это полярная система координат . Формулы преобразования декартовых в полярные: в той же статье :

enter image description here

Возвращает угол в радианах.

...