我想自动化我的绘图的外观。我的函数采用从
axes
方法创建的 plt.subplots()
对象。然而,我在自动调整脊柱的大小时遇到了麻烦,因为它似乎变化很大,具体取决于它是条形图、水平条形图、散点图等。
到目前为止,我尝试使用
ax.get_children()
并寻找 Rectangle
来确定它是否是条形图,但我无法确定它是水平条形图还是垂直条形图。
axes
或fig
对象中是否有属性或参数可以帮助确定绘图类型?或者确定情节类型的简单方法?
谢谢!
不是直接的方法,但也许是一种解决方法:
当您将绘图分配给变量时
plot_1 = ax.plot(x, y, linewidth=2.0)
无论如何,绘图都会被绘制出来,并且该变量包含一个列表或matplotlib容器,其中包含有关绘图的一些信息。
根据 matplotlib 绘图类型 HP:
中的 10 个示例打印这些变量
(获取此打印输出的完整代码添加在下面)
plot:
[<matplotlib.lines.Line2D object at 0x000001F00CF91B80>]
scatter:
<matplotlib.collections.PathCollection object at 0x000001F00CF91E50>
bar:
<BarContainer object of 8 artists>
step:
[<matplotlib.lines.Line2D object at 0x000001F00D17B250>]
stem:
<StemContainer object of 3 artists>
hist:
(array([ 6., 9., 32., 47., 53., 37., 10., 6.]), array([0.34774335,
1.2783365 , 2.20892966, 3.13952281, 4.07011596,
5.00070911, 5.93130226, 6.86189541, 7.79248856]), <BarContainer object of 8 artists>)
boxplot:
{'whiskers': [<matplotlib.lines.Line2D object at 0x000001F00D2C3D60>,
<matplotlib.lines.Line2D object at 0x000001F00D2C3EE0>, <matplotlib.lines.Line2D object
at 0x000001F00D2D4D00>, <matplotlib.lines.Line2D object at 0x000001F00D2D4FD0>,
<matplotlib.lines.Line2D object at 0x000001F00D2E2D90>, <matplotlib.lines.Line2D object
at 0x000001F00D2EF0A0>], 'caps': [<matplotlib.lines.Line2D object at 0x000001F00D2D4220>,
<matplotlib.lines.Line2D object at 0x000001F00D2D44F0>, <matplotlib.lines.Line2D object
at 0x000001F00D2E22E0>, <matplotlib.lines.Line2D object at 0x000001F00D2E25B0>,
<matplotlib.lines.Line2D object at 0x000001F00D2EF370>, <matplotlib.lines.Line2D object
at 0x000001F00D2EF640>], 'boxes': [<matplotlib.patches.PathPatch object
at 0x000001F00D2C39A0>, <matplotlib.patches.PathPatch object
at 0x000001F00D2D4970>, <matplotlib.patches.PathPatch object
at 0x000001F00D2E2A30>], 'medians': [<matplotlib.lines.Line2D object
at 0x000001F00D2D47C0>, <matplotlib.lines.Line2D object
at 0x000001F00D2E2880>, <matplotlib.lines.Line2D object
at 0x000001F00D2EF910>], 'fliers': [], 'means': []}
pie:
([<matplotlib.patches.Wedge object at 0x000001F00D3592E0>, <matplotlib.patches.Wedge
object at 0x000001F00D3597C0>, <matplotlib.patches.Wedge object
at 0x000001F00D359CA0>, <matplotlib.patches.Wedge object
at 0x000001F00D3641C0>], [Text(7.138486499000184,
5.019756096129642, ''), Text(5.019756022668064,
7.1384865228692975, ''), Text(0.8615134293924815,
5.019755875744905, ''), Text(5.019756463437526,
0.861513620345407, '')])
contour:
<matplotlib.contour.QuadContourSet object at 0x000001F00D381910>
tricontour:
<matplotlib.tri.tricontour.TriContourSet object at 0x000001F00D205910>
对于大多数绘图类型,您应该能够手动匹配可以分配给类型的单词。
然而,step
和 plot
是无法通过这种方式区分的示例(可能还有其他示例 - 请注意,这不是完整列表)。
对于难以区分的绘图,您还可以手动将信息添加到列表中(对于 matplotlib 容器 - 请参阅例如
print(type(plot_5))
可能需要另一个添加解决方法),例如:
plot_4.insert(0, 'step')
完整代码供参考:
import matplotlib.pyplot as plt
import numpy as np
plt.style.use('_mpl-gallery')
### "plot"
# make data
x = np.linspace(0, 10, 100)
y = 4 + 2 * np.sin(2 * x)
# plot
fig1, ax = plt.subplots()
plot_1 = ax.plot(x, y, linewidth=2.0)
ax.set(xlim=(0, 8), xticks=np.arange(1, 8),
ylim=(0, 8), yticks=np.arange(1, 8))
plt.show()
print(f"plot: {plot_1}")
### "scatter"
# make the data
np.random.seed(3)
x = 4 + np.random.normal(0, 2, 24)
y = 4 + np.random.normal(0, 2, len(x))
# size and color:
sizes = np.random.uniform(15, 80, len(x))
colors = np.random.uniform(15, 80, len(x))
# plot
fig, ax = plt.subplots()
plot_2 = ax.scatter(x, y, s=sizes, c=colors, vmin=0, vmax=100)
ax.set(xlim=(0, 8), xticks=np.arange(1, 8),
ylim=(0, 8), yticks=np.arange(1, 8))
plt.show()
print(f"scatter: {plot_2}")
### "bar"
# make data:
np.random.seed(3)
x = 0.5 + np.arange(8)
y = np.random.uniform(2, 7, len(x))
# plot
fig, ax = plt.subplots()
plot_3 = ax.bar(x, y, width=1, edgecolor="white", linewidth=0.7)
ax.set(xlim=(0, 8), xticks=np.arange(1, 8),
ylim=(0, 8), yticks=np.arange(1, 8))
plt.show()
print(f"bar: {plot_3}")
### "step"
# make data
np.random.seed(3)
x = 0.5 + np.arange(8)
y = np.random.uniform(2, 7, len(x))
# plot
fig, ax = plt.subplots()
plot_4 = ax.step(x, y, linewidth=2.5)
ax.set(xlim=(0, 8), xticks=np.arange(1, 8),
ylim=(0, 8), yticks=np.arange(1, 8))
plt.show()
print(f"step: {plot_4}")
### "stem"
# make data
np.random.seed(3)
x = 0.5 + np.arange(8)
y = np.random.uniform(2, 7, len(x))
# plot
fig, ax = plt.subplots()
plot_5 = ax.stem(x, y)
ax.set(xlim=(0, 8), xticks=np.arange(1, 8),
ylim=(0, 8), yticks=np.arange(1, 8))
plt.show()
print(f"stem: {plot_5}")
### "hist"
# make data
np.random.seed(1)
x = 4 + np.random.normal(0, 1.5, 200)
# plot:
fig, ax = plt.subplots()
plot_6 = ax.hist(x, bins=8, linewidth=0.5, edgecolor="white")
ax.set(xlim=(0, 8), xticks=np.arange(1, 8),
ylim=(0, 56), yticks=np.linspace(0, 56, 9))
plt.show()
print(f"hist: {plot_6}")
### "boxplot"
# make data:
np.random.seed(10)
D = np.random.normal((3, 5, 4), (1.25, 1.00, 1.25), (100, 3))
# plot
fig, ax = plt.subplots()
plot_7 = ax.boxplot(D, positions=[2, 4, 6], widths=1.5, patch_artist=True,
showmeans=False, showfliers=False,
medianprops={"color": "white", "linewidth": 0.5},
boxprops={"facecolor": "C0", "edgecolor": "white",
"linewidth": 0.5},
whiskerprops={"color": "C0", "linewidth": 1.5},
capprops={"color": "C0", "linewidth": 1.5})
ax.set(xlim=(0, 8), xticks=np.arange(1, 8),
ylim=(0, 8), yticks=np.arange(1, 8))
plt.show()
print(f"boxplot: {plot_7}")
### "pie"
# make data
x = [1, 2, 3, 4]
colors = plt.get_cmap('Blues')(np.linspace(0.2, 0.7, len(x)))
# plot
fig, ax = plt.subplots()
plot_8 = ax.pie(x, colors=colors, radius=3, center=(4, 4),
wedgeprops={"linewidth": 1, "edgecolor": "white"}, frame=True)
ax.set(xlim=(0, 8), xticks=np.arange(1, 8),
ylim=(0, 8), yticks=np.arange(1, 8))
plt.show()
print(f"pie: {plot_8}")
### "contuor"
plt.style.use('_mpl-gallery-nogrid')
# make data
X, Y = np.meshgrid(np.linspace(-3, 3, 256), np.linspace(-3, 3, 256))
Z = (1 - X/2 + X**5 + Y**3) * np.exp(-X**2 - Y**2)
levels = np.linspace(np.min(Z), np.max(Z), 7)
# plot
fig, ax = plt.subplots()
plot_9 = ax.contour(X, Y, Z, levels=levels)
plt.show()
print(f"contour:\n {plot_9}")
### "tricontuor"
# make data:
np.random.seed(1)
x = np.random.uniform(-3, 3, 256)
y = np.random.uniform(-3, 3, 256)
z = (1 - x/2 + x**5 + y**3) * np.exp(-x**2 - y**2)
levels = np.linspace(z.min(), z.max(), 7)
# plot:
fig, ax = plt.subplots()
ax.plot(x, y, 'o', markersize=2, color='lightgrey')
plot_10 = ax.tricontour(x, y, z, levels=levels)
ax.set(xlim=(-3, 3), ylim=(-3, 3))
plt.show()
print(f"tricontour:\n {plot_10}")
print(f"plot:\n {plot_1}")
print(f"scatter:\n {plot_2}")
print(f"bar:\n {plot_3}")
print(f"step:\n {plot_4}")
print(f"stem:\n {plot_5}")
print(f"hist:\n {plot_6}")
print(f"boxplot:\n {plot_7}")
print(f"pie:\n {plot_8}")
print(f"contour:\n {plot_9}")
print(f"tricontour:\n {plot_10}")
根据@MagnusO_O的回答,matplotalt的
infer_chart_type
函数使用其属性返回给定matplotlib轴的字符串图表类型。用法示例:
import numpy as np
import matplotlib.pyplot as plt
from matplotalt import infer_chart_type
# Contour example
X, Y = np.meshgrid(np.linspace(-3, 3, 256), np.linspace(-3, 3, 256))
Z = (1 - X/2 + X**5 + Y**3) * np.exp(-X**2 - Y**2)
levels = np.linspace(np.min(Z), np.max(Z), 7)
fig, ax = plt.subplots()
ax.contour(X, Y, Z, levels=levels)
# infer_chart_type should be called before plt.show()
print(infer_chart_type(ax))
plt.show()
# Line example
x = np.linspace(0, 10, 100)
y = 4 + 2 * np.sin(2 * x)
plt.plot(x, y, linewidth=2.0)
# infer_chart_type will use the first axis in plt.gca() if none is given
print(infer_chart_type())
plt.show()
就像@MagnusO_O提到的,有时无法区分图表类型。例如,对于使用
infer_chart_type
生成的图,sns.stripplot
将返回“分散”。
当前支持的图表类型有:
["line", "bar", "scatter", "heatmap", "boxplot", "pie", "contour", "other"]
。这是一个正在进行的项目,因此如果您有任何反馈或功能请求,请告诉我!