[英]How to shift axis labels, shift subplots and modify axis scaling in matplotlib
I am trying to make a plot like this我正在尝试像这样制作 plot
using matplotlib.使用 matplotlib。
Currently I have this plot:目前我有这个 plot:
which was generated using this code:这是使用此代码生成的:
import matplotlib.pyplot as plt
import matplotlib as mpl
import pandas as pd
width = 0.4
mpl.rcParams.update({'font.size':15})
mpl.rcParams.update({'legend.columnspacing':0.5})
##############################################################
# BEGIN: Prepare data #
##############################################################
energy_cm = 1550835.86856494
energy_fm = 1456129.29966378
energy_cm_trad = 1393026.50949191
energy_fm_trad = 1314814.95236864
energy_cm_hw = 1200000
energy_fm_hw = 1100000
data_energy = { 'Algorithm' : ['Algorithm 1', 'Algorithm 2'],
'SW' : [energy_cm, energy_fm],
'HW' : [energy_cm_hw, energy_fm_hw],
'Trad' : [energy_cm_trad, energy_fm_trad]
}
df_energy = pd.DataFrame(data_energy)
##############################################################
# END: Prepare data #
##############################################################
##############################################################
# BEGIN: Split the bars into two halves #
##############################################################
fig, (ax, ax2) = plt.subplots(2, 1, sharex=True)
df_energy[['Algorithm', 'SW', 'Trad',
'HW']].set_index('Algorithm').plot(kind='bar', legend=True,
width=width, rot=0,
ax=ax,
color=('sandybrown','rosybrown',
'goldenrod','indianred','tomato','r'))
df_energy[['Algorithm', 'SW', 'Trad',
'HW']].set_index('Algorithm').plot(kind='bar',
legend=False,
width=width, rot=0,
ax=ax2,
color=('sandybrown','rosybrown',
'goldenrod','indianred','tomato','r'))
max_lengths = sorted(df_energy.max(axis=0).values[1:])
min_lengths = sorted(df_energy.min(axis=0).values[1:])
# zoom-in / limit the view to different portions of the data
ax.set_ylim(max_lengths[-2] * 0.8, max_lengths[-1] * 1.1) # outliers only
ax2.set_ylim(0, min_lengths[0] * 1.1) # most of the data
# hide the spines between ax and ax2
ax.spines['bottom'].set_visible(False)
ax2.spines['top'].set_visible(False)
ax.xaxis.tick_top()
ax.tick_params(labeltop='off') # don't put tick labels at the top
ax2.xaxis.tick_bottom()
d = .01 # how big to make the diagonal lines in axes coordinates
# arguments to pass to plot, just so we don't keep repeating them
kwargs = dict(transform=ax.transAxes, color='k', clip_on=False)
ax.plot((-d, +d), (-d, +d), **kwargs) # top-left diagonal
ax.plot((1 - d, 1 + d), (-d, +d), **kwargs) # top-right diagonal
kwargs.update(transform=ax2.transAxes) # switch to the bottom axes
ax2.plot((-d, +d), (1 - d, 1 + d), **kwargs) # bottom-left diagonal
ax2.plot((1 - d, 1 + d), (1 - d, 1 + d), **kwargs) # bottom-right diagonal
##############################################################
# END: Split the bars into two halves #
##############################################################
##############################################################
# BEGIN: Labels #
##############################################################
# Remove X lables from the upper half of the plot
ax.tick_params(
axis='x', # changes apply to the x-axis
which='both', # both major and minor ticks are affected
bottom=False, # ticks along the bottom edge are off
top=False, # ticks along the top edge are off
labeltop=False,
labelbottom=False) # labels along the bottom edge are off
ax.set_ylabel('Energy in nJ')
ax.set_xlabel("")
ax2.set_xlabel("")
##############################################################
# END: Labels #
##############################################################
##############################################################
# BEGIN: Scaling #
##############################################################
mf = mpl.ticker.ScalarFormatter(useMathText=True)
mf.set_powerlimits((-2,2))
ax.yaxis.set_major_formatter(mf)
ax2.yaxis.set_major_formatter(mf)
##############################################################
# END: Scaling #
##############################################################
fig.tight_layout()
plt.show()
I am following matplotlibsexample code for the broken axis and I am using code from the answer to my previous question in order to scale the numbers on the y-axis.我正在关注断轴的 matplotlibs示例代码,并且我正在使用上一个问题的答案中的代码来缩放 y 轴上的数字。
I would like to:我想:
Thus the result would look like the fist image in this question.因此,结果看起来就像这个问题中的第一个图像。
How can I achieve these three things?我怎样才能实现这三件事? Any help is appreciated, even if it doesn't solve all three problems...任何帮助表示赞赏,即使它不能解决所有三个问题......
fig.subplots_adjust()
to change the spacing between the two axes.使用fig.subplots_adjust()
更改两个轴之间的间距。ylabel
with fig.text()
to center the label vertically in the figure我用fig.text()
替换了ylabel
以使 label 在图中垂直居中ax2.yaxis.get_offset_text().set_visible(False)
to hide the exponent on the bottom axis.使用ax2.yaxis.get_offset_text().set_visible(False)
隐藏底轴上的指数。Note that the limits of your axes are poorly chosen as the top of the HW bar in the "Count Min" category is visible in both the bottom and top axes.请注意,您的轴的限制选择不当,因为“计数最小值”类别中的硬件栏顶部在底部和顶部轴中都可见。
complete code:完整代码:
import matplotlib.pyplot as plt
import matplotlib as mpl
import pandas as pd
width = 0.4
mpl.rcParams.update({'font.size':15})
mpl.rcParams.update({'legend.columnspacing':0.5})
# BEGIN: Prepare data
energy_cm = 1550835.86856494
energy_fm = 1456129.29966378
energy_cm_trad = 1393026.50949191
energy_fm_trad = 1314814.95236864
energy_cm_hw = 1200000
energy_fm_hw = 1100000
data_energy = { 'Algorithm' : ['Algorithm 1', 'Algorithm 2'],
'SW' : [energy_cm, energy_fm],
'HW' : [energy_cm_hw, energy_fm_hw],
'Trad' : [energy_cm_trad, energy_fm_trad]
}
df_energy = pd.DataFrame(data_energy)
# BEGIN: Split the bars into two halves
fig, (ax, ax2) = plt.subplots(2, 1, sharex=True)
kw = dict(width=width, rot=0,
color=('sandybrown','rosybrown','goldenrod','indianred','tomato','r'))
df_energy[['Algorithm', 'SW', 'Trad',
'HW']].set_index('Algorithm').plot(kind='bar', legend=True, ax=ax, **kw)
df_energy[['Algorithm', 'SW', 'Trad',
'HW']].set_index('Algorithm').plot(kind='bar', legend=False, ax=ax2, **kw)
max_lengths = sorted(df_energy.max(axis=0).values[1:])
min_lengths = sorted(df_energy.min(axis=0).values[1:])
# zoom-in / limit the view to different portions of the data
ax.set_ylim(max_lengths[-2] * 0.8, max_lengths[-1] * 1.1) # outliers only
ax2.set_ylim(0, min_lengths[0] * 1.1) # most of the data
# hide the spines between ax and ax2
ax.spines['bottom'].set_visible(False)
ax2.spines['top'].set_visible(False)
ax.xaxis.tick_top()
ax.tick_params(labeltop='off') # don't put tick labels at the top
ax2.xaxis.tick_bottom()
d = .01 # how big to make the diagonal lines in axes coordinates
# arguments to pass to plot, just so we don't keep repeating them
kwargs = dict(transform=ax.transAxes, color='k', clip_on=False)
ax.plot((-d, +d), (-d, +d), **kwargs) # top-left diagonal
ax.plot((1 - d, 1 + d), (-d, +d), **kwargs) # top-right diagonal
kwargs.update(transform=ax2.transAxes) # switch to the bottom axes
ax2.plot((-d, +d), (1 - d, 1 + d), **kwargs) # bottom-left diagonal
ax2.plot((1 - d, 1 + d), (1 - d, 1 + d), **kwargs) # bottom-right diagonal
# BEGIN: Labels
# Remove X lables from the upper half of the plot
ax.tick_params(
axis='x', # changes apply to the x-axis
which='both', # both major and minor ticks are affected
bottom=False, # ticks along the bottom edge are off
top=False, # ticks along the top edge are off
labeltop=False,
labelbottom=False) # labels along the bottom edge are off
fig.text(0,0.5,'Energy in nJ', rotation=90, va='center', ha='left')
ax.set_xlabel("")
ax2.set_xlabel("")
# BEGIN: Scaling
ax.ticklabel_format(style='sci', axis='y', useOffset=True, scilimits=(0,0))
ax2.ticklabel_format(style='sci', axis='y', useOffset=True, scilimits=(0,0))
ax2.yaxis.get_offset_text().set_visible(False)
fig.tight_layout()
fig.subplots_adjust(hspace=0.05)
plt.show()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.