Plot a 3 line graphs on a scatter plot_Python - python

I want to plot a 3 line plots on the scatter plot to check how much scatter are the points from the line plot
My scatter plot is obtained as below
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
x = np.array([38420690,53439687,82878917,97448841])
y = np.array([47581627,12731149,3388697,911432])
plt.scatter(x,y)
plt.plot()
plt.show()
Now, I want to plot another 3 line graphs on the scatter plot such that,
1 line graph # x = y
2nd Line graph # x = 10*y
3rd Line graph # x = 10/y
Expected outout
Please help me how to do this in python

You can create a linspace of let's say 50 points using the min and max values of your x array and then apply the operations to it:
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
x = np.array([38420690,53439687,82878917,97448841])
y = np.array([47581627,12731149,3388697,911432])
min_x = min(x)
max_x = max(x)
newx = np.linspace(min_x, max_x, 50)
newy = newx
plt.figure(figsize=(12, 8))
plt.scatter(x,y, label='scatter')
plt.plot(newx, newy, color='red', label='x=y') # x=y
plt.plot(newx, newy*10, color='blue', label='x=10*y') # x -> 10*y'
plt.plot(newx, 10/newy, color='black',label='x=10/y') # x -> 10/y
plt.legend()
plt.show()
This results in:

What you describe would be the following:
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
x = np.array([38420690,53439687,82878917,97448841])
y = np.array([47581627,12731149,3388697,911432])
val = [0, 97448841*0.5, 97448841]
plt.scatter(x,y)
plt.plot(val, val, color='red')
plt.plot(val, [i*10 for i in val], color='blue')
plt.plot(val, [i*0.1 for i in val], color='black')
plt.plot()
plt.show()
But you are likely looking for 3 lines with similar slope but different intersection point so instead (more like in the drawing):
plt.plot(val, val, color='red')
plt.plot(val, [i+10000000 for i in val], color='blue')
plt.plot(val, [i-10000000 for i in val], color='black')

Related

python, matplotlib.pyplot, draw graph without the curve

I am trying to draw a curve without a line (skeleton). I want the axis and grid lines only.
Here is the code.
++++++++++
import matplotlib.pyplot as plt
import numpy as np
plt.rcParams["figure.figsize"] = [10.00, 7.00]
plt.rcParams["figure.autolayout"] = True
x = [1.6,2,2.5,3.2,4,5,6.3,8,10,13,16,20,25,32,40,50,63,80,100,130,160,200,250,320,400,500,630,800,1000]
y = range(1,10000,350)#[1,10,100,1000,10000]
# Display grid
plt.grid(True, which="both")
default_x_ticks = range(len(x))
plt.plot(default_x_ticks, y)
plt.yscale('log')
plt.xticks(default_x_ticks, x, rotation=90)
plt.show()
+++++++
Kindly help draw without the curve.
By adding
print(plt.xlim())
print(plt.ylim())
to your code you get the exact axis limits.
These can be used in a second run to create the plot without actually plotting anything:
import matplotlib.pyplot as plt
import numpy as np
plt.rcParams["figure.figsize"] = [10.00, 7.00]
plt.rcParams["figure.autolayout"] = True
x = [1.6,2,2.5,3.2,4,5,6.3,8,10,13,16,20,25,32,40,50,63,80,100,130,160,200,250,320,400,500,630,800,1000]
y = range(1,10000,350)#[1,10,100,1000,10000]
# Display grid
plt.grid(True, which="both")
default_x_ticks = range(len(x))
# plt.plot(default_x_ticks, y)
plt.yscale('log')
plt.xticks(default_x_ticks, x, rotation=90)
plt.xlim(-1.4, 29.4)
plt.ylim(0.6315917965717447, 15517.934294269562)
plt.show()

matplotlab How can I plot points in a loop using one array

This is a simplified example of a problem I am having.
import matplotlib.pyplot as plt
for i in range(0,10):
plt.plot(i, i + 1)
plt.show()
shows this. and
x = y = []
for i in range(0,10):
x.append(i)
y.append(i + 1)
plt.plot(x, y,)
plt.show()
shows this.
How can I plot points in a loop so that I don't need to create two arrays?
Try this-
import matplotlib.pyplot as plt
for i in range(0,10):
plt.plot(i, i + 1, color='green', linestyle='solid', linewidth = 3,
marker='o')
plt.show()
Pass array as the first argumet to plt.plot(), this would plot y using x as index array 0..N-1:
import matplotlib.pyplot as plt
# plot y using x as index array 0..N-1
plt.plot(range(10))
plt.show()
You'll find more interesting information at plt.plot().
You can do it with:
import matplotlib.pyplot as plt
from matplotlib.collections import LineCollection
fig, ax = plt.subplots()
max =10
for i in range(0,max):
#scatter:
#s=0 to make dissapeared the scatters
ax.scatter(i, i + 1,s=1,facecolor='blue')
#lines
if i > 0:
lc = LineCollection([[(i-1, i),(i, i+1)]])
ax.add_collection(lc)
plt.show()
result:

How to plot a contour plot if the difference between Zmax and Zmin is of the order of 10^(-5)?

