Skip to content

[ENH]: Polar Plots. YTicks. Allow placement also on the left side (for negative values) #29026

@A-Infor

Description

@A-Infor

Problem

Limitation description:

  • I'm using a Polar Plot to build a Taylor Diagram, since this type of Diagram is not natively supported;
  • It is not a easy task to adapt the Polar Plot in such a way, but the resulting code is shorter and simpler than object oriented proposed solutions found on the Web;
  • The Polar Plot is limited to 90° when there are only positive values, and have 180° when there are also negative values;
  • The problem arises when setting the ytick labels. They can only be set on the right half of the plot, that is the positive side. I am not able to set them on the left half of the plot, that is the negative side.
  • Instead, I am forced to use ax.text, which does not position the labels correctly vertically. Or the text is placed exactly on the axis, or values get progressively lower on the graph area as they get lower. Both are wrong visually.

Example graph:
imagen

Example code:

import matplotlib.pyplot as plt
import numpy             as np

train_predictions_std_dev = 0.18179760873317719
test_predictions_std_dev  = 0.1591469645500183

## Correlation Coefficient:
train_data_model_corr =  0.9759789999233454
test_data_model_corr  = -0.9616011980701071
### If both values are positive, the left part of the semicircle (negative values) isn't needed:
degrees =  90 if (train_data_model_corr > 0) and (test_data_model_corr > 0) else 180

# Plots the graph: 
std_ref = 1.0                                                           # Reference standard deviation
models_std_dev = [train_predictions_std_dev, test_predictions_std_dev]  # Standard deviations of models
models_corr    = [train_data_model_corr    , test_data_model_corr    ]  # Correlation coefficients of models

## Create an empty Taylor Diagram:
fig, ax = plt.subplots(subplot_kw={'projection': 'polar'})
ax.set_thetalim(thetamin=0, thetamax=degrees) # thetamax = 90° or 180°
ax.set_theta_zero_location('E')               # Set 0 degrees at the right
ax.set_theta_direction(1)                     # Counter-clockwise direction

### X axis (angular):
ax.xaxis.grid     (color='blue' )
correlation_range = np.arange( 0 if degrees == 90 else -1, 1.1, 0.1)  # min. is 0 if 90° or -1 if 180º (max. 1.1 is discarded, real max. is 1)
ax.set_xticks     (np.arccos(correlation_range))                      # Set the ticks at calculated angles (converted by arccos)
ax.set_xticklabels([f'{c:.1f}' for c in correlation_range], color='blue', fontsize=10 if degrees == 90 else 7)  # Use correlation values as labels

### Y axis (radial):
ax.yaxis.grid(color='black')
ax.set_ylim(min(models_std_dev) * 0.8, max(models_std_dev) * 1.2)   # 20% margin

#### Set the y-ticks
yticks = np.arange(0, max(models_std_dev) * 1.2, 0.1)
ax.set_yticks(yticks)

if degrees == 180:
    for tick in yticks:   # Adds the left-side (negative) ticks
        if tick != 0.0: ax.text(np.pi, tick, f'-{tick:.1f}', ha='center', va='center', color='black', fontsize=10) # perfectly aligned horizontally, but need to be a bit lower
    
### Axis labels    :
ax.set_xlabel('Standard Deviation')
ax.xaxis.set_label_coords(0.5, 0.15 if degrees == 180 else -0.1)
if   degrees ==  90: ax.set_ylabel('Standard Deviation', labelpad=4)
if   degrees ==  90: ax.text(np.pi / 4.2, 0.26, 'Pearson Correlation Coefficient', ha='center', va='center', color='blue', rotation=-45)
elif degrees == 180: ax.text(np.pi / 2  , 0.27, 'Pearson Correlation Coefficient', ha='center', va='bottom', color='blue')

ax.set_title('Taylor Diagram')

## Fill in the Taylor Diagram:
ax.plot(np.arccos(models_corr), models_std_dev,  'ro', label='Models'   )
ax.plot(    [0], [std_ref]    ,                  'mo', label='Reference')
plt.legend()

ax.text(np.arccos(train_data_model_corr), train_predictions_std_dev + 0.005, 'train', ha='center', va='bottom')
ax.text(np.arccos(test_data_model_corr ), test_predictions_std_dev  + 0.005, 'test' , ha='center', va='bottom')

fig.tight_layout()
plt.show()

Proposed solution

Allow the Polar Plots to have Y ticks labels on both sides, left and right, not just right like now.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions