web-dev-qa-db-fra.com

Changer l'échelle de la parcelle d'un facteur dans matplotlib

Je crée une intrigue en python. Existe-t-il un moyen de redimensionner l'axe d'un facteur? Les commandes yscale et xscale me permettent uniquement de désactiver l'échelle du journal.

Modifier:
Par exemple. Si j'ai un tracé où les échelles x vont de 1 nm à 50 nm, l'échelle x variera de 1x10 ^ (- 9) à 50x10 ^ (- 9) et je veux qu'elle change de 1 à 50. Ainsi, je veux que la fonction de tracé divise les valeurs x placées sur le tracé par 10 ^ (- 9)

27
Yotam

Au lieu de changer les ticks, pourquoi ne pas changer les unités à la place? Créez un tableau séparé X de valeurs x dont les unités sont en nm. De cette façon, lorsque vous tracez les données, elles sont déjà au format correct! Assurez-vous simplement d'ajouter un xlabel pour indiquer les unités (qui devraient toujours être faites de toute façon).

from pylab import *

# Generate random test data in your range
N = 200
epsilon = 10**(-9.0)
X = epsilon*(50*random(N) + 1)
Y = random(N)

# X2 now has the "units" of nanometers by scaling X
X2 = (1/epsilon) * X

subplot(121)
scatter(X,Y)
xlim(epsilon,50*epsilon)
xlabel("meters")

subplot(122)
scatter(X2,Y)
xlim(1, 50)
xlabel("nanometers")

show()

enter image description here

12
Hooked

Comme vous l'avez remarqué, xscale et yscale ne prend pas en charge une simple mise à l'échelle linéaire (malheureusement). Comme alternative à la réponse de Hooked, au lieu de jouer avec les données, vous pouvez tromper les étiquettes comme suit:

ticks = ticker.FuncFormatter(lambda x, pos: '{0:g}'.format(x*scale))
ax.xaxis.set_major_formatter(ticks)

Un exemple complet montrant les échelles x et y:

import numpy as np
import pylab as plt
import matplotlib.ticker as ticker

# Generate data
x = np.linspace(0, 1e-9)
y = 1e3*np.sin(2*np.pi*x/1e-9) # one period, 1k amplitude

# setup figures
fig = plt.figure()
ax1 = fig.add_subplot(121)
ax2 = fig.add_subplot(122)
# plot two identical plots
ax1.plot(x, y)
ax2.plot(x, y)

# Change only ax2
scale_x = 1e-9
scale_y = 1e3
ticks_x = ticker.FuncFormatter(lambda x, pos: '{0:g}'.format(x/scale_x))
ax2.xaxis.set_major_formatter(ticks_x)

ticks_y = ticker.FuncFormatter(lambda x, pos: '{0:g}'.format(x/scale_y))
ax2.yaxis.set_major_formatter(ticks_y)

ax1.set_xlabel("meters")
ax1.set_ylabel('volt')
ax2.set_xlabel("nanometers")
ax2.set_ylabel('kilovolt')

plt.show() 

Et enfin j'ai les crédits pour une photo:

Left: ax1 no scaling, right: ax2 y axis scaled to kilo and x axis scaled to nano

Notez que si vous avez text.usetex: true comme je l'ai fait, vous voudrez peut-être mettre les étiquettes entre $, ainsi: '${0:g}$'.

61
oystein

Pour définir la plage de l'axe des x, vous pouvez utiliser set_xlim(left, right), voici les documents

Mise à jour:

Il semble que vous souhaitiez un tracé identique, mais modifiez uniquement les `` valeurs de tick '', vous pouvez le faire en obtenant les valeurs de tick et en les changeant simplement en ce que vous voulez. Donc, pour votre besoin, ce serait comme ceci:

ticks = your_plot.get_xticks()*10**9
your_plot.set_xticklabels(ticks)
5
fraxel