Polar plot gives wrong angles in matplotlib - python

I am trying to plot a Right Ascension - Declination, polar plot in Python, where the angle denotes the right ascension, and the radius the declination, ranging between ±30.
My code is
import numpy
import matplotlib.pyplot as pyplot
ra = [345.389547454166689,31.892236646759279,45.893722479722229,93.955296573703706,160.079453957685217,211.154701609814822,256.486559377222193,307.258751710462889,299.691923545370344,340.364168244814834,335.077343971296386,358.126565808425880]
dec = [23.835021447037050,25.218513920000003,27.509148433518519,26.551432991388879,-25.077519630833340,-20.134061982500004,-21.042512836851849,-4.903512838240742,-0.506450475370370,14.280932901944448,19.222101837500002,18.792707990925926]
fig = pyplot.figure()
ax = fig.add_axes([0.1,0.1,0.8,0.8],polar=True)
ax.set_ylim(-30,30)
ax.set_yticks(numpy.arange(-30,30,10))
ax.scatter(ra,dec,c ='r')
pyplot.show()
This produces the following graph:
Clearly I am misunderstanding how a polar graph works, as the RA's do not correspond to the angle round from theta = 0. For example, one of my points should have RA = 45.89 degrees, yet no point seems to correspond to this.
Any advice on what I'm doing wrong?

The plot requires radians. Adding the following line and replotting shows correctly:
ra = [x/180.0*3.141593 for x in ra]

Related

Polar plots in python

I'm trying to plot antenna pattern in python. I have the measured theta vs. radius readings in a csv file. However, when I try the following code
import numpy as np
import matplotlib.pyplot as plt
gain_on = np.loadtxt('patterne.txt')
#------------------------------------------------------------------------
theta = gain_on[:, 0]
r = gain_on[:, 3]
fig1 = plt.figure()
ax1 = fig1.add_axes([0.1,0.1,0.8,0.8],polar=True)
ax1.set_rlim(-50,0)
#ax1.set_yticks(np.arange(-2,2,0.5))
ax1.plot(theta,r)
plt.show()
I get this output
python polar plot
The expected plot is
expected plot
How do I get the expected plot in python?
Change your units for theta from degrees to radians:
theta = numpy.deg2rad(gain_on[:,0])
In the examples for Matplotlib polar plots they always use angle in radians. e.g. https://matplotlib.org/stable/gallery/pie_and_polar_charts/polar_demo.html

How to rotate theta ticklabels in a matplotlib polar plot?

In a matplotlib polar plot, I would like to rotate each individual theta ticklabel by a different angle. However, I cannot find anything in the documentation to do that. Here's a simple plot to illustrate:
from matplotlib import pyplot as plt
import numpy as np
fig = plt.figure()
ax = plt.axes(polar=True)
ax.set_thetalim(0., np.pi/4.)
ax.set_rlim(0., 2.)
# set the size of theta ticklabels (works)
thetatick_locs = np.linspace(0.,45.,4)
thetatick_labels = [u'%i\u00b0'%np.round(x) for x in thetatick_locs]
ax.set_thetagrids(thetatick_locs, thetatick_labels, fontsize=16)
This adds labels at 0, 15, 30 and 45 degrees. What I'd like to do is rotate the 15 degree label by 15 degrees, the 30 degree label by 30 degrees, and so on, so that each label's text direction is radially outward. Since get_xticklabels on a PolarAxes instance seems to get the theta ticklabels, I tried:
for i,t in enumerate(ax.get_xticklabels()):
t.set_rotation(thetatick_locs[i])
However, that did nothing. Is there any other way of doing what I want? In general, I'm finding that the documentation for polar axes is not as thorough as for rectangular axes, probably because fewer people use it. So maybe there's already a way to do this.
Your current method works for cartesian coordinates but for polar coordinates, you can use the workaround solution presented earlier here. I have adapted that answer for you below. You can add the following code after setting the theta grids
fig.canvas.draw()
labels = []
for label, angle in zip(ax.get_xticklabels(), thetatick_locs):
x,y = label.get_position()
lab = ax.text(x,y, label.get_text(), transform=label.get_transform(),
ha=label.get_ha(), va=label.get_va())
lab.set_rotation(angle)
labels.append(lab)
ax.set_xticklabels([])
plt.show()

How to draw few angles to compare them?

I have a csv database with number of angles (all of them from 0 to 360). I want kind of matplotlib diagram which show me distribution of all angles (for every row in csv).
Maybe you know how to realize that with any python library?
Or please show me how to draw at least two angles as vectors?
I was find only polar plot in matplotlib, that have degrees and its a circle. And I need something like this image (three angles shown and understandable for comparing) (draw lines by hand).
https://i.stack.imgur.com/Ls5zI.png
The polar plot is a bit strange, I managed to create the plot using a scatter plot set to polar. I haven't included any code to read in the angles from a csv, just note that should be converted to radians before plotting.
import numpy as np
import matplotlib.pyplot as plt
theta = np.radians(np.array([10, 20, 40]))
radius = np.ones(theta.size) # make a radius for each point of length 1
fig = plt.figure()
ax = plt.subplot(111, polar=True) # Create subplot in polar format
for t, r in zip(theta, radius):
ax.plot((0, t), (0, r))
fig.show()

Matplotlib plot has slanted lines