I want to produce a ramachandran plot which would look like the following
basically it is a superposition of two plots: contour and scatter. I have the data file for plotting the contour and scatter plot. The data for contour plot is present as three different columns denoting x, y and z values. the value of x and y varies from -180 to 180. Whereas the value z varies from 0 to 1 and the difference between z values can be as low as 10^(-5). In my code I tried to plot the contour using tricontourf where the difference each entry of the level is 0.01. Whenever I tried to make gap between those levels to 0.00001, the code just doesn't get over. That's why I am unable to generate a graph that I want.
The code that I wrote is the following:
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.tri as tri
import matplotlib.cm as cm
x=[]
y=[]
z=[]
x1=[]
y1=[]
lst = []
plt.style.use('seaborn-whitegrid')
for line in open('rama_data.txt', 'r'):
values = [float(s) for s in line.split()]
x.append(values[0])
y.append(values[1])
z.append(values[2])
f=open('all_str_C-S-S-C_Acceptor.txt',"r")
lines=f.readlines()
for m in lines:
x1.append(m.split(' ')[8])
y1.append(m.split(' ')[9])
f.close()
norm = cm.colors.Normalize(vmax=max(z), vmin=min(z))
cmap = cm.OrRd
fig2, ax2 = plt.subplots()
#ax2.set_aspect('equal')
levels = np.arange(0, 1,0.01)
tcf = ax2.tricontourf(x, y, z, levels, cmap=cm.get_cmap(cmap, len(levels)-1),norm=norm)
ax2.set_xticks(np.arange(-180,181,45))
ax2.set_yticks(np.arange(-180,181,45))
ax2.set_xlabel('$\Phi$ Dihedral angle($\circ$)', fontsize=12, fontweight='bold')
ax2.set_ylabel('$\Psi\'$ Dihedral angle($\circ$)', fontsize=12, fontweight='bold')
#cbar=fig2.colorbar(tcf)
#cbar.ax.set_ylabel('Relative Electronic energy(kJ/mol)', fontsize=12, fontweight='bold')
ax2.autoscale(False) # To avoid that the scatter changes limits
ax2.scatter(x1,y1,s=0.15,c='black',zorder=1)
fig2.savefig("Ramachandran plot",dpi=300)
plt.show()
My code generates an image which looks this this:
What modifications should I do do produce the desirable plot?
I have attached the rama_data.txt file. Anyone can download and try it once.
The main problem seems to be that for 100 levels (as in levels = np.arange(0, 1,0.01)) the colors get very smoothed out. Just reducing the number of levels gets a plot much closer to the example plot.
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.tri as tri
xyz = np.loadtxt('rama.txt')
x = xyz[:, 0]
y = xyz[:, 1]
z = xyz[:, 2]
fig2, (ax1, ax2) = plt.subplots(ncols=2)
cmap = 'OrRd'
tcf = ax2.tricontourf(x, y, z, levels=5, cmap=cmap) # norm=norm)
filter = (z > 0.2) & (np.random.randint(0, 10, z.size) == 0)
ax2.scatter(x[filter], y[filter], marker='.', s=1, color='black')
ax1.scatter(x, y, c=z, cmap=cmap)
ax1.set_xticks(np.arange(-180, 181, 45))
ax1.set_yticks(np.arange(-180, 181, 45))
ax2.set_xticks(np.arange(-180, 181, 45))
ax2.set_yticks(np.arange(-180, 181, 45))
plt.show()
The plot shows a regular scatter plot of the given data at the left, and the contourf plot at the right.

Specify range of colors for density plot in Matplotlib

The following code:
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import gaussian_kde
# Generate fake data
x = np.random.normal(size=1000)
y = x * 3 + np.random.normal(size=1000)
# Calculate the point density
xy = np.vstack([x,y])
z = gaussian_kde(xy)(xy)
# Sort the points by density, so that the densest points are plotted last
idx = z.argsort()
x, y, z = x[idx], y[idx], z[idx]
fig, ax = plt.subplots()
ax.scatter(x, y, c=z, s=50, edgecolor='')
plt.show()
produces a graph like this:
How can I change the theme from red to, say, blue? Something like this:
import seaborn as sns
sns.palplot(sns.color_palette("Blues"))
You can assign any color map to scatter plot as follows. Here you will find all the existing colormaps in matplotlib.
The colormap you want is named Blues. You have to import matplotlib.cm to access the color maps and then pass the required color map as an argument to cmap in your scatter plot. Additionally, you can show the color bar for sake of interpretation of the colors. If you want to reverse a color map, just include _r at the end of that color map. For instance, Blues_r will reverse the map with the scale now going from blue (low) to white (high).
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import gaussian_kde
import matplotlib.cm as cm
# Generate fake data
x = np.random.normal(size=1000)
y = x * 3 + np.random.normal(size=1000)
# Calculate the point density
xy = np.vstack([x,y])
z = gaussian_kde(xy)(xy)
# Sort the points by density, so that the densest points are plotted last
idx = z.argsort()
x, y, z = x[idx], y[idx], z[idx]
fig, ax = plt.subplots()
ax_ = ax.scatter(x, y, c=z, cmap=cm.Blues, s=50, edgecolor='')
plt.colorbar(ax_)

Python plotting 2d data on to 3d axes

I've had a look at matplotlib's examples of 3d plots, but none of these give me what I want to plot, something like:
The plot shows a series of measurements on the y-axis (N) and each measurement has an intensity spectrum (p/2hk_L), i.e. N is fixed for each line you see in the graph. What is the easiest function to use to plot data like this?
Here is a try:
import numpy as np
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
x = np.linspace(-50,50,100)
y = np.arange(25)
X,Y = np.meshgrid(x,y)
Z = np.zeros((len(y),len(x)))
for i in range(len(y)):
damp = (i/float(len(y)))**2
Z[i] = 5*damp*(1 - np.sqrt(np.abs(x/50)))
Z[i] += np.random.uniform(0,.1,len(Z[i]))
ax.plot_surface(X, Y, Z, rstride=1, cstride=1000, color='w', shade=False, lw=.5)
ax.set_zlim(0, 5)
ax.set_xlim(-51, 51)
ax.set_zlabel("Intensity")
ax.view_init(20,-120)
plt.show()

Categories