I am trying to create a scatter plot with a cbar of my data which I have stored in a .txt file. I found a piece of code here on stackoverflow and tested it to see whether it would work with my data.
The example code is as follows:
for record in range(5):
x = rand(50)
y = rand(50)
c = rand(1)[0] * np.ones(x.shape)
X.append(x)
Y.append(y)
C.append(c)
X = np.hstack(X)
Y = np.hstack(Y)
C = np.hstack(C)
ms=45
s = plt.scatter(X,Y,c=C, cmap=cm,s=ms)
cbar = plt.colorbar()
cbar.set_label('test')
plt.savefig('pics/test/test.png', dpi=300)
The above code produces the following scatter plot:
I have adapted the above simple code into something like this for my data:
cm = plt.cm.get_cmap('YlOrRd')
x, y, z = np.loadtxt('test.txt', unpack=True)
ms=45
pareto = plt.scatter(x,y,z, cmap=cm,s=ms)
cbar = plt.colorbar()
cbar.set_label('test')
plt.savefig('pics/test/test.png', dpi=300)
However, the above code returns with the following error:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Users\Mason\Desktop\WinPython-64bit-2.7.6.4\python-
2.7.6.amd64\lib\site-
packages\spyderlib\widgets\externalshell\sitecustomize.py", line 540, in
runfile
execfile(filename, namespace)
File "F:/Optimisation/Plotting_data.py", line 28, in
<module>
d = plt.scatter(x,y,z, cmap=cm,s=ms)
TypeError: scatter() got multiple values for keyword argument 's'
>>>
Also, how could I adjust my axis limits?
You almost had it. You just need to specify that your colors pertain to the z array since scatter plots don't need a 3rd value. Just specify that c=z in your code and your good to go.
cm = plt.cm.get_cmap('YlOrRd')
x, y, z = np.loadtxt('test.txt', unpack=True)
ms=45
pareto = plt.scatter(x,y,c=z, cmap=cm,s=ms) #change to c=z
cbar = plt.colorbar()
cbar.set_label('test')
plt.savefig('pics/test/test.png', dpi=300)
And as noted by Jacob, use plt.xlim() and plt.ylim() to adjust limits.
The scatter function takes in 2 keyword arguments, not the 3 you are passing in within the line:
pareto = plt.scatter(x,y,z, cmap=cm,s=ms)
If you need to plot in 3D dimensions you could look into mplot3d.
To adjust your axis limits you could use:
plt.xlim(x_low, x_high)
plt.ylim(y_low, y_high)
Related
I would like my sybplots to be generated in 2x columns and 5x rows.
I've also tried adding ncols=2, nrows=5 to the code. didn't work.
And when I change the subplots to plt.subplots(5,2) instead of plt.subplots(10,1) it says (see added picture of code+error message):
AttributeError Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_9844/709244097.py in
13
14 for ax, afstand, tid in zip(ax, afstande, tider):
---> 15 ax.plot(tid, afstand)
16 ax.set_title("x(t)", fontsize=12)
17 ax.set_xlabel("tid (s)", fontsize=12)
AttributeError: 'numpy.ndarray' object has no attribute 'plot'
My code:
from scipy.optimize import fmin
a = -75.64766759
b = 68.02691163
f = lambda x: a * x + b
afstand1, afstand2, afstand3, afstand4, afstand5, afstand6, afstand7, afstand8, afstand9, afstand10 = f(U1), f(U2), f(U3), f(U4), f(U5),f(U6), f(U7), f(U8), f(U9), f(U10)
afstande = [afstand1, afstand2, afstand3, afstand4, afstand5, afstand6, afstand7, afstand8, afstand9, afstand10]
tider = [tid1, tid2, tid3, tid4, tid5, tid6, tid7, tid8, tid9, tid10]
fig, ax = plt.subplots(10,1, figsize=(7,25))
plt.subplots_adjust(hspace=0.55)
#loop
for ax, afstand, tid in zip(ax, afstande, tider):
ax.plot(tid, afstand)
ax.set_title("x(t)", fontsize=12)
ax.set_xlabel("tid (s)", fontsize=12)
ax.set_ylabel("Position", fontsize=12)
enter image description here
First of all, you're using the same variable name for the array of axis and in the loop, you should change that. Subplot-axes are stored in numpy arrays. If you only have 1 row, then looping over the array gives you the elements, but in a x*y pattern of subplots, you loop over a two-dimensional array of axis, which yields the rows. You can solve that by using .flat to get a one-dimensional view.
fig, axs = plt.subplots(ncols=5, nrows=2)
for ax in axs.flat:
ax.plot(...)
I have this code were i want to draw a live cahrt
import datetime as dt
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from matplotlib import style
style.use('fivethirtyeight')
# Create figure for plotting
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
xs = []
ys = []
def animate(i, xs, ys):
# Read temperature (Celsius) from TMP102
polarity = open("sentiment2.txt", "r").read()
lines = polarity.split('\n')
print(lines)
for line in lines:
if len(line) > 1:
x,y = line.split(',')
xs.append(dt.datetime.now().strftime('%H:%M:%S.%f'))
ys.append(line)
# Add x and y to lists
# Limit x and y lists to 20 items
xs = xs[-20:]
ys = ys[-20:]
# Draw x and y lists
ax.clear()
ax.plot(xs, ys)
# Format plot
plt.xticks(rotation=45, ha='right')
plt.subplots_adjust(bottom=0.30)
plt.title('Etehreum Sentiment')
plt.ylabel('Sentiment')
# Set up plot to call animate() function periodically
ani = animation.FuncAnimation(fig, animate, fargs=(xs, ys), interval=60000)
plt.show()
When i run it i get this error:
File "ploty.py", line 23, in animate
x,y = line.split(',')
ValueError: not enough values to unpack (expected 2, got 1)
I have this code from a tutorial and he does the same as i try to achieve so im not sure whats the problem here
What I try to achieve is to get the value(sentiment) from my text file- i run a senitment analysis every 10 minutes and whenever my sentiment.txt file gets updated i want to update my chart
the content of my sentiment.txt file:
-8.944388227513231
-7.731292989417991
-8.493252615440113
0.5413275613275612
Perhaps look at how you had generated the sentiment2.txt file.
Each line of your sentiment2.txt file has only one number and there is no comma.
so despite the line.split(','), there is only one of the coordinate but the code is expecting TWO, X AND Y.
Updated:
Currently, the chart is plotting xs and ys onto the chart; ys are values from the file and xs is the real-time when reading the value. If that is intended, then the split line is redundant and can be removed, and you can remove the 'commas' from your source file.
However, if the sentiment file should contains both x-axis and y-axis values; x and y should map into xs and ys instead:
x,y = line.split(',')
xs.append(x)
ys.append(y)
The latter can be improved further by working with panda which works with csv files see: Plot from CSV with Plotly Express
I have a graph which needs two y-axis. Having created the second y-axis I now want to add the labels from each of the two axes instances into one legend, I have seen a method on SO here Secondary axis with twinx(): how to add to legend? but it doesn't produce the legend, instead I get a traceback error.
Some of the code
plot4 = my_figure_trap.add_subplot(111) # adding the subplot
print('\n'*2, 'DEBUG+++++++++type of plot4: ',type(plot4),'\n'*2)
lns1 = plot4.scatter(x=df["Frequency_khz"], y= df["Velocity_ms"], marker='.', c='none', edgecolor='b', label = 'Velocity m/s')
lns2 = plot4.scatter(x=df["Frequency_khz"], y= df["Volume_pl"], marker='.', c='none', edgecolor='r', label = 'Volume_pl')
plot4.set_xlabel('Frequency $(kHz)$', color = 'midnightblue')
plot4.set_ylabel('Velocity $(m/s)$ and Drop Volume $(pL)$', color = 'midnightblue')
plot4.set_xticks(np.arange(freq_axis_origin, freq_axis_max, 10))
plot4.set_yticks(np.arange(vel_axis_origin, vel_axis_max, 1))
plot4.set_facecolor('xkcd:light gray')
plot4a = plot4.twinx()
# LOGIC FOR TRAJECTORY PLOT
# get current traj method
if get_traj_method()==0:
lns3 = plot4a.scatter(x=df["Frequency_khz"], y= df["Traj_deviation_mrads"], marker='.', c='none', edgecolor='g', label = 'Traj Deviation mrads')
plot4a.set_ylim([0-user_traj_range, user_traj_range])
plot4a.set_ylabel('Trajectory deviation from 90$^\circ$ $(mRads)$', color = 'midnightblue')
else:
#get_traj_method()==1:
lns3 = plot4a.scatter(x=df["Frequency_khz"], y= df["Trajectory_deg"], marker='.', c='none', edgecolor='g', label = 'Trajectory ($^\circ$)')
plot4a.set_ylim([90-user_traj_range, 90+user_traj_range])
plot4a.set_ylabel('Trajectory($^\circ$)', color = 'midnightblue')
lns = lns1+lns2+lns3
print(lns)
labs = [l.get_label() for l in lns]
print(labs)
plot4.legend(lns, labs, loc="upper right")
The traceback error is :
Exception in Tkinter callback
Traceback (most recent call last):
File "/Users/.../opt/anaconda3/lib/python3.7/tkinter/__init__.py", line 1705, in __call__
return self.func(*args)
File "/Users/.../Desktop/tk_gui_grid/e_07.py", line 204, in plot_frequency_sweep
lns = lns1+lns2+lns3
TypeError: unsupported operand type(s) for +: 'PathCollection' and 'PathCollection'
(base) ... tk_gui_grid %
I think there are a couple of ways to do this but the option I personally prefer is the following:
### Do everything for plot4 as before
...
handles4,labels4 = plot4.get_legend_handles_labels()
### Do everything for plot4a
...
handles4a,labels4a = plot4a.get_legend_handles_labels()
### Combine the legend handles and labels to make a new legend object
handles = handles4 + handles4a
labels = labels4 + labels4a
plot4.legend(handles, labels)
It'll look something like this:
I have a code:
import math
import numpy as np
import pylab as plt1
from matplotlib import pyplot as plt
uH2 = 1.90866638
uHe = 3.60187307
eH2 = 213.38
eHe = 31.96
R = float(uH2*eH2)/(uHe*eHe)
C_Values = []
Delta = []
kHeST = []
J_f21 = []
data = np.genfromtxt("Lamda_HeHCL.txt", unpack=True);
J_i1=data[1];
J_f1=data[2];
kHe=data[7]
data = np.genfromtxt("Basecol_Basic_New_1.txt", unpack=True);
J_i2=data[0];
J_f2=data[1];
kH2=data[5]
print kHe
print kH2
kHe = map(float, kHe)
kH2 = map(float, kH2)
kHe = np.array(kHe)
kH2= np.array(kH2)
g = len(kH2)
for n in range(0,g):
if J_f2[n] == 1:
Jf21 = J_f2[n]
J_f21.append(Jf21)
ratio = kHe[n]/kH2[n]
C = (((math.log(float(kH2[n]),10)))-(math.log(float(kHe[n]),10)))/math.log(R,10)
C_Values.append(C)
St = abs(J_f1[n] - J_i1[n])
Delta.append(St)
print C_Values
print Delta
print J_f21
fig, ax = plt.subplots()
ax.scatter(Delta,C_Values)
for i, txt in enumerate(J_f21):
ax.annotate(txt, (Delta[i],C_Values[i]))
plt.plot(np.unique(Delta), np.poly1d(np.polyfit(Delta, C_Values, 1))(np.unique(Delta)))
plt.plot(Delta, C_Values)
fit = np.polyfit(Delta,C_Values,1)
fit_fn = np.poly1d(fit)
# fit_fn is now a function which takes in x and returns an estimate for y
plt.scatter(Delta,C_Values, Delta, fit_fn(Delta))
plt.xlim(0, 12)
plt.ylim(-3, 3)
In this code, I am trying to plot a linear regression that extends past the data and touches the x-axis. I am also trying to add a legend to the plot that shows the slope of the plot. Using the code, I was able to plot this graph.
Here is some trash data I have been using to try and extend the line and add a legend to my code.
x =[5,7,9,15,20]
y =[10,9,8,7,6]
I would also like it to be a scatter except for the linear regression line.
Given that you don't provide the data you're loading from files I was unable to test this, but off the top of my head:
To extend the line past the plot, you could turn this line
plt.plot(np.unique(Delta), np.poly1d(np.polyfit(Delta, C_Values, 1))(np.unique(Delta)))
Into something like
x = np.linspace(0, 12, 50) # both 0 and 12 are from visually inspecting the plot
plt.plot(x, np.poly1d(np.polyfit(Delta, C_Values, 1))(x))
But if you want the line extended to the x-axis,
polynomial = np.polyfit(Delta, C_Values, 1)
x = np.linspace(0, *np.roots(polynomial))
plt.plot(x, np.poly1d(polynomial)(x))
As for the scatter plot thing, it seems to me you could just remove this line:
plt.plot(Delta, C_Values)
Oh right, as for the legend, add a label to the plots you make, like this:
plt.plot(x, np.poly1d(polynomial)(x), label='Linear regression')
and add a call to plt.legend() just before plt.show().
I'm using a library which produces 3 plots given an object k.
I need to figure the data points (x,y,z) that produced these plot, but the problem is that the plots comes from a function from k.
The library I'm using is pyKriging and this is their github repository.
A simplified version of their example code is:
import pyKriging
from pyKriging.krige import kriging
from pyKriging.samplingplan import samplingplan
sp = samplingplan(2)
X = sp.optimallhc(20)
testfun = pyKriging.testfunctions().branin
y = testfun(X)
k = kriging(X, y, testfunction=testfun, name='simple')
k.train()
k.plot()
The full code, comments and output can be found here.
In summary, I'm trying to get the numpy array that produced these plots so I can create plots that follows my formatting styles.
I'm not knowledgeable about going into library codes in Python and I appreciate any help!
There is no single data array that produces the plot. Instead many arrays used for plotting are generated inside the kriging plot function.
Changing the filled contours to line contours is of course not a style option. One therefore needs to use the code from the original plotting function.
An option is to subclass kriging and implement a custom plot function (let's call it myplot). In this function, one can use contour instead of contourf. Naturally, it's also possible to change it completely to one's needs.
import pyKriging
from pyKriging.krige import kriging
from pyKriging.samplingplan import samplingplan
import numpy as np
import matplotlib.pyplot as plt
class MyKriging(kriging):
def __init__(self,*args,**kwargs):
kriging.__init__(self,*args,**kwargs)
def myplot(self,labels=False, show=True, **kwargs):
fig = plt.figure(figsize=(8,6))
# Create a set of data to plot
plotgrid = 61
x = np.linspace(self.normRange[0][0], self.normRange[0][1], num=plotgrid)
y = np.linspace(self.normRange[1][0], self.normRange[1][1], num=plotgrid)
X, Y = np.meshgrid(x, y)
# Predict based on the optimized results
zs = np.array([self.predict([xi,yi]) for xi,yi in zip(np.ravel(X), np.ravel(Y))])
Z = zs.reshape(X.shape)
#Calculate errors
zse = np.array([self.predict_var([xi,yi]) for xi,yi in zip(np.ravel(X), np.ravel(Y))])
Ze = zse.reshape(X.shape)
spx = (self.X[:,0] * (self.normRange[0][1] - self.normRange[0][0])) + self.normRange[0][0]
spy = (self.X[:,1] * (self.normRange[1][1] - self.normRange[1][0])) + self.normRange[1][0]
contour_levels = kwargs.get("levels", 25)
ax = fig.add_subplot(222)
CS = plt.contour(X,Y,Ze, contour_levels)
plt.colorbar()
plt.plot(spx, spy,'or')
ax = fig.add_subplot(221)
if self.testfunction:
# Setup the truth function
zt = self.testfunction( np.array(zip(np.ravel(X), np.ravel(Y))) )
ZT = zt.reshape(X.shape)
CS = plt.contour(X,Y,ZT,contour_levels ,colors='k',zorder=2, alpha=0)
if self.testfunction:
contour_levels = CS.levels
delta = np.abs(contour_levels[0]-contour_levels[1])
contour_levels = np.insert(contour_levels, 0, contour_levels[0]-delta)
contour_levels = np.append(contour_levels, contour_levels[-1]+delta)
CS = plt.contour(X,Y,Z,contour_levels,zorder=1)
plt.plot(spx, spy,'or', zorder=3)
plt.colorbar()
ax = fig.add_subplot(212, projection='3d')
ax.plot_surface(X, Y, Z, rstride=3, cstride=3, alpha=0.4)
if self.testfunction:
ax.plot_wireframe(X, Y, ZT, rstride=3, cstride=3)
if show:
plt.show()
sp = samplingplan(2)
X = sp.optimallhc(20)
testfun = pyKriging.testfunctions().branin
y = testfun(X)
k = MyKriging(X, y, testfunction=testfun, name='simple')
k.train()
k.myplot()