I'm in a physics lab class and we have to write some code to analyze some data we have collected. My question is simple and probably stupid but I was just wondering how to plot a graph on top of another graph using python. Here is my code so far thanks
%pylab
import numpy as np
import matplotlib.mlab as mlab
import matplotlib.pyplot as plt
#SIGNAL DATA
dataSig = [658, 679, 683, 691, 693, 693, 695, 696, 696, 696, 697, 699, 699, 700, 700, 700, 702, 703, 703, 704, 706, 706, 708, 708, 709, 709, 712, 712, 713, 714, 714, 715, 715, 715, 716, 716, 716, 717, 717, 717, 718, 718, 718, 718, 719, 720, 720, 721, 721, 721, 722, 723, 723, 724, 725, 725, 725, 726, 726, 726, 727, 727, 728, 728, 729, 730, 730, 731, 731, 731, 731, 732, 732, 733, 734, 734, 734, 734, 735, 736, 737, 738, 738, 738, 738, 740, 740, 741, 741, 741, 742, 743, 743, 743, 743, 743, 743, 743, 744, 744, 745, 746, 746, 746, 746, 747, 747, 747, 747, 748, 749, 749, 750, 750, 750, 750, 751, 751, 751, 751, 752, 752, 752, 754, 754, 756, 756, 757, 757, 757, 759, 759, 760, 760, 760, 762, 762, 762, 762, 762, 762, 763, 764, 765, 765, 765, 765, 766, 766, 766, 767, 767, 768, 769, 769, 770, 770, 771, 773, 775, 776, 780, 786, 786, 786, 787, 790, 790, 793, 796, 797, 798, 817, 823]
#[658,679,683,691,693,695,696,697,699,700,702,703,704,706,708,709,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727,728,729,730,731,732,733,734,735,736,737,738,740,741,742,743,744,745,746,747,748,749,750,751,752,754,756,757,759,760,762,763,764,765,766,767,768,769,770,771,773,775,776,780,786,787,790,793,796,797,798,817,823] #[1,1,1,1,1,1,3,1,2,3,1,2,1,2,2,1,2,1,2,3,2,3,3,1,2,3,1,2,1,3,3,2,2,1,1,4,2,1,4,1,1,1,4,2,3,1,7,2,1,4,4,1,2,4,4,3,2,2,2,2,3,6,1,1,4,3,2,1,2,2,1,1,1,1,1,3,1,2,1,1,1,1,1,1]
#SIGNAL DEFINED VARIABLES
ntestpoints = 175
themean = 739.1
#sigma = ?
#amp = center/guassian
#SIGNAL GAUSSIAN FITTING FUNCTION
def mygauss(x, amp, center, sigma):
"""This is an example gaussian function, which takes in x values, the amplitude (amp),
the center x value (center) and the sigma of the Gaussian, and returns the respective y values."""
y = amp * np.exp(-.5*((x-center)/sigma)**2)
return y
#SIGNAL PLOT, NO GAUSS
plt.figure(figsize=(10,6))
plt.hist(dataSig,bins=ntestpoints/10,histtype="stepfilled",alpha=.5,color='g',range=[600,900])
plt.xlabel('Number of Counts/Second',fontsize=20)
plt.ylabel('Number of Measurements',fontsize=20)
plt.title('Measured Signal Count Rate Fitting with Gaussian Function',fontsize=22)
plt.axvline(themean,linestyle='-',color='r')
#plt.axvline(themean+error_on_mean,linestyle='--',color='b')
#plt.axvline(themean-error_on_mean,linestyle='--',color='b')
#plt.axvline(testmean,color='k',linestyle='-')
plt.show()
#------------------------------------------------------------
# define a function to make a gaussian with input values, used later
def mygauss(x, amp, center, sigma):
"""This is an example gaussian function, which takes in x values, the amplitude (amp),
the center x value (center) and the sigma of the Gaussian, and returns the respective y values."""
y = amp * np.exp(-.5*((x-center)/sigma)**2)
return y
npts = 40 # the number of points on the x axis
x = np.linspace(600,900,npts) # make a series of npts linearly spaced values between 0 and 10
amp = 40
center = 740.5
sigma = 40
y = mygauss(x, amp, center, sigma)
print y
plt.figure(figsize=(10,6))
plt.plot(x,y,'bo', label='data points')
plt.text(center, amp, "<-- peak is here",fontsize=16) # places text at any x/y location on the graph
plt.xlabel('X axis',fontsize=20)
plt.ylabel('Y axis', fontsize=20)
plt.title('A gaussian plot \n with some extras!',fontsize=20)
plt.legend(loc='best')
plt.show()
when you call for plt.figure() you are making a new plot area, in a different figure.
if you dont call for it the second time, you will plot in the same graph as the first one.
that however is not always a solution by itself, if they have very different scales, that can cause one graph to be massively outscaled by the other.
fortunately its not the case here so i wont get into details of how to use 2 different scales in one graph, but you can check it here (http://matplotlib.org/examples/api/two_scales.html)
by commenting the second plt.figure() from your code you get this:
hope it helps!
ps: next time try posting it with a matplotlib tag, it will get a fastter response than physics, since its basically a matplotlib question you had.
Related
I have the following dataframe:
df = {'count1': [2.2336, 2.2454, 2.2538, 2.2716999999999996, 2.2798000000000003, 2.2843, 2.2906, 2.2969, 2.3223000000000003, 2.3282, 2.3356999999999997, 2.3544, 2.3651999999999997, 2.3727, 2.3775, 2.3823000000000003, 2.392, 2.4051, 2.4092, 2.4133, 2.4168000000000003, 2.4175, 2.4209, 2.4392, 2.4476, 2.456, 2.461, 2.4723, 2.4776, 2.4882, 2.4989, 2.5095, 2.5221999999999998, 2.5318, 2.5422, 2.5494, 2.559, 2.5654, 2.5814, 2.5878, 2.6238, 2.6178000000000003, 2.624, 2.6303, 2.6366, 2.6425, 2.6481999999999997, 2.6525, 2.6553, 2.663, 2.6712, 2.6898, 2.7051, 2.7144, 2.727, 2.7416, 2.7472, 2.7512, 2.7557, 2.7574, 2.7594000000000003, 2.7636, 2.7699000000000003, 2.7761, 2.7809, 2.7855, 2.7902, 2.7948000000000004, 2.7995, 2.8043, 2.815, 2.8249, 2.8352, 2.8455, 2.8708, 2.8874, 2.9004000000000003, 2.9301, 2.9399, 2.9513000000000003, 2.9634, 2.9745999999999997, 2.9852, 2.9959000000000002, 3.0037, 3.0093, 3.015, 3.0184, 3.0206, 3.0225, 3.0245, 3.0264, 3.0282, 3.0305999999999997, 3.0331, 3.0334, 3.0361, 3.0388, 3.0418000000000003, 3.0443000000000002, 3.0463, 3.0464, 3.0481, 3.0496999999999996, 3.0514, 3.0530999999999997, 3.0544000000000002, 3.0556, 3.0569, 3.0581, 3.0623, 3.0627, 3.0633000000000004, 3.0638, 3.0643000000000002, 3.0648, 3.0652, 3.0656999999999996, 3.0663, 3.0675, 3.0682, 3.0688, 3.0695, 3.0702, 3.0721, 3.0741, 3.0761, 3.078, 3.08, 3.082, 3.0839000000000003, 3.0859, 3.0879000000000003, 3.0898000000000003, 3.0918, 3.0938000000000003, 3.0994, 3.1050999999999997, 3.1144000000000003, 3.1613, 3.1649000000000003, 3.1752, 3.1869, 3.1899, 3.1925, 3.1976, 3.2001, 3.2051999999999996, 3.2098, 3.2123000000000004],
'count2': [3144, 3944, 7888, 4428, 68874, 5480, 56697, 20560, 8744, 91190, 352, 924, 1308611, 480, 51146, 170373, 58792, 11424, 1288673, 1845105, 401464, 657930, 1361172, 199373, 19753, 39082, 776, 7533, 9289, 36731, 53865, 100140, 59274, 35740, 2648, 144998, 78616, 848241, 34579, 216591, 22512, 4024, 17168, 1552, 13760, 8344, 65589, 43104, 44672, 917115, 16256, 4168, 29679, 22571, 7720, 452, 8836, 6888, 18578, 5148, 9289, 442, 214, 485, 3164, 1101, 1010, 9048, 293, 1628, 960, 517, 2362, 1262, 1524, 1173, 1348, 1288, 25568, 8416, 5792, 4944, 504, 4696, 2336, 458, 453, 1220, 1149, 6688, 6956, 7324, 7100, 7784, 5650, 5076, 5336, 6792, 5212, 4592, 5260, 1279, 654, 842, 990, 782, 1412, 1363, 935, 996, 775, 1471, 1525, 1398, 1097, 1082, 1668, 1007, 497, 598, 645, 698, 541, 504, 549, 540, 1568, 514, 578, 2906, 4360, 3916, 11944, 1434, 1589, 732, 641, 477, 307, 1884, 3232, 2408, 1016, 332, 139, 344, 4784, 1784, 1324, 204]}
df = pd.DataFrame(df)
And I want to plot a barplot with it, where the x axis is count1 and the y axis count2, with bins spaced every 0.1 intervals.
I used this:
plt.bar(x=df['count1'], y=df['count2'], width=0.1)
But it returns me this error:
TypeError: bar() missing 1 required positional argument: 'height'
I'm trying to replicate an R code:
ggplot(df, aes(x= count1,
y= count2)) +
geom_col() +
ylim(0, 2000000) +
scale_x_binned()
That generates the following graph:
To get a histogram from values and counts, you can use the weights= parameter of plt.hist.
To create bins with a width of 0.1, you can use np.arange(...,..., 0.1).
The rwidth=0.9 parameter makes the bars a bit narrower.
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
df = {'count1': [2.2336, 2.2454, 2.2538, 2.2716999999999996, 2.2798000000000003, 2.2843, 2.2906, 2.2969, 2.3223000000000003, 2.3282, 2.3356999999999997, 2.3544, 2.3651999999999997, 2.3727, 2.3775, 2.3823000000000003, 2.392, 2.4051, 2.4092, 2.4133, 2.4168000000000003, 2.4175, 2.4209, 2.4392, 2.4476, 2.456, 2.461, 2.4723, 2.4776, 2.4882, 2.4989, 2.5095, 2.5221999999999998, 2.5318, 2.5422, 2.5494, 2.559, 2.5654, 2.5814, 2.5878, 2.6238, 2.6178000000000003, 2.624, 2.6303, 2.6366, 2.6425, 2.6481999999999997, 2.6525, 2.6553, 2.663, 2.6712, 2.6898, 2.7051, 2.7144, 2.727, 2.7416, 2.7472, 2.7512, 2.7557, 2.7574, 2.7594000000000003, 2.7636, 2.7699000000000003, 2.7761, 2.7809, 2.7855, 2.7902, 2.7948000000000004, 2.7995, 2.8043, 2.815, 2.8249, 2.8352, 2.8455, 2.8708, 2.8874, 2.9004000000000003, 2.9301, 2.9399, 2.9513000000000003, 2.9634, 2.9745999999999997, 2.9852, 2.9959000000000002, 3.0037, 3.0093, 3.015, 3.0184, 3.0206, 3.0225, 3.0245, 3.0264, 3.0282, 3.0305999999999997, 3.0331, 3.0334, 3.0361, 3.0388, 3.0418000000000003, 3.0443000000000002, 3.0463, 3.0464, 3.0481, 3.0496999999999996, 3.0514, 3.0530999999999997, 3.0544000000000002, 3.0556, 3.0569, 3.0581, 3.0623, 3.0627, 3.0633000000000004, 3.0638, 3.0643000000000002, 3.0648, 3.0652, 3.0656999999999996, 3.0663, 3.0675, 3.0682, 3.0688, 3.0695, 3.0702, 3.0721, 3.0741, 3.0761, 3.078, 3.08, 3.082, 3.0839000000000003, 3.0859, 3.0879000000000003, 3.0898000000000003, 3.0918, 3.0938000000000003, 3.0994, 3.1050999999999997, 3.1144000000000003, 3.1613, 3.1649000000000003, 3.1752, 3.1869, 3.1899, 3.1925, 3.1976, 3.2001, 3.2051999999999996, 3.2098, 3.2123000000000004],
'count2': [3144, 3944, 7888, 4428, 68874, 5480, 56697, 20560, 8744, 91190, 352, 924, 1308611, 480, 51146, 170373, 58792, 11424, 1288673, 1845105, 401464, 657930, 1361172, 199373, 19753, 39082, 776, 7533, 9289, 36731, 53865, 100140, 59274, 35740, 2648, 144998, 78616, 848241, 34579, 216591, 22512, 4024, 17168, 1552, 13760, 8344, 65589, 43104, 44672, 917115, 16256, 4168, 29679, 22571, 7720, 452, 8836, 6888, 18578, 5148, 9289, 442, 214, 485, 3164, 1101, 1010, 9048, 293, 1628, 960, 517, 2362, 1262, 1524, 1173, 1348, 1288, 25568, 8416, 5792, 4944, 504, 4696, 2336, 458, 453, 1220, 1149, 6688, 6956, 7324, 7100, 7784, 5650, 5076, 5336, 6792, 5212, 4592, 5260, 1279, 654, 842, 990, 782, 1412, 1363, 935, 996, 775, 1471, 1525, 1398, 1097, 1082, 1668, 1007, 497, 598, 645, 698, 541, 504, 549, 540, 1568, 514, 578, 2906, 4360, 3916, 11944, 1434, 1589, 732, 641, 477, 307, 1884, 3232, 2408, 1016, 332, 139, 344, 4784, 1784, 1324, 204]}
df = pd.DataFrame(df)
bin_start = np.trunc(df['count1'].min() * 10) / 10
bin_end = df['count1'].max() + 0.1
plt.style.use('ggplot')
plt.hist(x=df['count1'], weights=df['count2'], bins=np.arange(bin_start, bin_end, 0.1), rwidth=0.9)
plt.gca().get_yaxis().get_major_formatter().set_scientific(False)
plt.xlabel('count1')
plt.ylabel('count2')
plt.tight_layout()
plt.show()
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I have a list full of integers(it's not sorted) and I have 2 input:
-input no.1 the sum I want to get
-input no.2 the maximum number of usable element to get the sum
The sum can't be higher than the given value(input no.1) but can be less by -10. The number of used elements of the list can be equal to or less than the given value(input no.2).
from random import choice
def Diff(li1, li2):
return (list(list(set(li1)-set(li2)) + list(set(li2)-set(li1))))
def find_the_elements(current_sum, wanted_sum, used_elements, max_number_of_elements, n_o_elements):
solution = 0
while solution != 1:
elemnt=choice(Diff(elemts, used_elements))
used_elements.append(elemnt)
current_sum+=elemnt
n_o_elements+=1
if max_number_of_elements<=max_number_of_elements and current_sum in wanted_sum:
return used_elements
elif n_o_elements>max_number_of_elements or current_sum>wanted_sum.stop:
return -1
else:
x=find_the_elements(current_sum=current_sum, wanted_sum=wanted_sum, used_elements=used_elements, n_o_elements=n_o_elements, max_number_of_elements=max_number_of_elements)
if x!=-1:
return used_elements
elif x==-1:
return -1
elemts = [535, 508, 456, 612, 764, 628, 530, 709, 676, 546, 579, 676,
564, 565, 742, 657, 577, 514, 650, 590, 621, 642, 684, 567, 670, 609, 571, 655, 681, 615, 617, 569, 656, 615,
542, 711, 777, 763, 663, 657, 532, 630, 636, 445, 495, 567, 603, 598, 629, 651, 608, 653, 669, 603, 655, 622,
578, 551, 560, 712, 642, 637, 545, 631, 479, 614, 710, 458, 615, 659, 636, 578, 629, 622, 584, 582, 650, 636,
693, 527, 577, 711, 601, 530, 1028, 683, 589, 590, 670, 409,582, 635, 558, 607, 648, 542, 726, 534, 540, 590, 649, 482, 664, 629, 555, 596, 613, 572, 516, 479, 562, 452,
586]
max_no_elements = int(input())
wanted_sum = int(input())
solution = -1
while solution == -1:
solution = find_the_elements(current_sum=0, wanted_sum=range(wanted_sum - 10, wanted_sum + 1), used_elements=[], max_number_of_elements=max_no_elements, n_o_elements=0)
print(solution)
That's my solution for it but I think I should do it differently because originally I work with a much bigger list and each elements(integer) of the list is much 10-20x bigger.
Recursion with memoization (i.e. dynamic programing) is probably the best approach for this:
def closeSum(A,S,N,p=0,memo=None):
if not N: return [],0
if memo is None: memo = dict() # memoization
if (S,N,p) in memo: return memo[S,N,p]
best,bestSum = [],0
for i,a in enumerate(A[p:],p): # combine remaining elements for sum
if a>S: continue # ignore excessive values
if a == S: return [a],a # end on perfect match
r = [a] + closeSum(A,S-a,N-1,i+1,memo)[0] # extend sum to get closer
sr = sum(r)
if sr+10>=S and sr>bestSum: # track best so far
best,bestSum = r,sr
memo[S,N,p]=(best,sum(best)) # memoization
return best,sum(best)
output:
elemts = [535, 508, 456, 612, 764, 628, 530, 709, 676, 546, 579, 676,
564, 565, 742, 657, 577, 514, 650, 590, 621, 642, 684, 567, 670, 609, 571, 655, 681, 615, 617, 569, 656, 615,
542, 711, 777, 763, 663, 657, 532, 630, 636, 445, 495, 567, 603, 598, 629, 651, 608, 653, 669, 603, 655, 622,
578, 551, 560, 712, 642, 637, 545, 631, 479, 614, 710, 458, 615, 659, 636, 578, 629, 622, 584, 582, 650, 636,
693, 527, 577, 711, 601, 530, 1028, 683, 589, 590, 670, 409,582, 635, 558, 607, 648, 542, 726, 534, 540, 590, 649, 482, 664, 629, 555, 596, 613, 572, 516, 479, 562, 452,
586]
closeSum(elemts,1001,3)
[456, 545], 1001
closeSum(elemts,5522,7)
[764, 742, 777, 763, 712, 1028, 726], 5512
closeSum(elemts,5522,10)
[535, 508, 456, 612, 764, 628, 530, 546, 409, 534], 5522
It works relatively fast when there is an exact match but still takes a while for the larger values/item counts when it doesn't.
Note that there is still room for some optimization such as keeping track of the total of remaining elements (from position p) and exiting if they can't add up to the target sum.
I have something along the lines of this dict:
{10: [891, 506, 714, 430, 294, 659, 430, 430, 375, 430, 294, 714, 1510, 1049, 847, 430, 430, 430, 1410, 1657], 12: [676, 466, 719, 727, 573, 1202, 466, 719, 573, 885, 573, 573, 573, 573, 518, 518, 573, 573, 1465, 466]}
I am trying to plot a graph where the x axis has the keys, (i.e: 10,12,14...) and the y axis represents the average of the list corresponding with the key and I want to show some bars which represent the quartiles or the possible range? Anyone have any idea how I can go about doing that?
This is in Python btw.
Any help would be appreciated.
import matplotlib.pyplot as plt
data = {10: [891, 506, 714, 430, 294, 659, 430, 430, 375, 430, 294, 714, 1510, 1049, 847, 430, 430, 430, 1410, 1657],
12: [676, 466, 719, 727, 573, 1202, 466, 719, 573, 885, 573, 573, 573, 573, 518, 518, 573, 573, 1465, 466]}
keys = sorted(data) # keys in a defined order
plt.boxplot([data[k] for k in keys], positions=keys) # box-and-whisker plot
plt.plot(keys, [sum(data[k]) / len(data[k]) for k in keys], '-o') # line for the mean
plt.savefig('nice-box-plots')
Adding whis=(10, 90) as argument to plt.boxplot will put the whiskers to the 10 and 90%tile, see the doc of boxplots.
I suggest you turn your data into a pandas dataframe, carry on all calculation on that dataframe and plot. For example:
df = pd.DataFrame(data)
plot_data = df.agg(['mean', 'std']).T
plt.errorbar(plot_data.index, plot_data['mean'], yerr=plot_data['std'])
Output:
I have a zeros image with dimension 720*1280 and I have a list of pixels' coordinates to change:
x = [623, 623, 583, 526, 571, 669, 686, 697, 600, 594, 606, 657, 657, 657, 617, 646, 611, 657, 674, 571, 693, 688, 698, 700, 686, 687, 687, 693, 690, 686, 694]
y = [231, 281, 270, 270, 202, 287, 366, 428, 422, 517, 608, 422, 518, 608, 208, 214, 208, 231, 653, 652, 436, 441, 457, 457, 453, 461, 467, 469, 475, 477, 467]
here is the scatter plot :
yy= [720 -x for x in y]
plt.scatter(x, yy, s = 25, c = "r")
plt.xlabel('x')
plt.ylabel('y')
plt.xlim(0, 1280)
plt.ylim(0, 720)
plt.show()
here is the code to generate binary image by set the pixel value to 255
image_zeros = np.zeros((720, 1280), dtype=np.uint8)
for i ,j in zip (x, y):
image_zeros[i, j] = 255
plt.imshow(image_zeros, cmap='gray')
plt.show()
here is the result : What is the problem!!
As Goyo pointed out, the resolution of the image is the problem. The default figure size is 6.4 inches by 4.8 inches, and the default resolution is 100 dpi (at least for the current version of matplotlib). So the default image size is 640 x 480. The figure includes not only the imshow image, but also the tickmarks, ticklabels and the x and y axis and a white border. So there are are even fewer than 640 x 480 pixels available for the imshow image by default.
Your image_zeros has shape (720, 1280). The array is too large to be fully rendered in an image of 640 x 480 pixels.
Thus, to generate white dots using imshow, set the figsize and dpi so that the number of pixels available for the imshow image is bigger than (1280, 720):
import numpy as np
import matplotlib.pyplot as plt
x = np.array([623, 623, 583, 526, 571, 669, 686, 697, 600, 594, 606, 657, 657, 657, 617, 646, 611, 657, 674, 571, 693, 688, 698, 700, 686, 687, 687, 693, 690, 686, 694])
y = np.array([231, 281, 270, 270, 202, 287, 366, 428, 422, 517, 608, 422, 518, 608, 208, 214, 208, 231, 653, 652, 436, 441, 457, 457, 453, 461, 467, 469, 475, 477, 467])
image_zeros = np.zeros((720, 1280), dtype=np.uint8)
image_zeros[y, x] = 255
fig, ax = plt.subplots(figsize=(26, 16), dpi=100)
ax.imshow(image_zeros, cmap='gray', origin='lower')
fig.savefig('/tmp/out.png')
Here is a closeup showing some of the white dots:
To make the white dots easier to see, you may wish to use scatter instead of imshow:
import numpy as np
import matplotlib.pyplot as plt
x = np.array([623, 623, 583, 526, 571, 669, 686, 697, 600, 594, 606, 657, 657, 657, 617, 646, 611, 657, 674, 571, 693, 688, 698, 700, 686, 687, 687, 693, 690, 686, 694])
y = np.array([231, 281, 270, 270, 202, 287, 366, 428, 422, 517, 608, 422, 518, 608, 208, 214, 208, 231, 653, 652, 436, 441, 457, 457, 453, 461, 467, 469, 475, 477, 467])
yy = 720 - y
fig, ax = plt.subplots()
ax.patch.set_facecolor('black')
ax.scatter(x, yy, s=25, c='white')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_xlim(0, 1280)
ax.set_ylim(0, 720)
fig.savefig('/tmp/out-scatter.png')
I have a 2D numpy array, z, in which I would like to assign values to nan based on the equation of a line +/- a width of 20. I am trying to implement the Raman 2nd scattering correction as it is done by the eem_remove_scattering method in the eemR package listed here:
https://cran.r-project.org/web/packages/eemR/vignettes/introduction.html
but the method isn't visible.
import numpy as np
ex = np.array([240, 245, 250, 255, 260, 265, 270, 275, 280, 285, 290, 295, 300,
305, 310, 315, 320, 325, 330, 335, 340, 345, 350, 355, 360, 365,
370, 375, 380, 385, 390, 395, 400, 405, 410, 415, 420, 425, 430,
435, 440, 445, 450])
em = np.array([300, 302, 304, 306, 308, 310, 312, 314, 316, 318, 320, 322, 324,
326, 328, 330, 332, 334, 336, 338, 340, 342, 344, 346, 348, 350,
352, 354, 356, 358, 360, 362, 364, 366, 368, 370, 372, 374, 376,
378, 380, 382, 384, 386, 388, 390, 392, 394, 396, 398, 400, 402,
404, 406, 408, 410, 412, 414, 416, 418, 420, 422, 424, 426, 428,
430, 432, 434, 436, 438, 440, 442, 444, 446, 448, 450, 452, 454,
456, 458, 460, 462, 464, 466, 468, 470, 472, 474, 476, 478, 480,
482, 484, 486, 488, 490, 492, 494, 496, 498, 500, 502, 504, 506,
508, 510, 512, 514, 516, 518, 520, 522, 524, 526, 528, 530, 532,
534, 536, 538, 540, 542, 544, 546, 548, 550, 552, 554, 556, 558,
560, 562, 564, 566, 568, 570, 572, 574, 576, 578, 580, 582, 584,
586, 588, 590, 592, 594, 596, 598, 600])
X, Y = np.meshgrid(ex, em)
z = np.sin(X) + np.cos(Y)
The equation that I would like to apply is em = - 2 ex/ (0.00036*ex-1) + 500.
I want to set every value in the array that intersects this line (+/- 20 ) to be set to nans. Its simple enough to set a single element to nans, but I havent been able to locate a python function to apply this equation to the array and only set values that intersect with this line to nans.
The desired output would be a new array with the same dimensions as z, but with the values that intersect the line equivalent to nan. Any suggestions on how to proceed are greatly appreciated.
Use np.where in the form np.where( "condition for intersection", np.nan, z):
zi = np.where( np.abs(-2*X/(0.00036*X-1) + 500 - Y) <= 20, np.nan, z)
As a matter of fact, there are no intersections here because (0.00036*ex-1) is close to -1 for all your values, which makes - 2*ex/(0.00036*ex-1) close to 2*ex, and adding 500 brings this over any values you have in em. But in principle this works.
Also, I suspect that the goal you plan to achieve by setting those values to NaN would be better achieved by using a masked array.