python - tutorial - matplotlib شرح




matplotlib: تخالف قيم محور التنسيق مع الأعداد الصحيحة أو عدد محدد (6)

لدي شخصية matplotlib التي أخطط البيانات التي يشار إليها دائما باسم nanoseconds (1E-9). على y-axis ، إذا كان لدي بيانات بعشرات nanoseconds ، أي. 44e-9 ، تظهر القيمة على المحور كـ 4.4 مع a + 1e-8 كإزاحة. هل هناك على أي حال لإجبار المحور على إظهار 44 بإزاحة + 1e -9؟

وينطبق نفس الشيء على المحور السيني حيث يظهر المحور + 5.54478e4 ، حيث أفضّل إظهار إزاحة +55447 (العدد الكامل ، لا يوجد عشري - القيمة هنا بالأيام).

لقد جربت شيئين مثل هذا:

p = axes.plot(x,y)
p.ticklabel_format(style='plain')

بالنسبة للمحور x ، ولكن هذا لا يعمل ، على الرغم من أنني ربما أستخدمه بشكل غير صحيح أو أسيء تفسير شيء ما من المستندات ، فهل يمكن لشخص أن يشير لي في الاتجاه الصحيح؟

شكرا ، جوناثان

حاولت القيام بشيء ما باستخدام التنسيقين ولم أجد أي حل بعد ...:

myyfmt = ScalarFormatter(useOffset=True)
myyfmt._set_offset(1e9)
axes.get_yaxis().set_major_formatter(myyfmt)

و

myxfmt = ScalarFormatter(useOffset=True)
myxfmt.set_portlimits((-9,5))
axes.get_xaxis().set_major_formatter(myxfmt)

في ملاحظة جانبية ، أنا في حيرة من أمري بالنسبة إلى المكان الذي يوجد فيه بالفعل كائن 'offset number' ... هل هو جزء من القراد الرئيسي / الصغير؟


أعتقد أن الطريقة الأكثر أناقة هي استخدام مُنسق شريط المؤشرات. هنا مثال لكل من xaxis و yaxis:

from pylab import *
from matplotlib.ticker import MultipleLocator, FormatStrFormatter

majorLocator   = MultipleLocator(20)
xFormatter = FormatStrFormatter('%d')
yFormatter = FormatStrFormatter('%.2f')
minorLocator   = MultipleLocator(5)


t = arange(0.0, 100.0, 0.1)
s = sin(0.1*pi*t)*exp(-t*0.01)

ax = subplot(111)
plot(t,s)

ax.xaxis.set_major_locator(majorLocator)
ax.xaxis.set_major_formatter(xFormatter)
ax.yaxis.set_major_formatter(yFormatter)

#for the minor ticks, use no labels; default NullFormatter
ax.xaxis.set_minor_locator(minorLocator)

الحل أسهل بكثير هو ببساطة تخصيص علامات التجزئة. خذ هذا المثال:

from pylab import *

# Generate some random data...
x = linspace(55478, 55486, 100)
y = random(100) - 0.5
y = cumsum(y)
y -= y.min()
y *= 1e-8

# plot
plot(x,y)

# xticks
locs,labels = xticks()
xticks(locs, map(lambda x: "%g" % x, locs))

# ytikcs
locs,labels = yticks()
yticks(locs, map(lambda x: "%.1f" % x, locs*1e9))
ylabel('microseconds (1E-9)')

show()

لاحظ كيف في حالة المحور الصادي ، ضاعفت القيم بـ 1e9 ثم ذكرت ذلك الثابت في العلامة y

تصحيح

خيار آخر هو تزييف مضاعف الأس بإضافة نصه يدويًا إلى قمة الرسم:

locs,labels = yticks()
yticks(locs, map(lambda x: "%.1f" % x, locs*1e9))
text(0.0, 1.01, '1e-9', fontsize=10, transform = gca().transAxes)

EDIT2

