O título da figura do Python Matplotlib sobrepõe o rótulo dos eixos ao usar twiny

139

Estou tentando plotar duas quantidades separadas no mesmo gráfico usando twiny da seguinte maneira:

fig = figure()
ax = fig.add_subplot(111)
ax.plot(T, r, 'b-', T, R, 'r-', T, r_geo, 'g-')
ax.set_yscale('log')
ax.annotate('Approx. sea level', xy=(Planet.T_day*1.3,(Planet.R)/1000), xytext=(Planet.T_day*1.3, Planet.R/1000))
ax.annotate('Geostat. orbit', xy=(Planet.T_day*1.3, r_geo[0]), xytext=(Planet.T_day*1.3, r_geo[0]))
ax.set_xlabel('Rotational period (hrs)')
ax.set_ylabel('Orbital radius (km), logarithmic')
ax.set_title('Orbital charts for ' + Planet.N, horizontalalignment='center', verticalalignment='top')


ax2 = ax.twiny()
ax2.plot(v,r,'k-')
ax2.set_xlabel('Linear speed (ms-1)')

show()

e os dados são apresentados bem, mas estou tendo o problema de o título da figura se sobrepor aos rótulos dos eixos no eixo x secundário, para que fique quase legível (eu queria postar um exemplo de imagem aqui, mas não tenho um representante suficiente o suficiente).

Gostaria de saber se existe uma maneira simples de mudar o título diretamente para cima algumas dezenas de pixels, para que o gráfico pareça mais bonito.

Magic_Matt_Man
fonte
1
Bem-vindo ao Stack Overflow! Se você criar um link para uma postagem imgur da sua foto, um usuário com maior número de representantes incorporará a imagem na sua postagem para você.
Hooked
@ Magic - Você reconsideraria que resposta aceitar para esta pergunta? Matplotlib tenha adicionado um mecanismo incorporado para lidar com esta necessidade exacta (a resposta mais considerados abaixo)
Amelio Vazquez-Reina

Respostas:

243

Não tenho certeza se é um novo recurso nas versões posteriores do matplotlib, mas pelo menos para a 1.3.1, isso é simplesmente:

plt.title(figure_title, y=1.08)

Isso também funciona para plt.suptitle(), mas não (ainda) para plt.xlabel()etc.

herrlich10
fonte
6
Para rótulos, você pode definir o argumento labelpad, veja aqui .
Felix Hoffmann
1
Pelo que vale a pena, não é um novo recurso. titlelevou argumentos xe ypor um longo tempo (desde que me lembro, pelo menos).
31814 Joe Kington
3
plt.set_title ('string do título', y = 1,08) funciona para mim.
Yu Shen
3
Seria mais útil se alguém explicasse o que são as unidades 1.08 e quais são os padrões. O meu entendimento é que o padrão é 1
kon psych
3
@JohnCummings Parece que o valor padrão é y = 1 e as unidades são "fração dos eixos", ou seja, y = 0,5 significa que o título está no meio dos eixos e y = 0 significa que o título está logo acima da parte inferior de os eixos.
precisa
33

Esqueça o uso plt.titlee coloque o texto diretamente com plt.text. Um exemplo exagerado é dado abaixo:

import pylab as plt

fig = plt.figure(figsize=(5,10))

figure_title = "Normal title"
ax1  = plt.subplot(1,2,1)

plt.title(figure_title, fontsize = 20)
plt.plot([1,2,3],[1,4,9])

figure_title = "Raised title"
ax2  = plt.subplot(1,2,2)

plt.text(0.5, 1.08, figure_title,
         horizontalalignment='center',
         fontsize=20,
         transform = ax2.transAxes)
plt.plot([1,2,3],[1,4,9])

plt.show()

insira a descrição da imagem aqui

Hooked
fonte
@ user815423426 sim, tight_layoutainda não parece funcionar bem com canais não padrão. Talvez você possa fazer um relatório de bug?
fácil
2
Encontrei uma solução alternativa ao usar tight_layout, pelo menos quando você salvou seu gráfico usando figure.savefig () . Se title = plt.title(...), em seguida, você pode especificar para enquadrar a trama firmemente em torno do título usando a opção bbox_extra_artists:figure.savefig(filename, bbox_extra_artists=(title), bbox_inches='tight')
junkaholik
10
ax.set_title('My Title\n', fontsize="15", color="red")
plt.imshow(myfile, origin="upper")

Se você colocar '\n'logo após a sequência do título, o gráfico será desenhado logo abaixo do título. Essa pode ser uma solução rápida também.

Efkan
fonte
8

Eu estava tendo um problema com o rótulo x sobrepondo um título de subtrama; isso funcionou para mim:

import matplotlib.pyplot as plt
fig, ax = plt.subplots(2, 1)
ax[0].scatter(...)
ax[1].scatter(...)
plt.tight_layout()
.
.
.
plt.show()

antes

insira a descrição da imagem aqui

depois de

insira a descrição da imagem aqui

referência:

jmunsch
fonte
4

Basta usar plt.tight_layout()antes plt.show(). Isso funciona bem.

Peter Zhu
fonte
4

Você pode usar o pad para este caso:

ax.set_title("whatever", pad=20)
Radvin
fonte