我有这个代码:
rb=0
gb=80
bb=141
color_bar=rgb_to_hex(rb, gb, bb)
rl=237
gl=125
bl=49
color_line=rgb_to_hex(rl, gl, bl)
rbra=255
gbra=255
bbra=255
color_text_table=rgb_to_hex(rbra,gbra,bbra)
#Tamanho da letra e espessura linha 字号=18 线宽=5
#configuração tamanho da imagem plt.rcParams['figure.figsize']=(20,10)
#Alterar cor da frame do gráfico ou outros parametros plt.rc('axes',edgecolor=color_bar, lw=linewidth-2.5)
#Criar Grafico de Barras
width_bar=0.35
lim_sup=grouped\['OID_MEM_ID'\].max()+(grouped\['OID_MEM_ID'\].max()-grouped\['OID_MEM_ID'\].min())\*2
ax = grouped.plot('Mês Ano','OID_MEM_ID',
color=color_bar,
kind ='bar',
fontsize=fontsize+2,
legend=False,
width=width_bar,
ylim=(0,lim_sup))
#Retirar valores y do gráfico ax.axes.yaxis.set_ticklabels([])
我可以做些什么来改进我的解决方案?
我们可以使用
matplotlib
的mcolors
、Polygon
和Bbox
与imshow()
的组合来组合梯度条形图:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
from matplotlib.patches import Polygon
from matplotlib.transforms import Bbox
y = np.random.random(4)*0.01
box_width = 0.15
box_floor = 0
fill_color = [0, 0.5, 1]
alpha = 1.0
ax = plt.subplot(1, 1, 1)
rgb = mcolors.colorConverter.to_rgb(fill_color)
box_color = np.empty((100, 1, 4), dtype=float)
box_color[:, :, :3] = rgb
box_color[:, :, -1] = np.linspace(0, alpha, 100)[:, None]
for _x in range(len(y)):
im = ax.imshow(box_color, aspect='auto', extent=[_x - box_width + 1, _x + box_width + 1, box_floor, y[_x]], origin='lower')
xy = np.vstack([[_x - box_width + 1, box_floor], Bbox.from_bounds(_x - box_width + 1, _x + box_width + 1, box_floor, y[_x]), [_x + box_width + 1, box_floor], [_x - box_width + 1, box_floor]])
clip_path = Polygon(xy, facecolor='none', edgecolor='none', closed=True)
ax.add_patch(clip_path)
im.set_clip_path(clip_path)
ax.set_ylim(0, y.max() + (0.1*y.max()))
ax.set_xlim(-box_width, len(y) + box_width + 1)
plt.show()
输出:
但是,它并没有很好地扩展到十位之外(
0.1
)所以对于更大数字的数据我们必须使用像rescale_y
这样的东西并且还要调整yticklabels
:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
from matplotlib.patches import Polygon
from matplotlib.transforms import Bbox
_y = np.random.random(4)*1000
def rescale_y(y):
new_y = y.copy()
displacement = 0
while max(new_y) > 0.1:
displacement += 1
new_y*=0.1
return new_y, displacement
y, displacement = rescale_y(_y)
box_width = 0.15
box_floor = 0
fill_color = [0, 0.5, 1]
alpha = 1.0
ax = plt.subplot(1, 1, 1)
rgb = mcolors.colorConverter.to_rgb(fill_color)
box_color = np.empty((100, 1, 4), dtype=float)
box_color[:, :, :3] = rgb
box_color[:, :, -1] = np.linspace(0, alpha, 100)[:, None]
for _x in range(len(y)):
im = ax.imshow(box_color, aspect='auto', extent=[_x - box_width + 1, _x + box_width + 1, box_floor, y[_x]], origin='lower')
xy = np.vstack([[_x - box_width + 1, box_floor], Bbox.from_bounds(_x - box_width + 1, _x + box_width + 1, box_floor, y[_x]), [_x + box_width + 1, box_floor], [_x - box_width + 1, box_floor]])
clip_path = Polygon(xy, facecolor='none', edgecolor='none', closed=True)
ax.add_patch(clip_path)
im.set_clip_path(clip_path)
ax.set_ylim(0, y.max() + (0.1*y.max()))
if displacement:
ax.set_yticklabels([str(round(_tick*(10**(displacement)))) for _tick in ax.get_yticks()])
ax.set_xlim(-box_width, len(y) + box_width + 1)
plt.show()
输出:
否则...