简体   繁体   中英

How do I define the range of the Y-Axis in MatPlotLib?

I have read countless posts on stackoverflow suggesting to use plt.ylim(low,high) to define the desired range.

I also tried plt.axis([x_low, x_high, y_low, y_high]) . But it none of them work for me.

I am trying to plot voltage over time. I have 530 values that I want to plot, which I have stored in a list. The changes between the values are very little.

The data is in the range [4198, 4199]

I want to see a flat, horizontal line. Instead, I see a badly scaled plot where the line-graph ends up looking like a bar graph, highlighting the smallest changes, like this:

enter image description here

Here is the code that I have:

start = findStart(lines)
end = findEnd(lines, start)
q = enqueueVoltages(start, end)
x = range(len(q))
plt.plot(x, q)
#plt.axis([0,550,3000,4200])
plt.ylabel('Voltage (mV)')
plt.xlabel('Time (s)')
plt.show()

When I try it with the lines defining the desired axes ranges, I get this image: enter image description here

For reference, here is the whole script I am running (with the function definitions):

def findStart(lines):
    count = 0
    for line in lines:
        count += 1
        if(line.rfind('***') > -1):
            start = count
            break
    
    return start

def findEnd(lines, start):
    count = 0
    for line in lines[start:]:
        count += 1
        if(line.rfind('***') > -1):
            end = count + start
            break
    
    return end

def enqueueVoltages(lines, start, end):
    q = []
    counter=0
    for i in range(start+1, end-1):
        beg = lines[i].find('\t\t')
        voltage = lines[i][beg+2:beg+6]
        counter += 1
        q.append(voltage)
        print(voltage)

    return q


f = open(data_path, 'r')
lines = f.readlines()

start = findStart(lines)
end = findEnd(lines, start)
q = enqueueVoltages(lines, start, end)
x = range(len(q))
plt.plot(x, q)
plt.ylim([3000,4200])
plt.gca().invert_yaxis()

plt.ylabel('Voltage (mV)')
plt.xlabel('Time (s)')
plt.show()


print("Starting:\t{}\nEnding:\t\t{}\n".format(start, end))

f.close()

Here is the sample data I am processing (.txt file):

Start time: Wed Sep 14 15:05:14 2022        

***
Wed Sep 14 15:05:16 2022        4199
Wed Sep 14 15:05:17 2022        4199
Wed Sep 14 15:05:18 2022        4199
Wed Sep 14 15:05:20 2022        4199
Wed Sep 14 15:05:21 2022        4199
Wed Sep 14 15:05:22 2022        4199
Wed Sep 14 15:05:23 2022        4199
Wed Sep 14 15:05:24 2022        4199
Wed Sep 14 15:05:25 2022        4199
Wed Sep 14 15:05:26 2022        4199
Wed Sep 14 15:05:27 2022        4199
Wed Sep 14 15:05:29 2022        4199
Wed Sep 14 15:05:30 2022        4199
Wed Sep 14 15:05:31 2022        4199
Wed Sep 14 15:05:32 2022        4199
Wed Sep 14 15:05:33 2022        4199
Wed Sep 14 15:05:34 2022        4199
Wed Sep 14 15:05:35 2022        4199
Wed Sep 14 15:05:36 2022        4199
Wed Sep 14 15:05:38 2022        4199
Wed Sep 14 15:05:39 2022        4199
Wed Sep 14 15:05:40 2022        4199
Wed Sep 14 15:05:41 2022        4199
Wed Sep 14 15:05:42 2022        4199
Wed Sep 14 15:05:43 2022        4199
Wed Sep 14 15:05:44 2022        4199
Wed Sep 14 15:05:46 2022        4199
Wed Sep 14 15:05:47 2022        4199
Wed Sep 14 15:05:48 2022        4199
Wed Sep 14 15:05:49 2022        4199
Wed Sep 14 15:05:50 2022        4199
Wed Sep 14 15:05:51 2022        4199
Wed Sep 14 15:05:52 2022        4199
Wed Sep 14 15:05:53 2022        4199
Wed Sep 14 15:05:55 2022        4199
Wed Sep 14 15:05:56 2022        4199
Wed Sep 14 15:05:57 2022        4199
Wed Sep 14 15:05:58 2022        4199
Wed Sep 14 15:05:59 2022        4199

Thanks in advance for looking into it.

You need to provide the limits as tuple or list:

plt.ylim([y_low, y_high])
# or
plt.ylim((y_low, y_high))
import matplotlib.pyplot as plt                                                                          
import numpy as np                                                                                       
                                                                                                        
# This emulates data like yours.                                                                                     
t = np.linspace(0, 550, 50)                                                                              
sample = np.random.uniform(low=4198, high=4199, size=(50,))                                              
                                                                                                        
plt.plot(t, sample)                                                                                    
plt.ylim(4100, 4300) # This DOES produce the effect that you want!!
plt.ylabel('Voltage (mV)')
plt.xlabel('Time (s)')                                
plt.show()

The issue must come from how you pack your data into the two lists that you plot.

According to your whole script, the problem comes from how you process your data. In particular, the return statements of findStart and findEnd make references to a local variable that is NOT referenced unless the if statement returns true . This throws an error using Python 3.8 and 3.10 (I didn't try others)

Like others suspected, I'd suggest you to debug these functions in order to make sure they do what you want. In any case, there is nothing wrong with how you use matplotlib to achieve what you want to see in your plot.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM