How can I add a new plots to existing figures? - python

I am new to Python and have mainly used MatLab in the past. I am re-writing one of my MatLab scripts and am wondering how to add plots to figures. It seems in python I can only have one figure open at a time and have to manually close the window before a second figure will open. My original script is a couple hundred lines long, but here is a MWE of what I want to do.
import matplotlib.pyplot as plt
import numpy as np
#from mpl_toolkits import mplot3d
lst = [ 1, 1.5, 2, 4.5]
alpha= np.array(lst)
#initialize tables for plots
xtable = []
ytable = []
y2table = []
#determine whether lst is a vector or an array for number of iterations of inner and outer loops
def size(arr):
if len(arr.shape) == 1:
return arr.shape[0], 1
return arr.shape
[nn,mm] = size(alpha)
#create and plot data
for kk in range(nn):#= 1:nn
x = [i for i in range(0, 10)]
y = [alpha[kk]*i for i in range(0, 10)]
y2 = [alpha[kk]*i**2 for i in range(0, 10)]
#data for plot(s)
xtable += [x]
ytable += [y]
y2table += [y2]
#plot1
plt.plot(xtable,ytable)
plt.hold on
#plot2
plt.plot(xtable,y2table)
plt.hold on
In my script these will actually be 3D plots, but I don't think that's necessary here. I just want the for-loop to run for each value in lst and end up with two figures, each with 4 plots. The size of lst is not fixed or I'd generate the data in the loop and plot later.
Thank you in advance for your help

follow up on tdy's comment:
#create plots:
fig1, ax1 = plt.subplots()
fig2, ax2 = plt.subplots()
#plot data
for kk in range(nn):#= 1:nn
x = [i for i in range(0, 10)]
y = [alpha[kk]*i for i in range(0, 10)]
y2 = [alpha[kk]*i**2 for i in range(0, 10)]
#data for plot(s)
xtable += [x]
ytable += [y]
y2table += [y2]
#plot1
ax1.plot(xtable,ytable)
#plot2
ax2.plot(xtable,y2table)

Related

What code should I add to make x start at 1?

I tried to make graph with matplotlib, and my graph should start from 1 not 0, But I don't know how to do. I can do this by writing all figures in x_coords and y_coords, but I want to know the code I can use while I use f = open(). Sorry that I'm not fluent in English
import matplotlib.pyplot as plt
import numpy as np
avg_prices = []
labels = (i for i in range(1, 53))
f = open('C:/1994_Weekly_Gas_Averages.txt', 'r')
for line in f:
avg_prices.append(float(line))
plt.plot(avg_prices, 'o--', label=labels)
plt.title('1994 Weekly Gas Prices')
plt.xlabel('Weeks')
plt.ylabel('Average prices')
plt.grid()
plt.xticks(np.arange(0, 60, 10))
plt.yticks(np.arange(1, 1.17, 0.025))
plt.show()
Just include the corresponding x coordinate in before the y coordinate.
x = list(range(1,53))
plt.plot(x, avg_prices)
labels = (i for i in range(0, 53)) should work. range function will start from the first parameter and run al the way till the n-1 of the second parameter.
labels = (i for i in range(0, 53)) will give labels from 0.....52
labels = (i for i in range(1, 53)) will give labels from 1.....52
labels = (i for i in range(1, 54)) will give labels from 1.....53
labels = (i for i in range(0, 54)) will give labels from 0.....53

Merge multiple matplotlib charts into a single chart and assign color based on array

New to coding so please bear with me. I was trying to merge multiple matplotlib charts into one and based on the value of array 'z' auto assign a color.
import random
import matplotlib.pyplot as plt
z = []
x1 = []
y1 = []
for u in range(10):
z.append(round(random.uniform(1,40),0))
for i in range(30):
x1.append(i)
for x in z:
print(x)
for i in range(30):
if x%2 == 0:
x = x / 2
else:
x = x*3 + 1
y1.append(x)
plt.plot(x1,y1)
plt.show()
y1 = []
Effectively, I want to play around with values of iterants and not manually define color each time. Help is sincerely appreciated!

How to update a plot by calling data from within the program?

I am writing a programme which takes a circular membrane and models its evolution under certain forces. The programme is as follows (with the details of the evolution omitted)
import numpy as np
import math
from matplotlib import pyplot as plt
xCoords = {"%s" % i: np.array([math.cos(2*math.pi*i/360),0,0,0,0,0,0,0,0,0], dtype=float)
for i in range(0, 360)} #coordinates stored in arrays whose entries correspond to time evolution
yCoords = {"%s" % i: np.array([math.sin(2*math.pi*i/360),0,0,0,0,0,0,0,0,0], dtype=float)
for i in range(0, 360)}
#fill out arrays using diff eq.
x = np.zeros((360,10), dtype = float)
y = np.zeros((360,10), dtype = float)
for i in range(0,360):
for j in range(0,10):
x[i][j] = xCoords["%s" % i][j]
y[i][j] = yCoords["%s" % i][j]
If I want to now plot the evolution of the coordinates over time, how would I do that?
I tried to plot with the following.
plt.plot(x,y)
plt.show
but it just outputs
In particular, how do I get a plot of just (x[i][j],y[i][j]) at time j?
I then tried
for j in range(0,62):
for i in range(0,360):
plt.plot(x[i][j],y[i][j])
plt.show()
but that didn't work either as it didn't give a new 'circle' everytime.
I think you are looking for something like this:
fig = plt.figure()
ax = fig.gca()
h, = ax.plot([],[])
ax.set_xlim(-1, 1)
ax.set_ylim(-1, 1)
for time_ind in range(0,10):
h.set_data(x[:, time_ind], y[:, time_ind])
plt.draw()
plt.pause(0.5)

