How to scatter plot a two dimensional list in python? - python

How can I scatter plot a list of pairs with each axis of the plot representing one of the value in the pair in python? My list looks like this
[(62725984, 63548262), (64797631, 64619047), (65069350, 65398449), (58960696, 57416785), (58760119, 58666604), (60470606, 61338129), (60728760, 59001882)]

This should be easy. You can extract the pair into two variables as follows:
x,y = zip(*<name_of_your_2d_list>)
Also, you can pass the same to scatter function as
matplotlib.pyplot.scatter(*zip(*<name_of_your_2d_list>).
Try the following. It should work:
import matplotlib.pyplot, pylab
data = [(62725984, 63548262), (64797631, 64619047), (65069350, 65398449), (58960696, 57416785), (58760119, 58666604), (60470606, 61338129), (60728760, 59001882)]
matplotlib.pyplot.scatter(*zip(*data))
matplotlib.pyplot.show()

try below code:
import matplotlib.pyplot
import pylab
list1 = [(62725984, 63548262), (64797631, 64619047), (65069350, 65398449), (58960696, 57416785), (58760119, 58666604), (60470606, 61338129), (60728760, 59001882)]
list1 = list(zip(*list1))
pylab.scatter(list(list1[0]),list(list1[1]))
pylab.show()

You can use the function below.
import matplotlib.pyplot as plt
def scatter_plot(list):
x = []
y = []
for i in list:
x.append(i[0])
y.append(i[1])
plt.scatter(x,y)
plt.show()
And simply use this function as below.
scatter_plot(list_of_list)

Related

How to save multiple figure objects without knowing their variable names beforehand [duplicate]

I would like to:
pylab.figure()
pylab.plot(x)
pylab.figure()
pylab.plot(y)
# ...
for i, figure in enumerate(pylab.MagicFunctionReturnsListOfAllFigures()):
figure.savefig('figure%d.png' % i)
What is the magic function that returns a list of current figures in pylab?
Websearch didn't help...
Pyplot has get_fignums method that returns a list of figure numbers. This should do what you want:
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(100)
y = -x
plt.figure()
plt.plot(x)
plt.figure()
plt.plot(y)
for i in plt.get_fignums():
plt.figure(i)
plt.savefig('figure%d.png' % i)
The following one-liner retrieves the list of existing figures:
import matplotlib.pyplot as plt
figs = list(map(plt.figure, plt.get_fignums()))
Edit: As Matti Pastell's solution shows, there is a much better way: use plt.get_fignums().
import numpy as np
import pylab
import matplotlib._pylab_helpers
x=np.random.random((10,10))
y=np.random.random((10,10))
pylab.figure()
pylab.plot(x)
pylab.figure()
pylab.plot(y)
figures=[manager.canvas.figure
for manager in matplotlib._pylab_helpers.Gcf.get_all_fig_managers()]
print(figures)
# [<matplotlib.figure.Figure object at 0xb788ac6c>, <matplotlib.figure.Figure object at 0xa143d0c>]
for i, figure in enumerate(figures):
figure.savefig('figure%d.png' % i)
This should help you (from the pylab.figure doc):
call signature::
figure(num=None, figsize=(8, 6),
dpi=80, facecolor='w', edgecolor='k')
Create a new figure and return a
:class:matplotlib.figure.Figure
instance. If num = None, the
figure number will be incremented and
a new figure will be created.** The
returned figure objects have a
number attribute holding this number.
If you want to recall your figures in a loop then a good aproach would be to store your figure instances in a list and to call them in the loop.
>> f = pylab.figure()
>> mylist.append(f)
etc...
>> for fig in mylist:
>> fig.savefig()
Assuming you haven't manually specified num in any of your figure constructors (so all of your figure numbers are consecutive) and all of the figures that you would like to save actually have things plotted on them...
import matplotlib.pyplot as plt
plot_some_stuff()
# find all figures
figures = []
for i in range(maximum_number_of_possible_figures):
fig = plt.figure(i)
if fig.axes:
figures.append(fig)
else:
break
Has the side effect of creating a new blank figure, but better if you don't want to rely on an unsupported interface
I tend to name my figures using strings rather than using the default (and non-descriptive) integer. Here is a way to retrieve that name and save your figures with a descriptive filename:
import matplotlib.pyplot as plt
figures = []
figures.append(plt.figure(num='map'))
# Make a bunch of figures ...
assert figures[0].get_label() == 'map'
for figure in figures:
figure.savefig('{0}.png'.format(figure.get_label()))

How to make the function line break without manually def a piecewise function? [duplicate]

I am using matplotlib to plot some step functions from a dataframe
df['s1'].plot(c='b', drawstyle="steps-post")
df['s2'].plot(c='b', drawstyle="steps-post")
...
The result looks like
I would like to have this only plot the horizontal lines, not the vertical lines connecting the jump points. I could not find a straightforward parameter for plot that would seem to do that. Is there a way to do this?
There is no built-in option to produce a step function without vertical lines as far as I can tell. But you may easily build one yourself. The following uses the fact that np.nan is not plotted and cuts the line. So adding np.nan in between the steps suppresses the vertical line.
import matplotlib.pyplot as plt
import numpy as np
def mystep(x,y, ax=None, where='post', **kwargs):
assert where in ['post', 'pre']
x = np.array(x)
y = np.array(y)
if where=='post': y_slice = y[:-1]
if where=='pre': y_slice = y[1:]
X = np.c_[x[:-1],x[1:],x[1:]]
Y = np.c_[y_slice, y_slice, np.zeros_like(x[:-1])*np.nan]
if not ax: ax=plt.gca()
return ax.plot(X.flatten(), Y.flatten(), **kwargs)
x = [1,3,4,5,8,10,11]
y = [5,4,2,7,6,4,4]
mystep(x,y, color="crimson")
plt.show()
Seems like hlines is the "correct" (built-in) way to do this:
import matplotlib.pyplot as plt
x = [1,3,4,5,8,10,11]
y = [5,4,2,7,6,4]
plt.hlines(y,x[:-1],x[1:])
plt.show()

plt.scatter of 2-d array elements in a list

I have a list containing array elements:
[array([2.40460915, 0.85513601]), array([1.80998096, 0.97406986]), array([2.14505475, 0.96109123]),
array([2.12467111, 0.93991277])]
And I want to plot that list using mathplotlib, such that i iterate over each element in the list, and plot the ith element, using plt.scatter(x,y) where x is the first element of the array at the ith position, and similar for y the second element.
I am not super familiar with how to do this indexing in python, and no matter how I try to solve this, I cannot get a plot.
for i in range(len(list)):
# plt.scatter(x,y) for x,y as described above
Can anyone tell me an easy way to do this?
from numpy import array
import matplotlib.pyplot as plt
a = [array([2.40460915, 0.85513601]), array([1.80998096, 0.97406986]), array([2.14505475, 0.96109123]),
array([2.12467111, 0.93991277])]
# *i unpacks i into a tuple (i[0], i[1]), which is interpreted as (x,y) by plt.scatter
for i in a:
plt.scatter(*i)
plt.show()
You can zip the unpacked values of numpy array a.
One-liner to plot as you want:
plt.scatter(*zip(*a))
which is equivalent to x,y=zip(*a); plt.scatter(x,y)
import numpy as np
import matplotlib.pyplot as plt
a=[np.array([2.40460915, 0.85513601]), np.array([1.80998096, 0.97406986]), np.array([2.14505475, 0.96109123]), np.array([2.12467111, 0.93991277])]
plt.scatter(*zip(*a)) #x,y=zip(*a)
plt.show()
This would do it:
import matplotlib.pyplot as plt
import numpy as np
a= [np.array([2.40460915, 0.85513601]),
np.array([1.80998096, 0.97406986]),
np.array([2.14505475, 0.96109123]),
np.array([2.12467111, 0.93991277])]
plt.scatter([i[0] for i in a], [i[1] for i in a]) # just this line here
plt.show()
There are many solutions to this question. I write two that you will understand easily:
Solution 1: many scatters
for i in range(len(data)):
point = data[i] #the element ith in data
x = point[0] #the first coordenate of the point, x
y = point[1] #the second coordenate of the point, y
plt.scatter(x,y) #plot the point
plt.show()
Solution 2: one scatter (I recomend if you are not familiarizated with indexing)
x = []
y = []
for i in range(len(data)):
point = data[i]
x.append(point[0])
y.append(point[1])
plt.scatter(x,y)
plt.show()
try converting the array into pandas Dataframe by
data=pd.DataFrame(data='''array''')
and try plotting the datas

Pass variable to Ipython Widget

I have a simple widget that modifies a plot, here is the definition:
#Plot function
def plf(x,lm,ls):
plt.plot(x[lm:ls],np.sin(x)[lm:ls])
this function takes a list x an plot sin(x), lm and ls controls the number of data that is ploted, the problem is when i try to plot a determinated list of data, for example
list = [1,2,3,4,5,6,7,8,9]
and if i try
interact(plf,x=list,lm=(0,max(x)//2,1),ls=(max(x)//2,max(x),1))
throws me the error:
NameError: name 'x' is not defined
so, how can i define x so it can be any list that i want?
Is this what you are trying to do?
%matplotlib inline
from IPython.html.widgets import interact, fixed
import matplotlib.pyplot as plt
import numpy as np
def plf(x,lm,ls):
plt.plot(x[lm:ls],np.sin(x)[lm:ls])
data = [1,2,3,4,5,6,7,8,9]
max_lm = max(data)//2
max_ls = max(data)
interact(plf,x=fixed(data),lm=(0,max_lm,1),ls=(max_lm, max_ls,1))

Plot string values in matplotlib

I am using matplotlib for a graphing application. I am trying to create a graph which has strings as the X values. However, the using plot function expects a numeric value for X.
How can I use string X values?
From matplotlib 2.1 on you can use strings in plotting functions.
import matplotlib.pyplot as plt
x = ["Apple", "Banana", "Cherry"]
y = [5,2,3]
plt.plot(x, y)
plt.show()
Note that in order to preserve the order of the input strings on the plot you need to use matplotlib >=2.2.
You should try xticks
import pylab
names = ['anne','barbara','cathy']
counts = [3230,2002,5456]
pylab.figure(1)
x = range(3)
pylab.xticks(x, names)
pylab.plot(x,counts,"g")
pylab.show()
Why not just make the x value some auto-incrementing number and then change the label?
--jed
Here's one way which i know works, though i would think creating custom symbols is a more natural way accomplish this.
from matplotlib import pyplot as PLT
# make up some data for this example
t = range(8)
s = 7 * t + 5
# make up some data labels which we want to appear in place of the symbols
x = 8 * "dp".split()
y = map(str, range(8))
data_labels = [ i+j for i, j in zip(x, y)]
fig = PLT.figure()
ax1 = fig.add_subplot(111)
ax1.plot(t, s, "o", mfc="#FFFFFF") # set the symbol color so they are invisible
for a, b, c in zip(t, s, data_labels) :
ax1.text(a, b, c, color="green")
PLT.show()
So this puts "dp1", "dp2",... in place of each of the original data symbols--in essence creating custom "text symbols" though again i have to believe there's a more direct way to do this in matplotlib (without using Artists).
I couldn't find a convenient way to accomplish that, so I resorted to this little helper function.
import matplotlib.pyplot as p
def plot_classes(x, y, plotfun=p.scatter, **kwargs):
from itertools import count
import numpy as np
classes = sorted(set(x))
class_dict = dict(zip(classes, count()))
class_map = lambda x: class_dict[x]
plotfun(map(class_map, x), y, **kwargs)
p.xticks(np.arange(len(classes)), classes)
Then, calling plot_classes(data["class"], data["y"], marker="+") should work as expected.

Categories