问题
I try to set the line style of matplotlib plot spines, but for some reason, it does not work. I can set them invisible or make them thinner, but I cannot change the line style.
My aim is to present one plot cut up into two to show outliers at the top. I would like to set the respective bottom/top spines to dotted so they clearly show that there is a break.
import numpy as np
import matplotlib.pyplot as plt
# Break ratio of the bottom/top plots respectively
ybreaks = [.25, .9]
figure, (ax1, ax2) = plt.subplots(
nrows=2, ncols=1,
sharex=True, figsize=(22, 10),
gridspec_kw = {'height_ratios':[1 - ybreaks[1], ybreaks[0]]}
)
d = np.random.random(100)
ax1.plot(d)
ax2.plot(d)
# Set the y axis limits
ori_ylim = ax1.get_ylim()
ax1.set_ylim(ori_ylim[1] * ybreaks[1], ori_ylim[1])
ax2.set_ylim(ori_ylim[0], ori_ylim[1] * ybreaks[0])
# Spine formatting
# ax1.spines['bottom'].set_visible(False) # This works
ax1.spines['bottom'].set_linewidth(.25) # This works
ax1.spines['bottom'].set_linestyle('dashed') # This does not work
ax2.spines['top'].set_linestyle('-') # Does not work
ax2.spines['top'].set_linewidth(.25) # Works
plt.subplots_adjust(hspace=0.05)
I would expect the above code to draw the top plot's bottom spine and the bottom plot's top spine dashed.
What do I miss?
回答1:
First one should mention that if you do not change the linewidth, the dashed style shows fine.
ax1.spines['bottom'].set_linestyle("dashed")
However the spacing may be a bit too tight. This is due to the capstyle
being set to "projecting"
for spines by default.
One can hence set the capstyle
to "butt"
instead (which is also the default for normal lines in plots),
ax1.spines['bottom'].set_linestyle('dashed')
ax1.spines['bottom'].set_capstyle("butt")
Or, one can separate the dashes further. E.g.
ax1.spines['bottom'].set_linestyle((0,(4,4)))
Now, if you also set the linewidth so something smaller, then you would need proportionally more spacing. E.g.
ax1.spines['bottom'].set_linewidth(.2)
ax1.spines['bottom'].set_linestyle((0,(16,16)))
Note that the line does not actually become thinner on screen due to the antialiasing in use. It just washes out, such that it becomes lighter in color. So in total it may make sense to keep the lineswidth at some 0.72 points (0.72 points = 1 pixel at 100 dpi) and change the color to light gray instead.
来源:https://stackoverflow.com/questions/54716821/cannot-set-spine-line-style-with-matplotlib