matplotlib: पूर्ण संख्या या विशिष्ट संख्या के लिए प्रारूप अक्ष ऑफ़सेट-मान


92

मेरे पास एक matplotlib आंकड़ा है जो मैं डेटा को साजिश कर रहा हूं जिसे हमेशा नैनोसेकंड (1e-9) के रूप में संदर्भित किया जाता है। Y- अक्ष पर, यदि मेरे पास डेटा है जो दसियों नैनोसेकंड है, अर्थात। 44e-9, अक्ष पर मान एक ऑफसेट के रूप में + 1e-8 के साथ 4.4 के रूप में दिखाता है। वहाँ वैसे भी अक्ष को + 1e-9 ऑफसेट के साथ 44 दिखाने के लिए मजबूर करने के लिए है?

वही मेरे x- अक्ष के लिए जाता है जहाँ अक्ष + 5.54478e4 दिखा रहा है, जहाँ मैं इसके बजाय +55447 (पूरे संख्या, कोई दशमलव - यहाँ दिनों में मान है) की भरपाई दिखाऊँगा।

मैंने कुछ इस तरह की कोशिश की है:

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

एक्स-एक्सिस के लिए, लेकिन यह काम नहीं करता है, हालांकि मैं शायद इसका गलत तरीके से उपयोग कर रहा हूं या डॉक्स से कुछ गलत कर रहा हूं, क्या कोई मुझे सही दिशा में इंगित कर सकता है?

धन्यवाद, जोनाथन

समस्या चित्रण


मैंने फॉर्मेटर्स के साथ कुछ करने की कोशिश की, लेकिन अभी तक कोई समाधान नहीं मिला है ...:

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)

एक साइड नोट पर, मैं वास्तव में उलझन में हूँ कि 'ऑफ़सेट नंबर' ऑब्जेक्ट वास्तव में कहाँ रहता है ... क्या यह प्रमुख / मामूली टिक्स का हिस्सा है?


1
क्या आपने कोशिश की है set_units? matplotlib.sourceforge.net/api/… (मैं इसे आज़मा नहीं सकता क्योंकि मेरे पास यहाँ
matpllib

1
मैंने set_units फ़ंक्शन की जाँच की और यह आवश्यक से अधिक जटिल लगता है (अतिरिक्त मॉड्यूल को लिखना / जोड़ना है? - --__units?)। टिक के प्रारूप को संपादित करने का एक तरीका होना चाहिए। इकाइयों / set_unit फ़ंक्शन को इकाई रूपांतरण की तर्ज पर अधिक पसंद किया जाता है। टिप के लिए धन्यवाद, हालांकि, मुझे कुछ अन्य समाधानों की ओर ले गया, जो मैं अभी देख रहा हूं!
जोनाथन

1
कृपया rcParamsडिफ़ॉल्ट रूप से बंद करने पर विचार rcParams["axes.formatter.useoffset"] = Falseकरें: यहाँ के रूप में: stackoverflow.com/questions/24171064/…
Ruggero Turra

जवाबों:


100

मेरे पास ठीक यही समस्या थी, और इन लाइनों ने समस्या को ठीक कर दिया:

from matplotlib.ticker import ScalarFormatter

y_formatter = ScalarFormatter(useOffset=False)
ax.yaxis.set_major_formatter(y_formatter)

1
यह त्वरित और आसान उत्तर है। धन्यवाद।
मैक्समम

6
एक-लाइनर होगा:ax.get_yaxis().get_major_formatter().set_useOffset(False)
दातमन

3
मेरे जैसे from matplotlib.ticker import ScalarFormatterनोज के लिए न तो @Gonzalo के कोड को काम करने के लिए भूल जाओ या बस @Dataman के समाधान का उपयोग करें ऊपर
champost

36

एक बहुत आसान उपाय केवल टिक लेबल को अनुकूलित करना है। इस उदाहरण को लें:

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()

वैकल्पिक शब्द

ध्यान दें कि कैसे y- अक्ष मामले में, मैंने उन मानों को गुणा 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)

वैकल्पिक शब्द


यह वही था जो मैंने किया था, पहली बार में। दुर्भाग्य से, मैं अक्ष गुणक को सेट / दिखाने का एक आसान तरीका नहीं खोज सका (स्पष्ट रूप से इसे y- अक्ष लेबल में डालने के अलावा, जैसा आपने किया था।)। यदि आपको ऐक्सिस मल्टीप्लायर लेबल नहीं लगता है, तो यह सरल तरीका है। किसी भी तरह, मुझसे +1।
जो किंगटन

1
@ जो किंगटन: आप इसे मैन्युअल रूप से पाठ के रूप में जोड़ सकते हैं ... ऊपर संपादन देखें :)
अमरो सिप

महान! मैं एक्स-अक्ष के लिए लेबल के साथ आपके दृष्टिकोण की कोशिश करने जा रहा हूं। मैं पहले x मान का फर्श लूंगा, फिर इसे हर x-मान से हटा दूंगा और लेबल के रूप में "+ minxval" जोड़ूंगा। मैं यह पता नहीं लगा सकता कि एक्स-टिक ऑफसेट को कैसे प्रारूपित किया जाए। मैं ऑफ़सेट के परिमाण के साथ ठीक हूं, मुझे इसे गैर-घातीय मान के रूप में प्रदर्शित करने की आवश्यकता है।
जोनाथन

