H Ludwig
H Ludwig

Reputation: 83

ggplot coord_polar() plotting between pi/2 and -pi/2 at top and bottom

I have a set of values that range between pi/2 and -pi/2. I'd like to plot them using the histogram geom and polar plot, so at the top of the polar there is pi/2 and at the bottom, there is -pi/2.

The datafile I'm using: https://www.dropbox.com/s/i9npm6whxi9ok5d/ellipse_df.csv?dl=0

ggplot(ellipse_df) +
  geom_histogram(aes(theta)) +
  coord_polar(start = pi/2, direction = -1)

There seems to be something funny with the pinching of the x axis on the left of the plot below:

enter image description here

Upvotes: 2

Views: 1962

Answers (1)

Brian
Brian

Reputation: 8275

You need scale_x_continuous(expand = c(0,0)). ggplot automatically pads a bit on each end of all the scales so there's a nice border around a plot, but in polar coordinates, you usually want it to wrap with no gap.


Updated with additional steps to neaten the appearance:

  ggplot(ellipse_df, aes(theta/(pi))) + 
  geom_histogram(binwidth = .05, colour = "white", boundary = 0) +
  scale_x_continuous(expand = c(0,0), breaks = -2:2/4, 
                     labels = c(expression(frac(-pi, 2)), 
                                expression(frac(-pi, 4)), 
                                "0", 
                                expression(frac(+pi, 4)), 
                                expression(frac(+pi, 2)))) +
  coord_polar(start = pi/2, direction = -1)

If you run this without the arguments to geom_histogram and without coord_polar, you can diagnose what's going on:

enter image description here

The default 30 bins leaves one at the upper edge of the data with very few observations. By forcing the bins to have a certain width and choosing whether 0 is the center or edge, you can force the bins to line up neatly with the range of your data.

enter image description here

Then when you convert it to polar coordinates, it looks how you want, I assume:

enter image description here


Updated to change scale to equal radians

To get the -pi/2 to pi/2 to be the right half of the circle, you need to expand the x limits quite a bit:

  ... +
  scale_x_continuous(expand = c(0,0), 
                     breaks = c(-4, -2:2, 4)/4, 
                     limits = c(-1, 1),           # this is the important change
                     labels = c(expression(-pi),
                                expression(frac(-pi, 2)), 
                                expression(frac(-pi, 4)), "0", 
                                expression(frac(+pi, 4)),
                                expression(frac(+pi, 2)),
                                expression(+pi))) + ...

Since (after scaling by pi), your data go from -1/2 to 1/2, but you want the figure to display -1 to 1, you have to tell it to display all that non-data space.

enter image description here

enter image description here

If your next question is: how can I show it just as a semicircle, without the wasted space on the left? I'll preemptively answer that it's more challenging and will involve precalculating your histogram values and converting the corners of each bar to polar coordinates "by hand".

Upvotes: 4

Related Questions