我想知道,是否有可能偏移径向轴的起点或将其移到图表之外。
这是我希望实现的目标:
这就是我现在所拥有的。
我已阅读有关SO的文档和不同主题,但我找不到任何有用的信息。这是否意味着如果没有在任何地方提及它甚至是不可能的。
提前谢谢。
EDIT(添加了用于创建绘图的代码片段):
ax = fig.add_subplot(111, projection='polar')
ax.set_theta_zero_location('N')
ax.set_theta_direction(-1)
ax.plot(X,lines[li]*yScalingFactor,label=linelabels[li],color=color,linestyle=ls)
答案 0 :(得分:6)
我不确定polar plot
是否可以这样调整。但这是基于the last example given here: Floating Axes的解决方法。
我在代码中包含了解释性注释,如果你复制/粘贴它,它应该按原样运行:
import mpl_toolkits.axisartist.floating_axes as floating_axes
from matplotlib.projections import PolarAxes
from mpl_toolkits.axisartist.grid_finder import FixedLocator, \
MaxNLocator, DictFormatter
import numpy as np
import matplotlib.pyplot as plt
# generate 100 random data points
# order the theta coordinates
# theta between 0 and 2*pi
theta = np.random.rand(100)*2.*np.pi
theta = np.sort(theta)
# "radius" between 0 and a max value of 40,000
# as roughly in your example
# normalize the r coordinates and offset by 1 (will be clear later)
MAX_R = 40000.
radius = np.random.rand(100)*MAX_R
radius = radius/np.max(radius) + 1.
# initialize figure:
fig = plt.figure()
# set up polar axis
tr = PolarAxes.PolarTransform()
# define angle ticks around the circumference:
angle_ticks = [(0, r"$0$"),
(.25*np.pi, r"$\frac{1}{4}\pi$"),
(.5*np.pi, r"$\frac{1}{2}\pi$"),
(.75*np.pi, r"$\frac{3}{4}\pi$"),
(1.*np.pi, r"$\pi$"),
(1.25*np.pi, r"$\frac{5}{4}\pi$"),
(1.5*np.pi, r"$\frac{3}{2}\pi$"),
(1.75*np.pi, r"$\frac{7}{4}\pi$")]
# set up ticks and spacing around the circle
grid_locator1 = FixedLocator([v for v, s in angle_ticks])
tick_formatter1 = DictFormatter(dict(angle_ticks))
# set up grid spacing along the 'radius'
radius_ticks = [(1., '0.0'),
(1.5, '%i' % (MAX_R/2.)),
(2.0, '%i' % (MAX_R))]
grid_locator2 = FixedLocator([v for v, s in radius_ticks])
tick_formatter2 = DictFormatter(dict(radius_ticks))
# set up axis:
# tr: the polar axis setup
# extremes: theta max, theta min, r max, r min
# the grid for the theta axis
# the grid for the r axis
# the tick formatting for the theta axis
# the tick formatting for the r axis
grid_helper = floating_axes.GridHelperCurveLinear(tr,
extremes=(2.*np.pi, 0, 2, 1),
grid_locator1=grid_locator1,
grid_locator2=grid_locator2,
tick_formatter1=tick_formatter1,
tick_formatter2=tick_formatter2)
ax1 = floating_axes.FloatingSubplot(fig, 111, grid_helper=grid_helper)
fig.add_subplot(ax1)
# create a parasite axes whose transData in RA, cz
aux_ax = ax1.get_aux_axes(tr)
aux_ax.patch = ax1.patch # for aux_ax to have a clip path as in ax
ax1.patch.zorder=0.9 # but this has a side effect that the patch is
# drawn twice, and possibly over some other
# artists. So, we decrease the zorder a bit to
# prevent this.
# plot your data:
aux_ax.plot(theta, radius)
plt.show()
这将生成以下图:
您必须调整轴标签以满足您的要求 我缩放了数据,因为否则会出现与您的情节相同的问题 - 内部的空圆圈将被缩放为点。您可以尝试使用极坐标图进行缩放,只需将自定义标签放在径向轴上即可获得类似的效果。
答案 1 :(得分:0)
要偏移径向轴的起点:
编辑:从Matplotlib 2.2.3开始,有一个名为set_rorigin
的新Axes方法可以做到这一点。您用原点的理论径向坐标来称呼它。因此,如果您调用ax.set_ylim(0, 2)
和ax.set_rorigin(-1)
,则中心圆的半径将是绘图半径的三分之一。
Matplotlib <2.2.3的一种快速而肮脏的解决方法是将径向轴下限设置为负值,并将图的内部隐藏在一个圆后面:
import numpy as np
import matplotlib.pyplot as plt
CIRCLE_RES = 36 # resolution of circle inside
def offset_radial_axis(ax):
x_circle = np.linspace(0, 2*np.pi, CIRCLE_RES)
y_circle = np.zeros_like(x_circle)
ax.fill(x_circle, y_circle, fc='white', ec='black', zorder=2) # circle
ax.set_rmin(-1) # needs to be after ax.fill. No idea why.
ax.set_rticks([tick for tick in ax.get_yticks() if tick >= 0])
# or set the ticks manually (simple)
# or define a custom TickLocator (very flexible)
# or leave out this line if the ticks are fully behind the circle
要在图外添加比例,请执行以下操作:
您可以在其他轴的上半部添加一个额外的轴对象,并使用其y轴:
X_OFFSET = 0 # to control how far the scale is from the plot (axes coordinates)
def add_scale(ax):
# add extra axes for the scale
rect = ax.get_position()
rect = (rect.xmin-X_OFFSET, rect.ymin+rect.height/2, # x, y
rect.width, rect.height/2) # width, height
scale_ax = ax.figure.add_axes(rect)
# hide most elements of the new axes
for loc in ['right', 'top', 'bottom']:
scale_ax.spines[loc].set_visible(False)
scale_ax.tick_params(bottom=False, labelbottom=False)
scale_ax.patch.set_visible(False) # hide white background
# adjust the scale
scale_ax.spines['left'].set_bounds(*ax.get_ylim())
# scale_ax.spines['left'].set_bounds(0, ax.get_rmax()) # mpl < 2.2.3
scale_ax.set_yticks(ax.get_yticks())
scale_ax.set_ylim(ax.get_rorigin(), ax.get_rmax())
# scale_ax.set_ylim(ax.get_ylim()) # Matplotlib < 2.2.3
将它们放在一起:
(示例摘自Matplotlib polar plot demo)
r = np.arange(0, 2, 0.01)
theta = 2 * np.pi * r
ax = plt.subplot(111, projection='polar')
ax.plot(theta, r)
ax.grid(True)
ax.set_rorigin(-1)
# offset_radial_axis(ax) # Matplotlib < 2.2.3
add_scale(ax)
ax.set_title("A line plot on an offset polar axis", va='bottom')
plt.show()