I'm to Python and learning it by doing. I want to make two plots with matplotlib in Python. The second plot keeps the limits of first one. Wonder how I can change the limits of each next plot from previous. Any help, please. What is the recommended method?
X1 = [80, 100, 120, 140, 160, 180, 200, 220, 240, 260]
Y1 = [70, 65, 90, 95, 110, 115, 120, 140, 155, 150]
from matplotlib import pyplot as plt
plt.plot(
X1
, Y1
, color = "green"
, marker = "o"
, linestyle = "solid"
)
plt.show()
X2 = [80, 100, 120, 140, 160, 180, 200]
Y2 = [70, 65, 90, 95, 110, 115, 120]
plt.plot(
X2
, Y2
, color = "green"
, marker = "o"
, linestyle = "solid"
)
plt.show()
There are two ways:
The quick and easy way; set the x and y limits in each plot to what you want.
plt.xlim(60,200)
plt.ylim(60,200)
(for example). Just paste those two lines just before both plt.show() and they'll be the same.
The harder, but better way and this is using subplots.
# create a figure object
fig = plt.figure()
# create two axes within the figure and arrange them on the grid 1x2
ax1 = fig.add_Subplot(121)
# ax2 is the second set of axes so it is 1x2, 2nd plot (hence 122)
# they won't have the same limits this way because they are set up as separate objects, whereas in your example they are the same object that is being re-purposed each time!
ax2 = fig.add_Subplot(122)
ax1.plot(X1,Y1)
ax2.plot(X2,Y2)
Here is one way for you using subplot where plt.subplot(1, 2, 1) means a figure with 1 row (first value) and 2 columns (second value) and 1st subfigure (third value in the bracket, meaning left column in this case). plt.subplot(1, 2, 2) means subplot in the 2nd column (right column in this case).
This way, each figure will adjust the x- and y-limits according to the data. There are another ways to do the same thing. Here is a SO link for you.
from matplotlib import pyplot as plt
fig = plt.figure(figsize=(10, 4))
plt.subplot(1, 2, 1)
X1 = [80, 100, 120, 140, 160, 180, 200, 220, 240, 260]
Y1 = [70, 65, 90, 95, 110, 115, 120, 140, 155, 150]
plt.plot(X1, Y1, color = "green", marker = "o", linestyle = "solid")
# plt.plot(X1, Y1, '-go') Another alternative to plot in the same style
plt.subplot(1, 2, 2)
X2 = [80, 100, 120, 140, 160, 180, 200]
Y2 = [70, 65, 90, 95, 110, 115, 120]
plt.plot(X2, Y2, color = "green", marker = "o", linestyle = "solid")
# plt.plot(X2, Y2, '-go') Another alternative to plot in the same style
Output
Related
I'm new to python and I am trying to make re-arrange the rectangle from raw data. I'm using bin packing algorithmn and I want to sort it with color like below. Please need help?
Output Now:
Expected Output:
There are small changes in the code please follow below code once:
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
fig = plt.figure()
ax = fig.add_subplot(111)
temp_y=0
i=0
layout_height = 300
layout_width = 300
ax.set_xlim([0, layout_height])
ax.set_ylim([0, layout_width])
area_height = [80, 75, 50, 60, 52, 72, 100, 120, 150]
area_width = [50, 46, 52, 52, 50, 48, 25, 40, 48]
for (i,j) in zip(area_height, area_width):
print(i,j)
ax.add_patch(Rectangle((0, temp_y), float(j), float(i),edgecolor ='black',facecolor = 'red'))
temp_y = temp_y + float(i)
I'm trying to use seaborn to create a colored bubbleplot of 3-D points (x,y,z), each coordinate being an integer in range [0,255]. I want the axes to represent x and y, and the hue color and size of the scatter bubbles to represent the z-coordinate.
The code:
import seaborn
seaborn.set()
import pandas
import matplotlib.pyplot
x = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 200]
y = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 200]
z = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 200]
df = pandas.DataFrame(list(zip(x, y, z)), columns =['x', 'y', 'z'])
ax = seaborn.scatterplot(x="x", y="y",
hue="z",
data=df)
matplotlib.pyplot.xlim(0,255)
matplotlib.pyplot.ylim(0,255)
matplotlib.pyplot.show()
gets me pretty much what I want:
This however makes the hue range be based on the data in z. I instead want to set the range according to the range of the min and max z values (as 0,255), and then let the color of the actual points map onto that range accordingly (so if a point has z-value 50, then that should be mapped onto the color represented by the value 50 in the range [0,255]).
My summarized question:
How to manually set the hue color range of a numerical variable in a scatterplot using seaborn?
I've looked thoroughly online on many tutorials and forums, but have not found an answer. I'm not sure I've used the right terminology. I hope my message got across.
Following #JohanC's suggestion of using hue_norm was the solution. I first tried doing so by removing the [hue=] parameter and only using the [hue_norm=] parameter, which didn't produce any colors at all (which makes sense).
Naturally one should use both the [hue=] and the [hue_norm=] parameters.
import seaborn
seaborn.set()
import pandas
import matplotlib.pyplot
x = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 200]
y = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 200]
z = [0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 255]
df = pandas.DataFrame(list(zip(x, y, z, my_sizes)), columns =['x', 'y', 'z'])
ax = seaborn.scatterplot(x="x", y="y",
hue="z",
hue_norm=(0,255), # <------- the solution
data=df)
matplotlib.pyplot.xlim(0,255)
matplotlib.pyplot.ylim(0,255)
matplotlib.pyplot.show()
I have a scatter plot created from two columns of a pandas data frame and I would like to add a line across each axis representing the average. Is this possible with a scatter plot?
plt.title("NFL Conversion Rates", fontsize=40)
# simulating a pandas df['team'] column
types = df.Tm
x_coords = df['3D%']
y_coords = df['4D%']
binsy = [15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85]
binsx = [30,35,40,45,50,55]
avg_y = y_coords.mean()
avg_y = round(avg_y, 1)
display(avg_y)
avg_x = x_coords.mean()
avg_x = round(avg_x, 1)
display(avg_x)
for i,type in enumerate(types):
x = x_coords[i]
y = y_coords[i]
plt.scatter(x, y, s=30, marker='o', edgecolor='black', cmap='purple', linewidth=1, alpha = 0.5)
plt.text(x+0.2, y+0.1, type, fontsize=14)
plt.xlabel('3rd Down Conversion Percentage',fontsize=30)
plt.ylabel('4th Down Conversion Percentage', fontsize=30)
plt.xticks(binsx)
plt.yticks(binsy)
You can try
plt.axvline(<value>,color='red',ls='--') and plt.axhline(<value>,color='red',ls='--'). Substitute with the value at which you want the lines
I'm trying to plot a Pandas DataFrame, and add a line to show the mean and median. As you can see below, I'm adding a red line for the mean, but it doesn't show.
If I try to draw a green line at 5, it shows at x=190. So apparently the x values are treated as 0, 1, 2, ... rather than 160, 165, 170, ...
How can I draw lines so that their x values match those of the x axis?
From Jupyter:
Full code:
%matplotlib inline
from pandas import Series
import matplotlib.pyplot as plt
heights = Series(
[165, 170, 195, 190, 170,
170, 185, 160, 170, 165,
185, 195, 185, 195, 200,
195, 185, 180, 185, 195],
name='Heights'
)
freq = heights.value_counts().sort_index()
freq_frame = freq.to_frame()
mean = heights.mean()
median = heights.median()
freq_frame.plot.bar(legend=False)
plt.xlabel('Height (cm)')
plt.ylabel('Count')
plt.axvline(mean, color='r', linestyle='--')
plt.axvline(5, color='g', linestyle='--')
plt.show()
Use plt.bar(freq_frame.index,freq_frame['Heights']) to plot your bar plot. Then the bars will be at freq_frame.index positions. Pandas in-build bar function does not allow for specifying positions of the bars, as far as I can tell.
%matplotlib inline
from pandas import Series
import matplotlib.pyplot as plt
heights = Series(
[165, 170, 195, 190, 170,
170, 185, 160, 170, 165,
185, 195, 185, 195, 200,
195, 185, 180, 185, 195],
name='Heights'
)
freq = heights.value_counts().sort_index()
freq_frame = freq.to_frame()
mean = heights.mean()
median = heights.median()
plt.bar(freq_frame.index,freq_frame['Heights'],
width=3,align='center')
plt.xlabel('Height (cm)')
plt.ylabel('Count')
plt.axvline(mean, color='r', linestyle='--')
plt.axvline(median, color='g', linestyle='--')
plt.show()
So I've got some data which I wish to plot via a frequency density (unequal class width) histogram, and via some searching online, I've created this to allow me to do this.
import numpy as np
import matplotlib.pyplot as plt
plt.xkcd()
freqs = np.array([3221, 1890, 866, 529, 434, 494, 382, 92, 32, 7, 7])
bins = np.array([0, 5, 10, 15, 20, 30, 50, 100, 200, 500, 1000, 1500])
widths = bins[1:] - bins[:-1]
heights = freqs.astype(np.float)/widths
plt.xlabel('Cost in Pounds')
plt.ylabel('Frequency Density')
plt.fill_between(bins.repeat(2)[1:-1], heights.repeat(2), facecolor='steelblue')
plt.show()
As you may see however, this data stretches into the thousands on the x axis and on the y axis (density) goes from tiny data (<1) to vast data (>100). To solve this I will need to break both axis. The closest to help I've found so far is this, which I've found hard to use. Would you be able to help?
Thanks, Aj.
You could just use a bar plot. Setting the xtick labels to represent the bin values.
With logarithmic y scale
import numpy as np
import matplotlib.pyplot as plt
plt.xkcd()
fig, ax = plt.subplots()
freqs = np.array([3221, 1890, 866, 529, 434, 494, 382, 92, 32, 7, 7])
freqs = np.log10(freqs)
bins = np.array([0, 5, 10, 15, 20, 30, 50, 100, 200, 500, 1000, 1500])
width = 0.35
ind = np.arange(len(freqs))
rects1 = ax.bar(ind, freqs, width)
plt.xlabel('Cost in Pounds')
plt.ylabel('Frequency Density')
tick_labels = [ '{0} - {1}'.format(*bin) for bin in zip(bins[:-1], bins[1:])]
ax.set_xticks(ind+width)
ax.set_xticklabels(tick_labels)
fig.autofmt_xdate()
plt.show()