I can write 'A circumflex' as a label on a graph in Python:
df = pd.DataFrame({'x':(0,3,4,0),'y':(3,0,4,3)})
fig, ax = plt.subplots(1,1)
df.plot(x='x', y='y', ax=ax, label='A\u0302', linewidth=5, color='k', linestyle='-')
for item in ([ax.title, ax.xaxis.label, ax.yaxis.label] +
ax.get_xticklabels() + ax.get_yticklabels()):
item.set_fontsize(22)
legend = ax.legend(loc=0, ncol=1, bbox_to_anchor=(0.9, -.3, .6, 1),
fancybox=True, shadow=False,
framealpha=1, fontsize=22)
plt.setp(legend.get_title(),fontsize=22)
This gives:
How can I get the circumflex larger please?
Thanks to Mr. T & tmdavison, either $^{A}$ or $\hat{A}$ work for some reason:
df = pd.DataFrame({'x':(0,3,4,0),'y':(3,0,4,3)})
fig, ax = plt.subplots(1,1)
df.plot(x='x', y='y', ax=ax, label='$A\u0302$', linewidth=5, color='k', linestyle='-')
df.plot(x='x', y='y', ax=ax, label='$\^{A}$', linewidth=5, color='k', linestyle='-')
df.plot(x='x', y='y', ax=ax, label='$\hat{A}$', linewidth=5, color='k', linestyle='-')
for item in ([ax.title, ax.xaxis.label, ax.yaxis.label] +
ax.get_xticklabels() + ax.get_yticklabels()):
item.set_fontsize(22)
legend = ax.legend(loc=0, ncol=1, bbox_to_anchor=(0.9, -.3, .6, 1),
fancybox=True, shadow=False,
framealpha=1, fontsize=22)
plt.setp(legend.get_title(),fontsize=22)
Related
I have the following code for a Matplotlib plot:
import pandas as pd
from matplotlib import pyplot as plt
columns = ['Price']
price_values = [[4.2],
[4.1],
[4],
[3.8],
[3.9],
[4.2],
[4.5],
[4.8],
[5.2],
[5.2],
[5.2],
[5.6],
[5.2],
[5.1],
[5.3],
[6],
[6.2],
[6.3],
[6.2],
[6],
[5.5] ,
[5.2],
[4.8],
[4.6]]
price_data = pd.DataFrame(price_values, index=range(0, 24), columns=columns)
fig = plt.figure(linewidth=1, figsize=(9, 5))
ax=plt.gca()
for column,color in zip(price_data.columns,['gold']):
ax.fill_between(
x=price_data.index,
y1=price_data[column],
y2=0,
label=column,
color=color,
alpha=.5,
step='post',
linewidth=5,
)
ax.set_facecolor("white")
ax.set_xlabel("Time of day", fontsize = 14, labelpad=8)
ax.set_ylabel("Price [Cent/kWh]", fontsize = 14,labelpad=8)
ax.set_xlim(0, 23)
ax.set_ylim(0, 8)
plt.xticks(price_data.index, labels=[f'{h:02d}:00' for h in price_data.index], rotation=90)
plt.tight_layout()
hours = list(range(25))
labels = [f'{h:02d}:00' for h in hours]
ax.tick_params(axis='both', which='major', labelsize=14)
ax.legend(loc='center left', bbox_to_anchor=(0.15, 1.07), fontsize = 14, ncol=3)
plt.savefig('Diagramm.png', edgecolor='black', dpi=400, bbox_inches='tight')
plt.show()
Now I would like to remove the area under the curve, sucht that I can only see the curve. I tried to use
plt.bar(fill=False)
but I get the error "TypeError: bar() missing 2 required positional arguments: 'x' and 'height'". Any suggestions how I can do that
Using fill_between and later remove the area under the curve seems like a pretty convoluted way to plot your data. But you could just set y2=price_data[column]:
price_data = pd.DataFrame(price_values, index=range(0, 24), columns=columns)
fig = plt.figure(linewidth=1, figsize=(9, 5))
ax=plt.gca()
for column,color in zip(price_data.columns,['gold']):
ax.fill_between(
x=price_data.index,
y1=price_data[column],
y2=price_data[column],
label=column,
color=color,
alpha=.5,
step='post',
linewidth=5,
)
ax.set_facecolor("white")
ax.set_xlabel("Time of day", fontsize = 14, labelpad=8)
ax.set_ylabel("Price [Cent/kWh]", fontsize = 14,labelpad=8)
ax.set_xlim(0, 23)
ax.set_ylim(0, 8)
plt.xticks(price_data.index, labels=[f'{h:02d}:00' for h in price_data.index], rotation=90)
plt.tight_layout()
hours = list(range(25))
labels = [f'{h:02d}:00' for h in hours]
ax.tick_params(axis='both', which='major', labelsize=14)
ax.legend(loc='center left', bbox_to_anchor=(0.15, 1.07), fontsize = 14, ncol=3)
plt.savefig('Diagramm.png', edgecolor='black', dpi=400, bbox_inches='tight')
plt.show()
Output:
Edit: #JohanC rightfully noted that the last value barely appears on the plot. One way to avoid this would be to replace your loop with the following:
price_data.plot(ax=ax, color="gold", drawstyle="steps-mid", linewidth=2)
Note that your solution is missing the last price value, the one between 23 and 24 h. You'll need to repeat the last value for this to work. To draw a step plot, the easiest way is ax.step.
The following example code changes the values for the first and the last value to make them stand out more.
from matplotlib import pyplot as plt
import pandas as pd
columns = ['Price']
price_values = [[1.2], [4.1], [4], [3.8], [3.9], [4.2], [4.5], [4.8], [5.2], [5.2], [5.2], [5.6], [5.2], [5.1], [5.3], [6], [6.2], [6.3], [6.2], [6], [5.5], [5.2], [4.8], [1.6]]
price_data = pd.DataFrame(price_values, index=range(0, 24), columns=columns)
fig, ax = plt.subplots(figsize=(9, 5))
for column, color in zip(price_data.columns, ['gold']):
ax.step(x=range(len(price_data) + 1), y=list(price_data[column]) + list(price_data[column][-1:]),
where='post', color=color, linewidth=5, label=column)
ax.set_xlabel("Time of day", fontsize=14, labelpad=8)
ax.set_ylabel("Price [Cent/kWh]", fontsize=14, labelpad=8)
ax.set_xlim(0, 24)
ax.set_ylim(0, 8)
xs = range(len(price_data) + 1)
ax.set_xticks(xs, labels=[f'{h:02d}:00' for h in xs], rotation=90)
ax.tick_params(axis='both', which='major', labelsize=14)
ax.legend(loc='lower left', bbox_to_anchor=(0.15, 1.01), fontsize=14, ncol=3)
plt.tight_layout()
plt.savefig('Diagramm.png', edgecolor='black', dpi=400, bbox_inches='tight')
plt.show()
Alternatively, you could use Seaborn's histplot, which has a step option (element='step', fill=False), but that works easiest if you'd let seaborn do the counting for the histogram. You could use sns.histplot's weights= parameter to fill in the values, e.g.
sns.histplot(x=price_data.index, weights=price_data[column].values, bins=len(price_data), binrange=(0, 24),
element='step', fill=False, color=color, linewidth=5, label=column, ax=ax)
I tried using
ax = pintar_campo('grey')
df_suarez.plot(kind='scatter', x='x<=17', y='y', color='light blue', ax=ax)
df_suarez.plot(kind='scatter', x='x>17 & x<=50', y='y', color='blue', ax=ax)
df_suarez.plot(kind='scatter', x='x>50 & x<=83', y='y', color='dark blue', ax=ax)
df_suarez.plot(kind='scatter', x='x>83', y='y', color='purple', ax=ax)
ax.set_title("Los eventos de Luís Suárez")
I have 4 zones and which zone have your condition:
Zone 1: x <= 17
Zone 2: x > 17 and x <=50
Zone 3: x>50 and x <=83
Zone 4: x>83
You can filter the dataframe with your condition first.
df.query('x<=17').plot(kind='scatter', x='x', y='y', color='red', ax=ax)
df.query('x>17& x<=50').plot(kind='scatter', x='x', y='y', color='blue', ax=ax)
df.query('x>50& x<=83').plot(kind='scatter', x='x', y='y', color='black', ax=ax)
df.query('x>83').plot(kind='scatter', x='x', y='y', color='purple', ax=ax)
# pr
df[df['x']<=17].plot(kind='scatter', x='x', y='y', color='red', ax=ax)
When plotting with twinx how can multiple subplots be used?
%pylab inline
import pandas as pd
import seaborn as sns; sns.set()
df = pd.DataFrame({'dt':['2020-01-01', '2020-01-02', '2020-01-03', '2020-01-04'], 'category':['a', 'b', 'a', 'b'], 'foo':[10, 15, 8, 13], 'bar':[12, 8, 5, 18]})
df['dt'] = pd.to_datetime(df['dt'])
ax = sns.lineplot(x='dt', y='foo', data=df, hue='category')
ax.set_ylabel('asdf', fontsize=28)
ax.plot([], '-g', label = 'other axis in legend')
plt.legend(fontsize='x-large')
handles, labels = ax.get_legend_handles_labels()
ax.legend(handles=handles[1:], labels=labels[1:], fontsize='large', loc='lower left')
plt.xticks(rotation=90, horizontalalignment='center', fontsize=28)
plt.xlabel('')
plt.yticks(fontsize=16)
ax2 = ax.twinx()
ax2 = sns.lineplot(x='dt', y='bar', data=df, ax=ax2, color='green')
plt.yticks(fontsize=16)
ax2.plot([], '-g', label = 'other axis in legend')
ax2.set_ylabel('ratio', fontsize=28)
plt.axvline(x=np.datetime64('2020-01-02'),color='k', linestyle='--', lw=4)
plt.text(x=np.datetime64('2020-01-02'), y=10, s=' foo-the-bar ', fontsize=28, horizontalalignment='left')
plt.show()
d2 = pd.DataFrame({'dt':['2020-01-01', '2020-01-02', '2020-01-03', '2020-01-04'], 'category':['a', 'b', 'a', 'b'],'foo':[11, 16, 8, 14], 'bar':[11, 7, 4, 17]})
d2['dt'] = pd.to_datetime(d2['dt'])
ax = sns.lineplot(x='dt', y='foo', data=d2, hue='category')
ax.set_ylabel('something else', fontsize=28)
ax.plot([], '-g', label = 'other axis in legend')
plt.legend(fontsize='x-large')
handles, labels = ax.get_legend_handles_labels()
ax.legend(handles=handles[1:], labels=labels[1:], fontsize='large', loc='lower left')
plt.xticks(rotation=90, horizontalalignment='center', fontsize=28)
plt.xlabel('')
plt.yticks(fontsize=16)
plt.axvline(x=np.datetime64('2020-01-02'),color='k', linestyle='--', lw=4)
plt.text(x=np.datetime64('2020-01-02'), y=10, s=' foo-the-bar ', fontsize=28, horizontalalignment='left')
ax2 = ax.twinx()
ax2 = sns.lineplot(x='dt', y='bar', data=d2, ax=ax2, color='green')
plt.yticks(fontsize=16)
ax2.plot([], '-g', label = 'other axis in legend')
ax2.set_ylabel('ratio', fontsize=28)
plt.show()
It is more or less nice. But when adding in subplots to combine multiple measurements into a single figure sharing the x-axis (i.e. saving space and writing the dates over and over) the following fails to work and completely distorts the plot
ax0 = plt.subplot(211)
ax2 = ax0.twinx()
ax3 = plt.subplot(212)
ax4 = ax3.twinx()
ax = sns.lineplot(x='dt', y='foo', data=df, hue='category', ax=ax0)
ax.set_ylabel('asdf', fontsize=28)
ax.plot([], '-g', label = 'other axis in legend')
plt.legend(fontsize='x-large')
handles, labels = ax.get_legend_handles_labels()
ax.legend(handles=handles[1:], labels=labels[1:], fontsize='large', loc='lower left')
plt.xticks(rotation=90, horizontalalignment='center', fontsize=28)
plt.xlabel('')
plt.yticks(fontsize=16)
plt.axvline(x=np.datetime64('2020-01-02'),color='k', linestyle='--', lw=4)
plt.text(x=np.datetime64('2020-01-02'), y=10, s=' foo-the-bar ', fontsize=28, horizontalalignment='left')
#ax2 = ax.twinx()
ax2 = sns.lineplot(x='dt', y='bar', data=df, ax=ax2, color='green')
plt.yticks(fontsize=16)
ax2.plot([], '-g', label = 'other axis in legend')
ax2.set_ylabel('ratio', fontsize=28)
plt.show()
# TODO second plot is missing
Problems always arise when trying to mix the object-oriented syntax and the pyplot interface.
pyplot functions (plt.XXX) only affect the current axes (generally the latest created, in your case ax4). When you have several axes, it is generally much better to use the OO functions so that there is no ambiguity about which axes you are working on.
Additionally, you might want to through a tight_layout() at the end of your code to automatically adjust the position of your axes to give enough room for your labels
plt.figure()
ax0 = plt.subplot(211)
ax2 = ax0.twinx()
ax3 = plt.subplot(212)
ax4 = ax3.twinx()
ax = sns.lineplot(x='dt', y='foo', data=df, hue='category', ax=ax0)
ax.set_ylabel('asdf', fontsize=28)
ax.plot([], '-g', label = 'other axis in legend')
handles, labels = ax.get_legend_handles_labels()
ax.legend(handles=handles[1:], labels=labels[1:], fontsize='large', loc='lower left')
ax.set_xticklabels(ax.get_xticklabels(), rotation=90, horizontalalignment='center', fontsize=28)
ax.set_xlabel('')
ax.tick_params(axis='y', labelsize=16)
ax.axvline(x=np.datetime64('2020-01-02'),color='k', linestyle='--', lw=4)
ax.text(x=np.datetime64('2020-01-02'), y=10, s=' foo-the-bar ', fontsize=28, horizontalalignment='left')
#ax2 = ax.twinx()
ax2 = sns.lineplot(x='dt', y='bar', data=df, ax=ax2, color='green')
ax2.tick_params(axis='y', labelsize=16)
ax2.plot([], '-g', label = 'other axis in legend')
ax2.set_ylabel('ratio', fontsize=28)
plt.tight_layout()
plt.show()
Consider this code:
fig, ax = plt.subplots(figsize=(8,5))
sns.heatmap(np.ones((4,4)), ax=ax, cbar=None, cmap="Blues", linewidths=1, linecolor='black')
fig, ax = plt.subplots(figsize=(8,5))
sns.heatmap(np.ones((4,4)), ax=ax, cmap="Blues", linewidths=1, linecolor='black')
It outputs:
Why does adding the argument cbar=None change the result of the outcome?
It is the default behavior by cbar, some kind of bug.
Turn off cbar:
fig, ax = plt.subplots(figsize=(8,5))
sns.heatmap(np.ones((4, 4)), ax=ax, cmap='Blues', linewidths=1, linecolor='black', cbar=False, vmin=0, vmax=2)
Turn on cbar:
fig, ax = plt.subplots(figsize=(8,5))
sns.heatmap(np.ones((4,4)), ax=ax, cmap='Blues', linewidths=1, linecolor='black', cbar=True, vmin=0, vmax=2)
As showed by #Alpha, cbar value should be boolean as it can be seen in the documentation
cbar : boolean, optional
Whether to draw a colorbar.
For both figures to have the same size, you can use:
fig, ax = plt.subplots(figsize=(8,5))
sns.heatmap(np.ones((4,4)), ax=ax, linewidths=1, linecolor='black', cmap="Blues",)
cbar = ax.collections[0].colorbar
cbar.remove()
plt.show()
and ...
fig, ax = plt.subplots(figsize=(8,5))
sns.heatmap(np.ones((4,4)), ax=ax, linewidths=1, linecolor='black', cmap="Blues",)
cbar = ax.collections[0].colorbar
#cbar.remove()
plt.show()
I have the output of a group-by representing a sum of dates per week.
Date
2008-10-28 20.0
2008-11-04 25.0
2008-11-11 20.0
2008-11-18 40.0
2008-11-25 35.0
2008-12-02 35.0
2008-12-09 NaN
2008-12-16 NaN
2008-12-23 NaN
2008-12-30 NaN
Freq: W-TUE, Name: Count, dtype: float64
I'm trying to plot these using plot_date
fig, ax = plt.subplots(figsize=(2, 4))
# ax = plt.gca()
line = ax.plot_date(a.index, a.values, '.', label='a', alpha=0.5, linewidth=1)
ax.tick_params('y', colors='k')
ax.set_xlabel('Date')
ax.set_ylabel('Frequency')
ax.set_title('Daily Games')
ax.tick_params('y', colors='k')
ax.grid(b=True, which='major', color='w', linewidth=1.0)
ax.grid(b=True, which='minor', color='w', linewidth=0.5)
ax.yaxis.grid(True)
ax.get_xaxis().set_minor_locator(mpl.ticker.AutoMinorLocator())
ax.set_xticklabels(ax.xaxis.get_majorticklabels(),
rotation=70)
ax.set_xticklabels(ax.xaxis.get_minorticklabels(),
rotation=70)
plt.xticks(rotation=70)
plt.show()
This is producing a graph like so:
I've tried all manner of rearranging but I can't get both minor and major labels for the date to plot.
I'd like to have each month labelled at 70 degrees. How can I adjust what I have to do so?
You could use the AutoDateLocator() as follows:
import seaborn as sns
import matplotlib as mpl
import matplotlib.pyplot as plt
import pandas as pd
sns.set()
a = pd.DataFrame([
('2008-10-28', 20.0), ('2008-11-04', 25.0), ('2008-11-11', 20.0),
('2008-11-18', 40.0), ('2008-11-25', 35.0), ('2008-12-02', 35.0)], columns=['Date', 'Frequency'])
a['Date'] = pd.to_datetime(a['Date'], format='%Y-%m-%d')
fig, ax = plt.subplots(figsize=(5, 5))
# ax = plt.gca()
line = ax.plot_date(a.Date, a.Frequency, '.', label='a', alpha=0.5, linewidth=1)
ax.tick_params('y', colors='k')
ax.set_xlabel('Date')
ax.set_ylabel('Frequency')
ax.set_title('Daily Games')
ax.tick_params('y', colors='k')
ax.grid(b=True, which='major', color='w', linewidth=1.0)
ax.grid(b=True, which='minor', color='w', linewidth=0.5)
ax.yaxis.grid(True)
xtick_locator = mpl.dates.AutoDateLocator()
xtick_formatter = mpl.dates.AutoDateFormatter(xtick_locator)
ax.xaxis.set_major_locator(xtick_locator)
ax.xaxis.set_major_formatter(xtick_formatter)
fig.subplots_adjust(bottom=0.24)
plt.xticks(rotation=70)
plt.show()
This would then display as:
From #MartinEvans suggestion to use AutoDateLocator() I looked up more of the matplotlib documentation and found matplotlib.dates.MonthLocator along with the WeekdayLocator. This allowed tuning the major and minor xticks to change the format and appearance as required.
I then used this answer to set their rotation.
fig, ax = plt.subplots(figsize=(2, 4))
# ax = plt.gca()
line = ax.plot_date(a.Date, a.Frequency, '.', label='a', alpha=0.5, linewidth=1)
ax.tick_params('y', colors='k')
# ax.xticks(rotation=70)
ax.set_xlabel('Date')
# ax.xlabel('Date')
ax.set_ylabel('Frequency')
ax.set_title('Daily Games')
ax.tick_params('y', colors='k')
ax.grid(b=True, which='major', color='w', linewidth=1.0)
ax.grid(b=True, which='minor', color='w', linewidth=0.5)
ax.yaxis.grid(True)
xtick_locator = mpl.dates.MonthLocator(interval=1)
xtick_formatter = mpl.dates.AutoDateFormatter(xtick_locator)
ax.xaxis.set_major_locator(xtick_locator)
ax.xaxis.set_major_formatter(xtick_formatter)
xtick_locator = mpl.dates.WeekdayLocator(byweekday=3)
xtick_formatter = mpl.dates.AutoDateFormatter(xtick_locator)
ax.xaxis.set_minor_locator(xtick_locator)
ax.xaxis.set_minor_formatter(xtick_formatter)
plt.setp(ax.xaxis.get_minorticklabels(), rotation=90, size=10)
plt.setp(ax.xaxis.get_majorticklabels(), rotation=90, size=7)
fig.subplots_adjust(bottom=0.24)
plt.show()