Making parts of a line graph a different colour depending on their y value in Matplotlib

I'm making a program which takes a random list of data and will plot it.
I want the colour of the graph to change if it goes above a certain value.
https://matplotlib.org/gallery/lines_bars_and_markers/multicolored_line.html
Matplotlib has an entry on doing just this but it seems to require using a function as input for the graph not using lists.
Does anyone know how to either convert this to work for lists or another way of doing so?
Here's my code so far (without my horrific failed attempts to colour code them)
from matplotlib import pyplot as plt
import random
import sys
import numpy as np
#setting the max and min values where I want the colour to change
A_min = 2
B_max = 28
#makes lists for later
A_min_lin = []
B_max_lin = []
#simulating a corruption of the data where it returns all zeros
sim_crpt = random.randint(0,10)
print(sim_crpt)
randomy = []
if sim_crpt == 0:
randomy = []
#making the empty lists for corrupted data
for i in range(0,20):
randomy.append(0)
print(randomy)
else:
#making a random set of values for the y axis
for i in range(0,20):
n = random.randint(0,30)
randomy.append(n)
print(randomy)
#making an x axis for time
time = t = np.arange(0, 20, 1)
#Making a list to plot a straight line showing where the maximum and minimum values
for i in range(0, len(time)):
A_min_lin.append(A_min)
B_max_lin.append(B_max)
#Testing to see if more than 5 y values are zero to return if it's corrupted
tracker = 0
for i in (randomy):
if i == 0:
tracker += 1
if tracker > 5:
sys.exit("Error, no data")
#ploting and showing the different graphs
plt.plot(time,randomy)
plt.plot(time,A_min_lin)
plt.plot(time,B_max_lin)
plt.legend(['Data', 'Minimum for linear', "Maximum for linear"])
plt.show
You can use np.interp to generate the fine-grain data to plot:
# fine grain time
new_time = np.linspace(time.min(), time.max(), 1000)
# interpolate the y values
new_randomy = np.interp(new_time, time, randomy)
# this is copied from the link with few modification
points = np.array([new_time, new_randomy]).T.reshape(-1, 1, 2)
segments = np.concatenate([points[:-1], points[1:]], axis=1)
fig, axs = plt.subplots()
norm = plt.Normalize(new_randomy.min(), new_randomy.max())
lc = LineCollection(segments, cmap='viridis', norm=norm)
# Set the values used for colormapping
lc.set_array(new_randomy[1:])
lc.set_linewidth(2)
line = axs.add_collection(lc)
fig.colorbar(line, ax=axs)
# set the limits
axs.set_xlim(new_time.min(), new_time.max())
axs.set_ylim(new_randomy.min(), new_randomy.max())
plt.show()
Output:

Matplotlib; Help setting ylimit in subplot

I searched and couldn't find what I was looking for.
How can I set the y limit range on the y axis of a subplot?
Below is a demo of what I'm trying to accomplish. Right now the ranges are automatic. I want to set a specific y limit range on the first subplot from say 50 to 100. I tried a few things with no luck (you will see it commented out).
import math
import matplotlib.pyplot as plt
import random
def graphIt(tupleList1, title1, List2, title2, List3, title3):
x = []
y = []
x2 = []
y2 = []
x3 = []
y3 = []
for i in range(len(tupleList1)):
x.append(tupleList1[i][0])
y.append(tupleList1[i][1])
for i in range(len(List2)):
x2.append(List2[i])
y2.append(1)
for i in range(len(List3)):
x3.append(List3[i])
y3.append(1)
f, plotarray = plt.subplots(3, sharex=True)
#plt.ylim((50, 100)) #<--This sets the range of plotarray[2]
#plotarray[0].ylim((50,100)) #<---No such attribute 'ylim'
plotarray[0].plot(x,y,"o-")
plotarray[0].set_title(title1)
plotarray[1].bar(x2,y2,0.15,color='b',label=title2)
plotarray[1].set_title(title2)
plotarray[2].bar(x3,y3,0.15,color='r',label=title3)
plotarray[2].set_title(title3)
plt.gcf().autofmt_xdate()
plt.show()
myTupleList = []
myList2 = []
myList3 = []
for x in range(100):
y = random.random()*x
myTupleList.append((x,y))
if y > 5 and y <20:
myList2.append(x)
if y >20 and y <30:
myList3.append(x)
graphIt(myTupleList,"MyTupleList",myList2,"MyList2",myList3,"MyList3")
Here is how you can do it:
plotarray[0].set_ylim([50,100])
I tested it with your code to make sure it works, and the top subplot has its y limits changed.

Categories