pythonmatplotlibpolar-plot

Adjust Matplotlib Polar Plot to Show Sub Degree Motion (AKA Stretch a polar plot() slice)


I have RA and DEC pointing data I would like to show on a polar plot (converting to rho and theta). The theta motion is very small, ~0.01 degrees. This is not easily seen on a full polar plot so I am trying to 'zoom in' to the region and show the change from data point to data point. When I adjust the thetamin/thetamax below to the limits I would prefer the wedge becomes a very thin line that losses all useful information.

I would like a wedge shape like below but where the min/max theta angle shown is at least a degree.

    import numpy as np

    import matplotlib.pyplot as plt

    import matplotlib

    import pandas as pd

    print('matplotlib version : ', matplotlib.__version__)

    fig = plt.figure()

    

    ra = np.asarray([1.67484,1.67485,1.67485,1.67486,1.67486,1.67488,1.67487,1.67488,1.67487, 1.67487]) #radians

    dec = np.asarray([-0.92147,-0.92147,-0.92147,-0.92147,-0.92147,-0.92147,-0.92147, -0.92147,-0.92147, -0.92147]) #radians

    rho = np.sqrt(ra**2 + dec**2) # get rho from ra and dec
    theta = np.arctan2(dec,ra) # get theta from ra and dec

    fig = plt.figure()
    ax = fig.add_subplot(1,1,1,polar=True)
    ax.plot(theta, rho,'*-',color='y')
    ax.set_ylim(1.9114,1.9117) # limits of rho

    ax.set_thetamin(310)
    ax.set_thetamax(340)

    plt.show()

enter image description here

I've been reading online and looking at the matplotlib polar plot documentation but the examples I've found don't go beyond what I've implemented so far..


Solution

  • First of all, you still have some potential concerning narrowing down the plotted radial range, e.g., to ax.set_ylim(1.91159, 1.91164). Please also note, that when I was searching for a solution (which I couldn't fin on the internet either), I found that using np.arctan2() is the appropriate approach for polar coordinates, that is the reason why I changed this part in your code.

    Otherwise, I had no better idea than applying a scaling approach to your plot. Now the wedge in question is scaled up by an arbitrary scaling factor (i.e., theta for the upscaled plot in degrees), as in:

    import numpy as np
    import matplotlib.pyplot as plt
    
    
    ra = np.asarray([1.67484, 1.67485, 1.67485, 1.67486, 1.67486, 
                     1.67488, 1.67487, 1.67488, 1.67487, 1.67487]) 
    
    dec = np.asarray([-0.92147, -0.92147, -0.92147, -0.92147, -0.92147, 
                      -0.92147, -0.92147, -0.92147, -0.92147, -0.92147]) 
    
    
    rho = np.sqrt(ra**2 + dec**2) 
    theta = np.arctan2(dec, ra)  # instead of np.tan(dec / ra), see the other answer.
    
    
    # set scaling factor
    scalingfactor = 40
    
    # scaling up by arbitrary scaling factor
    theta_scaled = (theta - np.min(theta)) / (np.max(theta) - np.min(theta)) * np.radians(scalingfactor)
    
    
    fig, ax = plt.subplots(figsize=(6, 6), subplot_kw={'projection': 'polar'})
    
    ax.plot(theta_scaled, rho, '*-', color='y', label=f"Scaled 1:{1/scalingfactor}")
    ax.set_ylim(1.91159, 1.91164)
    
    #check theta limits
    print(np.degrees(min(theta)), np.degrees(max(theta)))
    
    #creating theta ticks
    ticks = np.radians(np.linspace(0, scalingfactor, 5)) 
    ax.set_xticks(ticks) 
    
    # setting theta labels explicitly
    scaled_labels = np.round(np.linspace(360+np.degrees(min(theta)), 360+np.degrees(max(theta)), len(ticks)), 4)
    ax.set_xticklabels(scaled_labels) 
    
    ax.set_thetamin(-3)  
    ax.set_thetamax(scalingfactor+1)  
    
    ax.grid(True, linestyle="--", alpha=0.5)
    ax.legend()
    
    plt.show()
    

    I am sure you can still make it look prettier, otherwise, it looks to be a solid solution to me, resulting in for example this version of the plot: enter image description here