I'm trying to plot projections of coordinates onto a line, but for some reason, Matplotlib is plotting the projections in a slightly slanted manner. Ideally, I would like the (blue) projections to be perpendicular to the (green) line. Here's an image of how it looks with sample data:
As you can see, the angles between the blue lines and the green line are slightly obtuse instead of right. I tried playing around with the rotation parameter to the annotate function, but this did not help. The code for this plot is below, although the data might look a bit different since the random generator is not seeded:
import numpy as np
import matplotlib.pyplot as plt
prefs = {'color':'purple','edgecolors':'black'}
X = np.dot(np.random.rand(2,2), np.random.rand(2,50)).T
pts = np.linspace(-1,1)
v1_m = 0.8076549717643662
plt.scatter(X[:,0],X[:,1],**prefs)
plt.plot(pts, [v1_m*x for x in pts], color='lightgreen')
for x,y in X:
# slope of connecting line
# y = mx+b
m = -np.reciprocal(v1_m)
b = y-m*x
# find intersecting point
zx = b/(v1_m-m)
zy = v1_m*zx
# draw line
plt.annotate('',(zx,zy),(x,y),arrowprops=dict(linewidth=2,arrowstyle='-',color='lightblue'))
plt.show()
The problem lies in the unequal axes which makes it look like they are not at a right angle. Use plt.axis('equal') to have equal axis spans on x- and y-axis and a square figure with equal height and width. plt.axis('scaled') works the same way. As pointed out by #CedricZoppolo, you should set the equal aspect ratios before plt.show(). As per docs, setting the aspect ratio to "equal" means
same scaling from data to plot units for x and y
import numpy as np
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(8,8))
# Your code here
plt.axis('equal')
plt.show()
Choosing a square figure is not necessary as it works also with rectangular figures as
fig = plt.figure(figsize=(8,6))
# Your code here
plt.axis('equal')
plt.show()
The blue lines not being perpendicular is due to axis not being equal.
You just need to add below line before plt.show()
plt.gca().set_aspect('equal')
Below you can see the resulted graph:

Changing axis options for Polar Plots in Matplotlib/Python

I have a problem changing my axis labels in Matplotlib. I want to change the radial axis options in my Polar Plot.
Basically, I'm computing the distortion of a cylinder, which is nothing but how much the radius deviates from the original (perfectly circular) cylinder. Some of the distortion values are negative, while some are positive due to tensile and compressive forces. I'm looking for a way to represent this in cylindrical coordinates graphically, so I thought that a polar plot was my best bet. Excel gives me a 'radar chart' option which is flexible enough to let me specify minimum and maximum radial axis values. I want to replicate this on Python using Matplotlib.
My Python script for plotting on polar coordinates is as follows.
#!usr/bin/env python
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(-180.0,190.0,10)
theta = (np.pi/180.0 )*x # in radians
offset = 2.0
R1 = [-0.358,-0.483,-0.479,-0.346,-0.121,0.137,0.358,0.483,0.479,0.346,0.121,\
-0.137,-0.358,-0.483,-0.479,-0.346,-0.121,0.137,0.358,0.483,0.479,0.346,0.121,\
-0.137,-0.358,-0.483,-0.479,-0.346,-0.121,0.137,0.358,0.483,0.479,0.346,0.121,\
-0.137,-0.358]
fig1 = plt.figure()
ax1 = fig1.add_axes([0.1,0.1,0.8,0.8],polar=True)
ax1.set_rmax(1)
ax1.plot(theta,R1,lw=2.5)
My plot looks as follows:
But this is not how I want to present it. I want to vary my radial axis, so that I can show the data as a deviation from some reference value, say -2. How do I ask Matplotlib in polar coordinates to change the minimum axis label? I can do this VERY easily in Excel. I choose a minimum radial value of -2, to get the following Excel radar chart:
On Python, I can easily offset my input data by a magnitude of 2. My new dataset is called R2, as shown:
#!usr/bin/env python
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(-180.0,190.0,10)
theta = (np.pi/180.0 )*x # in radians
offset = 2.0
R2 = [1.642,1.517,1.521,1.654,1.879,2.137,2.358,2.483,2.479,2.346,2.121,1.863,\
1.642,1.517,1.521,1.654,1.879,2.137,2.358,2.483,2.479,2.346,2.121,1.863,1.642,\
1.517,1.521,1.654,1.879,2.137,2.358,2.483,2.479,2.346,2.121,1.863,1.642]
fig2 = plt.figure()
ax2 = fig2.add_axes([0.1,0.1,0.8,0.8],polar=True)
ax2.plot(theta,R2,lw=2.5)
ax2.set_rmax(1.5*offset)
plt.show()
The plot is shown below:
Once I get this, I can MANUALLY add axis labels and hard-code it into my script. But this is a really ugly way. Is there any way I can directly get a Matplotlib equivalent of the Excel radar chart and change my axis labels without having to manipulate my input data?
You can just use the normal way of setting axis limits:
#!usr/bin/env python
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(-180.0,190.0,10)
theta = (np.pi/180.0 )*x # in radians
offset = 2.0
R1 = [-0.358,-0.483,-0.479,-0.346,-0.121,0.137,0.358,0.483,0.479,0.346,0.121,\
-0.137,-0.358,-0.483,-0.479,-0.346,-0.121,0.137,0.358,0.483,0.479,0.346,0.121,\
-0.137,-0.358,-0.483,-0.479,-0.346,-0.121,0.137,0.358,0.483,0.479,0.346,0.121,\
-0.137,-0.358]
fig1 = plt.figure()
ax1 = fig1.add_axes([0.1,0.1,0.8,0.8],polar=True)
ax1.set_ylim(-2,2)
ax1.set_yticks(np.arange(-2,2,0.5))
ax1.plot(theta,R1,lw=2.5)

Categories