كما يمكنك تنسيق قيمة إزاحة المحور السيني بنفس الطريقة:

locs,labels = xticks()
xticks(locs, map(lambda x: "%g" % x, locs-min(locs)))
text(0.92, -0.07, "+%g" % min(locs), fontsize=10, transform = gca().transAxes)


بدأ حل غونزالو العمل بالنسبة لي بعد إضافة set_scientific(False) :

ax=gca()
fmt=matplotlib.ticker.ScalarFormatter(useOffset=False)
fmt.set_scientific(False)
ax.xaxis.set_major_formatter(fmt)

على غرار إجابة عمرو ، يمكنك استخدام FuncFormatter

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import FuncFormatter

# Generate some random data...
x = np.linspace(55478, 55486, 100) 
y = np.random.random(100) - 0.5
y = np.cumsum(y)
y -= y.min()
y *= 1e-8

# Plot the data...
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(x, y, 'b-')

# Force the y-axis ticks to use 1e-9 as a base exponent 
ax.yaxis.set_major_formatter(FuncFormatter(lambda x, pos: ('%.1f')%(x*1e9)))
ax.set_ylabel('microseconds (1E-9)')

# Make the x-axis ticks formatted to 0 decimal places
ax.xaxis.set_major_formatter(FuncFormatter(lambda x, pos: '%.0f'%x))
plt.show()

وكما تم الإشارة إليه في التعليقات وفي هذا الجواب ، قد يتم إزاحة الإزاحة عالميًا ، عن طريق القيام بما يلي:

matplotlib.rcParams['axes.formatter.useoffset'] = False

يجب عليك فئة فرعية ScalarFormatter للقيام بما تحتاجه ... _set_offset يضيف فقط ثابت ، تريد تعيين ScalarFormatter.orderOfMagnitude . لسوء الحظ ، لن orderOfMagnitude تعيين orderOfMagnitude يدويًا إلى القيام بأي شيء ، لأنه يتم إعادة تعيينه عند ScalarFormatter مثيل ScalarFormatter لتنسيق تسميات علامات المحور. لا ينبغي أن يكون الأمر معقدًا ، لكن لا يمكنني العثور على طريقة أسهل للقيام بما تريده بالضبط ... وإليك مثالاً:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.ticker import ScalarFormatter, FormatStrFormatter

class FixedOrderFormatter(ScalarFormatter):
    """Formats axis ticks using scientific notation with a constant order of 
    magnitude"""
    def __init__(self, order_of_mag=0, useOffset=True, useMathText=False):
        self._order_of_mag = order_of_mag
        ScalarFormatter.__init__(self, useOffset=useOffset, 
                                 useMathText=useMathText)
    def _set_orderOfMagnitude(self, range):
        """Over-riding this to avoid having orderOfMagnitude reset elsewhere"""
        self.orderOfMagnitude = self._order_of_mag

# Generate some random data...
x = np.linspace(55478, 55486, 100) 
y = np.random.random(100) - 0.5
y = np.cumsum(y)
y -= y.min()
y *= 1e-8

# Plot the data...
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(x, y, 'b-')

# Force the y-axis ticks to use 1e-9 as a base exponent 
ax.yaxis.set_major_formatter(FixedOrderFormatter(-9))

# Make the x-axis ticks formatted to 0 decimal places
ax.xaxis.set_major_formatter(FormatStrFormatter('%0.0f'))
plt.show()

التي تنتج شيء مثل:

بينما ، سيبدو التنسيق الافتراضي كما يلي:

نأمل أن يساعد قليلا!

تعديل: نظرًا لما يستحق ، لا أعرف أين تقع علامة الإزاحة إما ... سيكون من الأسهل قليلاً تعيينها يدويًا ، ولكن لم أتمكن من معرفة كيفية القيام بذلك ... أحصل على الشعور أنه يجب أن تكون هناك طريقة أسهل من كل هذا. يعمل ، على الرغم من!





matplotlib