问题描述
使用 matplotlib,我想在符号学图上绘制一个椭圆。
考虑下图和相关代码。
import numpy as np
import scipy.io
from matplotlib import pyplot as plt
from matplotlib.patches import Ellipse
plt.figure(figsize=[3.3,3.3])
plt.rcParams.update({'font.size': 8,'text.usetex': True})
plt.semilogy([1,2,3,4],[4,8,12,16],color='r')
plt.semilogy([1,[2,4,6,8],[12,15,20,27],color='b')
ax = plt.gca()
plt.annotate('blue curve',xy=(1.5,22.5),xytext=(1.5,ha='center',va='center')
plt.annotate('',xy=(2,15),22),arrowprops=dict(width=0.1,headwidth=2,headlength=2,color='grey'))
plt.annotate('red curves',xy=(2.5,xytext=(2.5,xy=(3,color='grey'))
ax.add_patch(Ellipse(xy=(3,10),width=0.2,height=10,color="grey",fill=False,lw=1,zorder=5))
plt.grid()
plt.xlabel('x')
plt.ylabel('y')
plt.savefig('filename.pdf',format='pdf')
plt.show()
如您所见,椭圆由于 y 轴上的对数刻度而变形。我试图在自然尺度上重叠一个新轴,我也试图从现有问题(例如 this one)中获得灵感:两种方法都不起作用,因为不幸的是,我对 Python 的了解接近于零.
是否有一种简单的方法可以在不大量修改现有代码的情况下绘制(未变形的)椭圆?
解决方法
answer in the Q&A you linked to 确实为您的问题提供了解决方案。您想使用那里记录的复合转换。我已经修改了你脚本的相关部分来做到这一点。
注意:使用此方法需要进行的一项更改是椭圆的高度以轴坐标(我使用高度为 0.5)而不是像您那样以数据坐标 (height=10
) 给出。可能有一种方法可以通过另一个变换在数据坐标中给出它,但我没有在这里包含它。我还稍微移动了椭圆中心,使其以两条红线为中心。
from matplotlib.transforms import ScaledTranslation
# Ellipse centre coordinates
x,y = 3,8
# use the axis scale tform to figure out how far to translate
ell_offset = ScaledTranslation(x,y,ax.transScale)
# construct the composite tform
ell_tform = ell_offset + ax.transLimits + ax.transAxes
# Create the ellipse centred on the origin,apply the composite tform
ax.add_patch(Ellipse(xy=(0,0),width=0.2,height=0.5,color="grey",fill=False,lw=1,zorder=5,transform=ell_tform))