问题
I've adapted this sample: Matplotlib: Polar plot axis tick label location. I want to add tick marks next to the tick labels (A, B, C, D and E) along the thetagrid from the center of the polar axis to the thetagrid labels. Also, I want a round circle ending each line, directly below the thetagrid titles (TG01, TG02, etc.). You will see these tick labels and thetagrid titles in my code sample. Visually, here's part of line TG01 to demonstrate what I'm looking for:
Here's my current code:
import numpy as np
import matplotlib.pyplot as plt
class Radar(object):
def __init__(self, fig, titles, label, rect=None):
if rect is None:
rect = [0.05, 0.15, 0.95, 0.75]
self.n = len(titles)
self.angles = [a if a <=360. else a - 360. for a in np.arange(90, 90+360, 360.0/self.n)]
self.axes = [fig.add_axes(rect, projection="polar", label="axes%d" % i)
for i in range(self.n)]
self.ax = self.axes[0]
# Show the labels
self.ax.set_thetagrids(self.angles, labels=titles, fontsize=14, weight="bold", color="black")
for ax in self.axes[1:]:
ax.patch.set_visible(False)
ax.grid(False)
ax.xaxis.set_visible(False)
self.ax.yaxis.grid(False)
for ax, angle in zip(self.axes, self.angles):
ax.set_rgrids(range(1, 6), labels=label, angle=angle, fontsize=12)
# hide outer spine (circle)
ax.spines["polar"].set_visible(False)
ax.set_ylim(0, 6)
ax.xaxis.grid(True, color='black', linestyle='-')
def plot(self, values, *args, **kw):
angle = np.deg2rad(np.r_[self.angles, self.angles[0]])
values = np.r_[values, values[0]]
self.ax.plot(angle, values, *args, **kw)
fig = plt.figure(1)
titles = ['TG01', 'TG02', 'TG03', 'TG04', 'TG05', 'TG06']
label = list("ABCDE")
radar = Radar(fig, titles, label)
radar.plot([3.75, 3.25, 3.0, 2.75, 4.25, 3.5], "-", linewidth=2, color="b", alpha=.7, label="Data01")
radar.plot([3.25, 2.25, 2.25, 2.25, 1.5, 1.75],"-", linewidth=2, color="r", alpha=.7, label="Data02")
radar.ax.legend(loc='upper center', bbox_to_anchor=(0.5, -0.10),
fancybox=True, shadow=True, ncol=4)
plt.show()
And how the polar plot currently looks:
I took a close look at the ThetaTick objects retrieved with ax.xaxis.majorTicks. However, nothing I changed in the properties of a ThetaTick object changed the lines in the way I would like them to render.
回答1:
I was able to get most of what I wanted by configuring the axes tick params for the y axis:
ax.tick_params(axis='y', pad=0, left=True, length=6, width=1, direction='inout')
and the marker decorations below the theta tick labels with the decorate_ticks function (as shown in the code and the result). However, it appears the center marker is always the color and style of the last theta grid marker. I've noted this in a comment inside of the decorate_ticks function. If you know of a way to style the center marker differently, please let me know how.
import numpy as np
import matplotlib.pyplot as plt
class Radar(object):
def __init__(self, fig, titles, label, rect=None):
if rect is None:
rect = [0.05, 0.15, 0.95, 0.75]
self.n = len(titles)
self.angles = [a if a <=360. else a - 360. for a in np.arange(90, 90+360, 360.0/self.n)]
self.axes = [fig.add_axes(rect, projection="polar", label="axes%d" % i)
for i in range(self.n)]
self.ax = self.axes[0]
# Show the labels
self.ax.set_thetagrids(self.angles, labels=titles, fontsize=14, weight="bold", color="black")
for ax in self.axes[1:]:
ax.patch.set_visible(False)
ax.grid(False)
ax.xaxis.set_visible(False)
self.ax.yaxis.grid(False)
for ax, angle in zip(self.axes, self.angles):
ax.set_rgrids(range(1, 6), labels=label, angle=angle, fontsize=12)
# hide outer spine (circle)
ax.spines["polar"].set_visible(False)
ax.set_ylim(0, 6)
ax.xaxis.grid(True, color='black', linestyle='-')
# draw a line on the y axis at each label
ax.tick_params(axis='y', pad=0, left=True, length=6, width=1, direction='inout')
def decorate_ticks(self, axes):
for idx, tick in enumerate(axes.xaxis.majorTicks):
# print(idx, tick.label._text)
# get the gridline
gl = tick.gridline
gl.set_marker('o')
gl.set_markersize(15)
if idx == 0:
gl.set_markerfacecolor('b')
elif idx == 1:
gl.set_markerfacecolor('c')
elif idx == 2:
gl.set_markerfacecolor('g')
elif idx == 3:
gl.set_markerfacecolor('y')
elif idx == 4:
gl.set_markerfacecolor('r')
# this doesn't get used. The center doesn't seem to be different than 5
else:
gl.set_markerfacecolor('black')
if idx == 0 or idx == 3:
tick.set_pad(10)
else:
tick.set_pad(30)
def plot(self, values, *args, **kw):
angle = np.deg2rad(np.r_[self.angles, self.angles[0]])
values = np.r_[values, values[0]]
self.ax.plot(angle, values, *args, **kw)
fig = plt.figure(1)
titles = ['TG01', 'TG02', 'TG03', 'TG04', 'TG05', 'TG06']
label = list("ABCDE")
radar = Radar(fig, titles, label)
radar.plot([3.75, 3.25, 3.0, 2.75, 4.25, 3.5], "-", linewidth=2, color="b", alpha=.7, label="Data01")
radar.plot([3.25, 2.25, 2.25, 2.25, 1.5, 1.75],"-", linewidth=2, color="r", alpha=.7, label="Data02")
radar.decorate_ticks(radar.ax)
# this avoids clipping the markers below the thetagrid labels
radar.ax.xaxis.grid(clip_on = False)
radar.ax.legend(loc='upper center', bbox_to_anchor=(0.5, -0.10),
fancybox=True, shadow=True, ncol=4)
plt.show()
and the result:
来源:https://stackoverflow.com/questions/50704932/adding-tick-marks-on-thetagrid-lines-of-a-polar-plot