圆形对象根据Matplotlib中的图像保存格式更改位置

时间:2018-08-16 05:17:26

标签: python matplotlib plot

我必须在图像的特定位置放置一个圆圈。问题在于,图像以半对数比例绘制,除非我使用某些特定的变换,否则会使圆失真。但是,当我这样做时,圆会根据我将图像另存为A PDF还是PNG来改变位置。这是MWE:

import matplotlib.pyplot as plt
from matplotlib.patches import Ellipse, Circle
import numpy as np
from matplotlib.text import OffsetFrom


fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(11,5), squeeze=False,
    gridspec_kw = {'width_ratios':[3, 1]}, subplot_kw=dict(aspect="auto"))

x=np.logspace(-2,1)
y=np.linspace(.5,0,x.size)

ax=axes[0,0]
ax.semilogx(x, y)
circ = Circle((.5, .5), .1, transform="none", facecolor="none", edgecolor="k")
ax.add_patch(circ)

ax.set(xlim=(1e-2, 1e1), ylim=(0, .6))
fig.savefig("circle.png")

这是两个输出,具体取决于我如何保存图像:

enter image description here enter image description here

我也尝试过使用transform=ax.transAxes,尽管它保留了圆的位置,但在半对数转换后,它不再是圆了。

有什么想法吗?

1 个答案:

答案 0 :(得分:1)

我认为这是known issue。问题在于,pdf总是以dpi为72保存,而png会考虑数字dpi。

但是,我建议不要使用Annotation BBox tools来代替在图形或轴上直接创建一个圆。

您可以创建一个内部带有DrawingArea的AnnotationBBox。 DrawingArea可能包含圆。 DrawingArea的坐标为点。 AnnotationBbox可以放置在轴或图形上的任何位置,并且可以在其他坐标系(例如轴坐标或数据坐标)中指定其位置。

import matplotlib.pyplot as plt
from matplotlib.patches import Ellipse, Circle
import numpy as np
from matplotlib.offsetbox import DrawingArea, AnnotationBbox


fig, axes = plt.subplots(nrows=1, ncols=2, figsize=(11,5), squeeze=False,
    gridspec_kw = {'width_ratios':[3, 1]}, subplot_kw=dict(aspect="auto"))

x=np.logspace(-2,1)
y=np.linspace(.5,0,x.size)

ax=axes[0,0]
ax.semilogx(x, y)

##################
# Axes Coordinates
# Create circle of 10 points radius
da = DrawingArea(1,1, 0, 0)
p = Circle((0, 0), 10)
da.add_artist(p)

# Place box in the middle ((.5,.5)) of the axes.
# Add circle inside drawing area to box
ab = AnnotationBbox(da, (.5,.5), xycoords='axes fraction',
                    box_alignment=(0, 0), frameon=False, pad=0.0)
ax.add_artist(ab)

###################
# Data Coordinates
# Create circle of 10 points radius
da = DrawingArea(1,1, 0, 0)
p = Circle((0, 0), 10, color="crimson")
da.add_artist(p)

# Place box at (0.1,0.3) in data coordinates.
# Add circle inside drawing area to box
ab = AnnotationBbox(da, (0.1,0.3), xycoords='data',
                    box_alignment=(0, 0), frameon=False, pad=0.0)
ax.add_artist(ab)




ax.set(xlim=(1e-2, 1e1), ylim=(0, .6))
fig.savefig("circle.png")
fig.savefig("circle.pdf")
plt.show()

生成的pdf和png现在相同

enter image description here