वाह। यह दिखाने में महान काम कि आप वास्तव में कैसे matplotlib का नियंत्रण ले सकते हैं और इसे अपनी आवश्यकताओं और वास्तव में और कुछ प्लज़ाज़ को अपने भूखंडों में बदल सकते हैं।
भौतिक विज्ञान

आप आकृति में 1e-9 का फ़ॉन्ट कैसे बदलते हैं?
एक प्रस्ताव

30

आपको वह करने के लिए उपवर्ग ScalarFormatterकरना होगा जो आपको चाहिए ... _set_offsetबस एक स्थिरांक जोड़ता है, जिसे आप सेट करना चाहते हैं ScalarFormatter.orderOfMagnitude। दुर्भाग्य से, मैन्युअल रूप से सेटिंग orderOfMagnitudeकुछ भी नहीं करेगी, क्योंकि यह तब रीसेट होता है जब 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()

जो कुछ इस तरह देता है: वैकल्पिक शब्द

जबकि, डिफ़ॉल्ट स्वरूपण ऐसा दिखेगा: वैकल्पिक शब्द

उम्मीद है कि इससे थोड़ी मदद मिलेगीं!

संपादित करें: यह किस लिए लायक है, मुझे नहीं पता कि ऑफ़सेट लेबल या तो रहता है ... इसे मैन्युअल रूप से सेट करना थोड़ा आसान होगा, लेकिन मैं यह पता नहीं लगा सका कि यह कैसे करना है ... मुझे लग रहा है कि इस सब से आसान तरीका है। यह काम करता है, हालांकि!


धन्यवाद! ScalarFormatter उप-वर्ग काम करता है महान! लेकिन मुझे लगता है कि मैंने स्पष्ट रूप से यह नहीं बताया कि मैं एक्स-एक्सिस के लिए क्या चाहता था। मैं x- अक्ष के लिए ऑफ़सेट रखना चाहूंगा, लेकिन ऑफ़सेट के मूल्य को प्रारूपित करूँगा ताकि यह एक घातांक के रूप में न दिखाया जाए।
जोनाथन

यह एकमात्र तरीका है जो मेरे लिए काम करता है! धन्यवाद :)
महासागर वैज्ञानिक

11

अमरो के जवाब के समान, आप फंकफॉर्मर का उपयोग कर सकते हैं

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()

5

जोड़े जाने के बाद गोंज़ालो के समाधान ने मेरे लिए काम करना शुरू कर दिया set_scientific(False):

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


4

मुझे लगता है कि टिकर फॉर्मेटर का उपयोग करने के लिए एक और अधिक सुंदर तरीका है। यहाँ 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)

1
यह प्रश्न का उत्तर नहीं देता है, कि ऑफसेट और / या वैज्ञानिक संकेतन में उपयोग किए जाने वाले कारक को कैसे निर्दिष्ट किया जाए
सोडा

@nordev भले ही मेरा जवाब विशेष रूप से उस सवाल का जवाब नहीं देता है जो अभी भी संकेत देता है। संदेश यह है कि आप किसी अन्य फॉर्मेटर को चुन सकते हैं और प्राप्त कर सकते हैं कि आप मेरे उदाहरण से तारीख के बजाय क्या चाहते हैं। वैज्ञानिक दुनिया में जूलियन दिन आदर्श है, या आप मेरे उदाहरण में तारीख का उपयोग कर सकते हैं। मैं जो सुझाव देना चाह रहा था, वह यह है कि एक अलग दृष्टिकोण लिया जा सकता है। कभी-कभी एक प्रश्न पूछा जा सकता है क्योंकि व्यक्ति के पास इस समय बेहतर विचार नहीं है। वैकल्पिक समाधानों को अस्वीकार नहीं किया जाना चाहिए या उनका अनादर नहीं किया जाना चाहिए। सभी में मैं -1 वोट के लायक नहीं था।
बोगदान

2

दूसरे भाग के लिए, सभी टिकों को मैन्युअल रूप से रीसेट किए बिना, यह मेरा समाधान था:

class CustomScalarFormatter(ScalarFormatter):
    def format_data(self, value):
        if self._useLocale:
            s = locale.format_string('%1.2g', (value,))
        else:
            s = '%1.2g' % value
        s = self._formatSciNotation(s)
        return self.fix_minus(s)
xmajorformatter = CustomScalarFormatter()  # default useOffset=True
axes.get_xaxis().set_major_formatter(xmajorformatter)

स्पष्ट रूप से आप प्रारूप स्ट्रिंग को आप जो चाहें कर सकते हैं।


दुर्भाग्य से मैंने जांच नहीं की है कि आपके प्रश्न के पहले भाग के रूप में गुणक कैसे सेट करें।
एस्ट्रोजूनलू
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.