Acquire x-axis values in Python matplotlib - python

Before I ask this question, I have already searched the internet for a while without success. To many experts this surely appears to be fairly simple. Please bear with me.
I am having a plot made by matplotlib and it is returned as a plf.Figure. See the following:
def myplotcode():
x = np.linspace(0, 2*np.pi)
y = np.sin(x)
print("x in external function", x)
y2 = np.cos(x)
fig = plf.Figure()
ax = fig.add_subplot(111)
ax.plot(x, y, 'bo', x, y2,'gs')
ax.set_ylabel("Some function")
return fig, ax
What I want to do in the function that call this one is to be able to get all these x values from the returned ax or fig. Well, I understand one simple solution is just to return x array too. However, I am trying to keep the number of returns as small as possible.
So, my question is: Can I acquire this x-axis array from fig or ax?
Thank you so much in advance.

You can do:
l = ax.axes.lines[0] # If you have more curves, just change the index
x, y = l.get_data()
That will give you two arrays, with the x and y data

Related

I would like to create a 3D surface plot with input variables that have different ranges

I've received an answer, but the question was closed due to not enough detail. I'm adding more information, in case this helps someone.
I posted a simplified version of the function I am working on. I gave: f(q, t) = k*q(1-t), where k is just some pre-defined constant. I wanted to create a 3D surface plot of f(q, t) for all q and t, when q and t lie on different intervals.
q is on the unit interval and t can be any value from 0 to some positive value z (excluding 1).
I found similar questions and answers but they addressed variables that were on the same interval. Some of the steps were unclear even after looking at guides. Specifically, I did not know how to combine intervals for q because I am new and did not know what else to search.
I have only done basic 2D plotting with excel data before so I did not know where to start other than defining the function. Hope this is enough detail for someone with a similar problem in the future.
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
def f(x, y):
return 2 * x * (1 - y)
x = np.linspace(0, 1, 50)
y = np.union1d(np.linspace(0, 0.99, 50), np.linspace(1.01, 2, 50))
X, Y = np.meshgrid(x, y)
Z = f(X, Y)
fig = plt.figure(figsize=(12,8))
ax = plt.axes(projection='3d')
ax.contour3D(X, Y, Z, 100, cmap='binary')
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('z');
Basically, you just need to adjust the example given here:
https://jakevdp.github.io/PythonDataScienceHandbook/04.12-three-dimensional-plotting.html.
The script is pretty self-explanatory.

Dynamically update plot Matplotlib Python (for unsteady heat diffusion)

I am new to python and trying to do what have been doing in MATLAB for so long. My current challenge is to dynamically update a plot without drawing a new figure in a for or while loop. I am aware there are similar questions and answers but most of them are too complicated and I believe it should be easier.
I got the example from here
https://pythonspot.com/matplotlib-update-plot/
But I can't see the figure, no error, no nothing. I added two lines just to see if I can see the static plot and I can.
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10*np.pi, 100)
y = np.sin(x)
# This is just a test just to see if I can see the plot window
plt.plot(x, y)
plt.show()
plt.ion()
fig = plt.figure()
ax = fig.add_subplot(111)
line1, = ax.plot(x, y, 'b-')
for phase in np.linspace(0, 10*np.pi, 100):
line1.set_ydata(np.sin(0.5 * x + phase))
fig.canvas.draw()
Any idea why I can't see the dynamic plot?
Thank you
Erdem
try to add plt.pause(0.0001) inside the loop after plt.show(block=False), and a final plt.show() outside the loop. This should work fine with plt.ion(); ref to some older answers Plot one figure at a time without closing old figure (matplotlib)

How to speed up Matplotlib?

I am new to Matplotlib and that's why there might be a more efficient way to run my program.
It is plotting a bunch of points with different colours (depending on some factors). It is constantly producing new pictures in a loop of the current colour state.
Basically it looks like this:
import matplotlib.pyplot as plt
def getColour():
#calculate some stuff with x and y and the changing factors
while True:
fig = plt.figure(figsize=(17,10))
plt.scatter(x, y , c=getColour())
plt.show()
plt.close(fig)
I was trying out clf() as well. However, it didn't change the pace at all. Does anyone have ideas? What am I doing wrong?
Thank you!
Edit:
The target is to produce a picture each time it goes through the loop. Since my program is doing this quite slowly, my question is whether there is a way to make it run faster.
I am working with python 2.7
Something like an animation:
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import numpy as np
ms_between_frames = 100
n_points = 100
x = np.arange(n_points, dtype=float) #EDIT
y = np.random.random(n_points)
z = np.random.random(n_points)
def getColour(x, y, z):
c = np.empty((len(x),3))
for i in range(len(x)):
c[i] = [x[i]/n_points, z[i], 1.-z[i]]
return c
def update(frame_number):
global x, y
z = np.random.random(n_points)
c = getColour(x, y, z)
graph.set_color(c)
fig = plt.figure(figsize=(17,10))
ax = fig.add_subplot(111)
graph = ax.scatter(x, y , c=getColour(x, y, z))
animation = FuncAnimation(fig, update, interval=ms_between_frames)
plt.show()
EDIT: made x hold floats so the division inside getColour would not return 0 (could also have made /float(n_points))
By the way, it should be possible to define only one function to update the colours, depending on the arguments you require to do so, to avoid the call overhead.

Can update .fill_betweenx() arguments? How?

I'm aware that it's possible to update the x and y values of a plot by using its artist with .set_xdata() and .set_ydata().
Can something similar be done with .fill_betweenx() to update its arguments ( y, x1, x2 and where ) to avoid clearing the axes and plotting it again?
It is somewhat a hack, there is a set_path method for the PolyCollection that fill_between returns, but it seems not to be functional. Have to directly assign new Path to _path:
from matplotlib.path import Path
x = [0,2,3,4,5]
y = [1,4,5,6,7]
z = [4,5,6,7,8]
PC = plt.fill_between(x, y, z)
PC._paths = [Path(np.vstack([[1,1,2,3,4,5,5,5,4,3,2,1,1],
[4,3,4,5,6,7,8,8,7,6,5,4,4]]).T,
np.array([1,2,2,2,2,2,2,2,2,2,2,2,9]))]
Before
After

How to plot with mplot3d

I am trying to plot the solutions of a minimization problem,
'X, Y = meshgrid(gammas, psis)'
gammas and psis are my 2 axes,
'mplot3d(X, Y, x)'
x is the solution of my problem,
While executing my script : name 'mplot3d' is not defined......
import pylab
def scatterme(x, y, z):
pylab.figure()
imi = pylab.scatter(x, y, c = z, edgecolor = "none")
pylab.colorbar(imi)
pylab.show()
In this case, my x and y are what for you would be X.flatten() and Y.flatten() and the z would be your x.flatten(). This code also works if your data does not come from something square, so if you just want to see what something looks like, if you have a lot of x and y values, and for each one you have a z, this shows you what you want as well.
Note: this is not a 3D plot, but i (personnal opinion) feel that a scatterplot in which the z-dimension is your colorbar seems to show much more what you need to know, compared to a 3D plot that you have to rotate around all the time, to be able to see at the angle that might show you something you want to know
Edit:
for the full code, that you can just copypaste (put this after the first piece in my post)
import numpy
X,Y = meshgrid(gammas, psis)
scatterme(X.flatten(), Y.flatten(), x.flatten())

Categories

Resources