Matplotlib changes the color of the bar when there are more values plotted :
With 5 columns I get the expected red bars :
ax = vc[vc.index[:5]].plot(color='red', kind='bar', title=col+('(count)'))
ax.set_axis_bgcolor('white')
But going for more values, the colors begin to fade and there is some grey bars appearing :(
ax = vc.plot(color='red', kind='bar', title=col+('(count)'))
ax.set_axis_bgcolor('white')
How can I keep My red bars all along ?
They probably become gray because of the edge colors of the bars:
import matplotlib.pylab as pl
import numpy as np
import pandas as p
pl.figure()
x = np.arange(5)
y = np.random.random(x.size)
vc1 = p.DataFrame(data=y, index=x)
x = np.arange(100)
y = np.random.random(x.size)
vc2 = p.DataFrame(data=y, index=x)
ax = pl.subplot(131)
vc1.plot(ax=ax, kind='bar', color='red')
ax = pl.subplot(132)
vc2.plot(ax=ax, kind='bar', color='red')
ax = pl.subplot(133)
vc2.plot(ax=ax, kind='bar', color='red', edgecolor='none')
Related
Could someone give me a tip on how to do multiple Y axis plots?
This is some made up data below, how could I put Temperature its own Y axis, Pressure on its own Y axis, and then have both Value1 and Value2 on the same Y axis. I am trying to go for the same look and feel of this SO post answer. Thanks for any tips, I don't understand ax3 = ax.twinx() process, like as far as do I need to define an ax.twinx() for each separate Y axis plot I need?
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
rows,cols = 8760,4
data = np.random.rand(rows,cols)
tidx = pd.date_range('2019-01-01', periods=rows, freq='H')
df = pd.DataFrame(data, columns=['Temperature','Value1','Pressure','Value2'], index=tidx)
# using subplots() function
fig, ax = plt.subplots(figsize=(25,8))
plt.title('Multy Y Plot')
ax2 = ax.twinx()
ax3 = ax.twinx()
ax4 = ax.twinx()
plot1, = ax.plot(df.index, df.Temperature)
plot2, = ax2.plot(df.index, df.Value1, color = 'r')
plot3, = ax3.plot(df.index, df.Pressure, color = 'g')
plot4, = ax4.plot(df.index, df.Value2, color = 'b')
ax.set_xlabel('Date')
ax.set_ylabel('Temperature')
ax2.set_ylabel('Value1')
ax3.set_ylabel('Pressure')
ax4.set_ylabel('Value2')
plt.legend([plot1,plot2,plot3,plot4],list(df.columns))
# defining display layout
plt.tight_layout()
# show plot
plt.show()
This will output everything jumbled up on the same side without separate Y axis for Pressure, Value1, and Value2.
You are adding 4 different plots in one, which is not helpful. I would recommend breaking it into 2 plots w/ shared x-axis "Date":
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
rows,cols = 8760,4
data = np.random.rand(rows,cols)
tidx = pd.date_range('2019-01-01', periods=rows, freq='H')
df = pd.DataFrame(data, columns=['Temperature','Value1','Pressure','Value2'], index=tidx)
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(25,8))
plt.title('Multy Y Plot')
ax1b = ax1.twinx()
plot1a, = ax1.plot(df.index, df.Temperature)
plot1b, = ax1b.plot(df.index, df.Pressure, color='r')
ax1.set_ylabel('Temperature')
ax1b.set_ylabel('Pressure')
ax2b = ax2.twinx()
plot2a, = ax2.plot(df.index, df.Value1, color='k')
plot2b, = ax2b.plot(df.index, df.Value2, color='g')
ax2.set_xlabel('Date')
ax2.set_ylabel('Value1')
ax2b.set_ylabel('Value2')
plt.legend([plot1a, plot1b, plot2a, plot2b], df.columns)
# defining display layout
plt.tight_layout()
# show plot
plt.show()
Here I have added in the first plot (on the top) Temperature and Pressure and on the second plot (on the bottom) Value 1 and Value 2. Normally, we add in the same plot things that make sense to compare on the same x-axis. Pressure and Temperature is a valid combination that is why I combined those two together. But you can do as you wish.
This answer below uses mpatches is how to make the subplot of Value1 and Value2 on the same axis. The solution for this post has subplot for Value1 and Value2 on different axis. Thanks for the help #tzinie!
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
rows,cols = 8760,4
data = np.random.rand(rows,cols)
tidx = pd.date_range('2019-01-01', periods=rows, freq='H')
df = pd.DataFrame(data, columns=['Temperature','Value1','Pressure','Value2'], index=tidx)
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(25,8))
plt.title('Multy Y Plot')
ax1b = ax1.twinx()
plot1a, = ax1.plot(df.index, df.Temperature, color='r') # red
plot1b, = ax1b.plot(df.index, df.Pressure, color='b') # blue
ax1.set_ylabel('Temperature')
ax1b.set_ylabel('Pressure')
ax2.plot(df.index, df.Value1, color='k') # black
ax2.plot(df.index, df.Value2, color='g') # green
ax2.set_xlabel('Date')
ax2.set_ylabel('Value1 & Value2')
red_patch = mpatches.Patch(color='red', label='Temperature')
blue_patch = mpatches.Patch(color='blue', label='Pressure')
green_patch = mpatches.Patch(color='green', label='Value2')
black_patch = mpatches.Patch(color='black', label='Value1')
plt.legend(handles=[red_patch,blue_patch,green_patch,black_patch])
# defining display layout
#plt.tight_layout()
# show plot
plt.show()
I have data where I have names, proportions and total. I want to show all 3 variables in one plot. Ideally I want to have everything like plot 1 but inside I want to show total as in plot 2
In first plot I don't get line right also this is not my plot of choice.
import pandas as pd
from matplotlib import pyplot as plt
import seaborn as sns
df = pd.DataFrame({"name": list("ABCDEFGHIJ"), "proportion": [0.747223, 0.785883, 0.735542, 0.817368, 0.565193, 0.723029, 0.723004, 0.722595, 0.783929, 0.55152],
"total": [694327, 309681, 239384, 201646, 192267, 189399, 181974, 163483, 157902, 153610]})
fig, ax1 = plt.subplots()
ax2 = ax1.twinx()
sns.barplot(data=df, x="name", y="total", color="lightblue", ax=ax1)
sns.lineplot(data=df, x="name", y= "proportion", color="black", lw=3, ls="--", ax=ax2)
# Plot the figure.
df["male"] = df.proportion * df.total
ax = sns.barplot(data = df, x= "name", y = 'total', color = "lightblue")
sns.barplot(data = df, x="name", y = "male", color = "blue", ax = ax)
ax.set_ylabel("male/no_of_streams")
Is there a way I can achieve my goal of effective plot where
I can show total split
I also want to add proportions values to plot as well
Any help would be appreciated
Thanks in advance
If my understanding is right, for the first plot, I guess you wanna to know why the line is dashed. Just remove argument ls="--", you will get solid line.
The second, following code can work, if you want percentage of "man-number" / "total". If the percentage is computed using other numbers, you can adjust the equation in the for statement:
import pandas as pd
from matplotlib import pyplot as plt
import seaborn as sns
if __name__ == '__main__':
df = pd.DataFrame({"name": list("ABCDEFGHIJ"), "proportion": [0.747223, 0.785883, 0.735542, 0.817368, 0.565193, 0.723029, 0.723004, 0.722595, 0.783929, 0.55152], "total": [694327, 309681, 239384, 201646, 192267, 189399, 181974, 163483, 157902, 153610]})
# fig, ax1 = plt.subplots()
# ax2 = ax1.twinx()
# sns.barplot(data=df, x="name", y="total", color="lightblue", ax=ax1)
# # remove ls='--'
# sns.lineplot(data=df, x="name", y="proportion", color="black", lw=3, ax=ax2)
# Plot the figure.
df["male"] = df.proportion * df.total
ax = sns.barplot(data = df, x= "name", y = 'total', color = "lightblue")
sns.barplot(data = df, x="name", y = "male", color = "blue", ax = ax)
ax.set_ylabel("proportion(male/no_of_streams)")
# this is code block to add percentage
for i, v in enumerate(df['proportion']):
p = ax.patches[i]
height = p.get_height()
ax.text(p.get_x()+p.get_width()/2.,
height + 3,
'{:1.0f}%'.format(v * 100),
ha="center")
plt.show()
BTW, I learn at this page, FYI.
I'm trying to make a bar plot with a color bar, each bar's hight is one variable (y) and each bar should have a color depending on another variable (c).
What I've got to is this (simple example):
data_x = [0,1,2,3]
data_hight = [60,60,80,100]
data_color = [1000,500,1000,900]
data_color = [x / max(data_color) for x in data_color]
fig, ax = plt.subplots(figsize=(15, 4))
my_cmap = plt.cm.get_cmap('GnBu')
colors = my_cmap(data_color)
rects = ax.bar(data_x, data_hight, color=colors)
CS = plt.contourf([data_x, data_color],cmap=my_cmap)
cbar = plt.colorbar(CS, cmap=my_cmap)
cbar.set_label('Color', rotation=270,labelpad=25)
plt.xticks(data_x)
plt.ylabel("Y")
plt.show()
The main problem is that the histogram colors are fine but the color bar is in a diferent scale. besides that I can see a blue line at y=0, it shouldn't be there.
Any help will be a preciated.
Thanks!
You are creating a contourf plot inside your bar plot. That makes no sense.
Instead you would need to create a mappable without any visual representation to supply to the colorbar. This would be a ScalarMappable.
import matplotlib.pyplot as plt
from matplotlib.cm import ScalarMappable
data_x = [0,1,2,3]
data_hight = [60,60,80,100]
data_color = [1000.,500.,1000.,900.]
data_color = [x / max(data_color) for x in data_color]
fig, ax = plt.subplots(figsize=(15, 4))
my_cmap = plt.cm.get_cmap('GnBu')
colors = my_cmap(data_color)
rects = ax.bar(data_x, data_hight, color=colors)
sm = ScalarMappable(cmap=my_cmap, norm=plt.Normalize(0,max(data_color)))
sm.set_array([])
cbar = plt.colorbar(sm)
cbar.set_label('Color', rotation=270,labelpad=25)
plt.xticks(data_x)
plt.ylabel("Y")
plt.show()
I'm trying to draw clean graphs using matplotlib.
Here is my code:
fig = plt.figure(figsize = (6,6))
plt.grid(True)
plt.xlabel('time (s)',fontweight='bold')
plt.ylabel('density',fontweight='bold')
plt.plot(data1, data2, color = 'y', linewidth = 2)
plt.show()
the floats in data2 lies between 0.0001 and 0.001, so When I do this, the y axis has ticks like '0.0001' '0.0002' etc.
How can I force the ticks to be in scientific notation ('1e-3', '1e-4' etc. ) ?
thx :)
This sets it like 1e-04:
import matplotlib.pyplot as plt
import matplotlib.ticker as mtick
data1 = [1,2,3,4,5]
data2 = [1e4,3e4,4e4,2e4,5e4]
fig = plt.figure(figsize = (6,6))
plt.grid(True)
plt.xlabel('time (s)',fontweight='bold')
plt.ylabel('density',fontweight='bold')
plt.plot(data1, data2, color = 'y', linewidth = 2)
plt.gca().yaxis.set_major_formatter(mtick.FormatStrFormatter('%.0e'))
plt.show()
I would like to ask how to produce a plot similar to that in the figure below? Basically, how to have x-axis at the top of the figure. Thanks
Image from: http://oceanographyclay1987.blogspot.com/2010/10/light-attenuation-in-ocean.html
Use
ax.xaxis.set_ticks_position("top")
For example,
import numpy as np
import matplotlib.pyplot as plt
numdata = 100
t = np.linspace(0, 100, numdata)
y = 1/t**(1/2.0)
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
ax.xaxis.set_ticks_position('top')
ax.yaxis.grid(linestyle = '-', color = 'gray')
ax.invert_yaxis()
ax.plot(t, y, 'g-', linewidth = 1.5)
plt.show()