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

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:

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()

Plot a 3 line graphs on a scatter plot_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')

matplotlib 3d: moving tick's label

Is there a way to move tick labels in Matplot3dlib like this?
from mpl_toolkits import mplot3d
import numpy as np
import matplotlib.pyplot as plt
x = np.outer(np.linspace(-2, 2, 30), np.ones(30))
y = x.copy().T # transpose
z = np.cos(x ** 2 + y ** 2)
fig = plt.figure()
ax = plt.axes(projection='3d')
ax.plot_surface(x, y, z,cmap='viridis', edgecolor='none')
ax.set_title('Surface plot')
plt.show()
There are some ways using pad parameters.
However, I want to move more precisely like figure in the link above.
Any help appreciated.
-- Addition --
When I changing PAD parameter like the code below, the tick's label is more closer to the axis. However, I want to move it a little bit more to -x direction.
tick's label position changing
from mpl_toolkits import mplot3d
import numpy as np
import matplotlib.pyplot as plt
x = np.outer(np.linspace(-2, 2, 30), np.ones(30))
y = x.copy().T # transpose
z = np.cos(x ** 2 + y ** 2)
fig = plt.figure()
ax = plt.axes(projection='3d')
ax.plot_surface(x, y, z,cmap='viridis', edgecolor='none')
ax.set_title('Surface plot')
ax.tick_params(axis='x', which='major', pad=-5)
plt.show()

How to connect the dots with a line?

I was able to plot the dots from an image. I am now trying to connect the dots using a line. Essentially mimicking those connect the dot puzzles.
This is my code:
from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
original_image = Image.open("jg.jpg")
bw_image = original_image.convert('1')
bw_image_array = np.array(bw_image, dtype=np.int)
black_indices = np.argwhere(bw_image_array == 0)
chosen_black_indices = black_indices[np.random.choice(black_indices.shape[0], replace=False, size=90000)]
plt.figure(figsize=(5, 5), dpi=100)
plt.scatter([x[1] for x in chosen_black_indices], [x[0] for x in chosen_black_indices], color='black', s=1)
plt.gca().invert_yaxis()
plt.xticks([])
plt.yticks([])
plt.show()
I am aiming for this:
import numpy as np
import matplotlib.pyplot as plt
x = np.random.random_sample(size=100)
y = np.random.random_sample(size=100)
fig, ax = plt.subplots()
ax.scatter(x,y)
plt.plot(x, y, '-o')
plt.show()
I am struggling with what would go inside of plt.plot() in order to connect the dots of the image.
It looks like you have the answer there in your second code block. Matplotlib's plot function can handle plotting connected points with the marker='o' argument, so you don't need to call scatter at all. So just change this line:
plt.scatter([x[1] for x in chosen_black_indices],
[x[0] for x in chosen_black_indices],
color='black', s=1)
to this:
plt.plot([x[1] for x in chosen_black_indices],
[x[0] for x in chosen_black_indices],
marker='o',
color='black')

How to specify ticks formatter for several subplots

I need to specify ticks formatter for each plot of several subplots:
import numpy as np
import pylab as plt
import matplotlib.ticker as ticker
x = np.arange(10)
y = x
fig = plt.figure()
for i in [1, 2, 3]:
ax = fig.add_subplot(3, 1, i)
ax.plot(x, y)
ticks = ticker.FuncFormatter(lambda x, pos: '{}:{:g}'.format(i, x))
ax.xaxis.set_major_formatter(ticks)
plt.show()
But only the last (bottom) fotmatter is used for all other plots. What I do wrong?
You can use a ticker.FormatStrFormatter object as shown below.
I believe the problem with your original approach was that you were setting the Formatter for each axis to the tick variable and then overwriting it on the next iteration, as such all your graphs were using the tick variable from the last iteration.
When you create Formatter objects you have to have one for each subplot, in my code below it's not a problem because I don't assign the FormatStrFormatter to a variable.
import numpy as np
import pylab as plt
import matplotlib.ticker as ticker
x = np.arange(10)
y = x
fig, axes = plt.subplots(nrows=3, ncols=1)
for i, ax in enumerate(axes):
ax.plot(x, y)
ax.xaxis.set_major_formatter(ticker.FormatStrFormatter('{}:%d'.format(i+1)))
plt.show()
EDIT
Here is a version which uses the original FuncFormatter formatter object. The map method creates three separate ticker objects from their associated lambda functions. The for loop iterates over both ax and tick to assign each subplot.
import numpy as np
import pylab as plt
import matplotlib.ticker as ticker
x = np.arange(10)
y = x
fig, axes = plt.subplots(nrows=3, ncols=1)
def create_ticker(i):
# Create a FuncFormatter.
return ticker.FuncFormatter(lambda x, pos: '{}:{:g}'.format(i+1, x))
ticks = map(create_ticker, range(3))
for ax, tick in zip(axes, ticks):
ax.plot(x, y)
ax.xaxis.set_major_formatter(tick)
plt.show()

Categories