Setting custom years as dates on the plt x axis - python

Im trying to get the red curve to begin at the year 2020 and for the curves to end at the year 2030. However it keeps showing 1970s dates. How do I correct these?
from matplotlib.dates import YearLocator, MonthLocator, DateFormatter
import pylab
years = YearLocator() # every year
months = MonthLocator() # every month
yearsFmt = DateFormatter('%Y')
J_diff = cInc[1:] - cInc[:-1]
J_diffint = cIncint[1:] - cIncint[:-1]
#J_diff = np.diff(cInc)
fig = plt.figure(facecolor='w')
ax = fig.add_subplot(111, facecolor='#dddddd', axisbelow=True)
ax.xaxis.set_major_locator(years)
ax.xaxis.set_major_formatter(yearsFmt)
ax.xaxis.set_minor_locator(months)
#ax.plot(t, U*100000, 'black', alpha=1, lw=2, label='uninfected')
#ax.plot(t, Lf/100000, 'r', alpha=1, lw=2, label='latent fast')
#ax.plot(t, Ls/100000, 'black', alpha=1, lw=2, label='latent slow')
#ax.plot(t, I*100000, 'green', alpha=1, lw=2, label='infected')
#ax.plot(t, R*100000, 'red', alpha=1, lw=2, label='recovered')
ax.plot(t[1:], J_diff*100000, 'blue', alpha=1, lw=2, label='incidence')
ax.plot(t[1:]+500, J_diffint*100000, 'red', alpha=1, lw=2, label='intervention incidence')
#ax.plot(t, cInc, 'red', alpha=1, lw=2, label='Prevalence')
ax.set_xlabel('Time in years')
ax.set_ylabel('Number')
ax.grid(b=True, which='major', c='w', lw=2, ls='-')
legend = ax.legend()
legend.get_frame().set_alpha(0.5)
plt.title("Intervention")
plt.show()

Related

Creating a Dashboard of Graphs in Python

using matplotlib in Jupyter Notebook, I have already written code to produce a number of different graphs (example code below used to create some of my graphs). I would like to put all of these graphs into a dashboard. Is there a preferred method for my instance where I already have the graph produced and just want to plug it in to a dashboard template?
It seems like there are a number of different options (bokeh and plotly).
# multiple line plots
plt.plot( 'Week', 'ESI_1_2_3', data=SZ_ED_TOT, marker='o', color='blue', linewidth=2)
plt.plot( 'Week', 'ESI_4_5', data=SZ_ED_TOT, marker='o', color='red', linewidth=2)
plt.ylabel('Patient Count')
plt.xlabel('Week')
plt.xticks(rotation = 90)
plt.title('SZ Acuity Counts')
plt.gcf().set_size_inches(20, 8)
plt.legend()
plt.show()
# multiple line plots
plt.plot( 'Week', '%_1_2_3', data=UMC_ED_TOT, marker='o', color='blue', linewidth=2)
plt.plot( 'Week', '%_4_5', data=UMC_ED_TOT, marker='o', color='red', linewidth=2)
plt.ylabel('% of Patients')
plt.xlabel('Week')
plt.xticks(rotation = 90)
plt.title('UMC Acuity % Of Total Patients')
plt.gcf().set_size_inches(20, 8)
plt.legend()
plt.show()
#dual Y axis graph
ax = UMC_Cobmined.plot.bar(x='Week', y='Total', rot=90,color=(0.2, 0.4, 0.6, 0.6))
ax.set_xlabel('Week')
ax.set_ylabel('Total Volume')
ax2 = ax.twinx()
ax2.plot(ax.get_xticks(),
UMC_Cobmined[['%_ESI_3','%_ESI_4','%_ESI_5']].values,
linestyle='-',
marker='o', linewidth=2.0)
ax2.set_ylabel('% LWBS By Acuity')
ax2.legend(["%_ESI_3", "%_ESI_4","%_ESI_5"]);
plt.title('UMC LWBS Acuity % by Volume')
plt.gcf().set_size_inches(20, 8)
plt.show()
Ideal example of what I would like my dashboard to look like:
You can achieve this by using a grid in matplotlib:
import matplotlib.pytplot as plt
fig = plt.figure()
grid = fig.add_gridspec(NUMBER_OF_GRID_COLUMNS, NUMBER_OF_GRID_ROWS)
and then add each plot to an axis:
ax1 = fig.add_subplot(grid[0, 0])
# add plot to ax1
ax1.plot(x,y)
ax1.title("Plot on ax1")
ax2 = fig.add_subplot(grid[1,0])
# add plot to ax2
ax2.plot(x,y)
ax2.title("Plot on ax2")
plt.show()
and so on

matplotlib annotation overlapping y_tick labels on plot

I have tried a number of different things to fix my chart, from zorder on the plots to plt.rcParams.
I feel that this is such a simple problem but I just dont know where I have gone wrong. As you can see the bottom annotation in cyan blue is unreadable and mashed with the y label.
Ideally, the annotation sits over the y label to a point where text inside annotation is readable.
If possible just for the annotation to sit on top and still overlay the y label..something like this
Any help on this would be greatly appreciated.
ax = df.plot(x=df.columns[0], y=df.columns[1], legend=False, zorder=0, linewidth=1)
y1 =df.loc[:, df.columns[2]].tail(1)
y2= df.loc[:, df.columns[1]].tail(1)
colors = plt.rcParams["axes.prop_cycle"].by_key()["color"]
print(colors)
for var in (y1, y2):
plt.annotate('%0.2f' % var.max(), xy=(1, var.max()), zorder=1, xytext=(8, 0),
xycoords=('axes fraction', 'data'),
textcoords='offset points',
bbox=dict(boxstyle="round", fc=colors[0], ec=colors[0],))
ax2 = ax.twinx()
df.plot(x=df.columns[0], y=df.columns[2], ax=ax2, legend=False, color='#fa8174', zorder=0,linewidth=1)
ax.figure.legend(prop=subtitle_font)
ax.grid(True, color="white",alpha=0.2)
pack = [df.columns[1], df.columns[2], freq[0]]
plt.text(0.01, 0.95,'{0} v {1} - ({2})'.format(df.columns[1], df.columns[2], freq[0]),
horizontalalignment='left',
verticalalignment='center',
transform = ax.transAxes,
zorder=10,
fontproperties=subtitle_font)
ax.text(0.01,0.02,"Sources: FRED, Quandl, #Paul92s",
color="white",fontsize=10,
horizontalalignment='left',
transform = ax.transAxes,
verticalalignment='center',
zorder=20,
fontproperties=subtitle_font)
ax.xaxis.set_major_locator(matplotlib.dates.YearLocator())
ax.xaxis.set_minor_locator(matplotlib.dates.MonthLocator((4,7,10)))
ax.xaxis.set_major_formatter(matplotlib.dates.DateFormatter("%Y"))
ax.xaxis.set_minor_formatter(ticker.NullFormatter()) # matplotlib.dates.DateFormatter("%m")
plt.setp(ax.get_xticklabels(), rotation=0, ha="center", zorder=-1)
plt.setp(ax2.get_yticklabels(), rotation=0, zorder=-1)
plt.setp(ax.get_yticklabels(), rotation=0, zorder=-1)
plt.gcf().set_size_inches(14,7)
ax.set_xlabel('Data as of; {0}'.format(df['Date'].max().strftime("%B %d, %Y")), fontproperties=subtitle_font)
y1 =df.loc[:, df.columns[2]].tail(1)
y2= df.loc[:, df.columns[1]].tail(1)
for var in (y1, y2):
plt.annotate('%0.2f' % var.max(), xy=(1, var.max()), zorder=1,xytext=(8, 0),
xycoords=('axes fraction', 'data'),
textcoords='offset points',
bbox=dict(boxstyle="round", fc="#fa8174", ec="#fa8174"))
plt.title('{0}'.format("FRED Velocity of M2 Money Stock v Trade Weighted U.S. Dollar Index: Broad"),fontproperties=heading_font)
ax.texts.append(ax.texts.pop())
ax.set_facecolor('#181818')
ax.figure.set_facecolor('#181818')
plt.rcParams['axes.axisbelow'] = True
I don't figure out why zorder doesn't work, but you can directly set the label style of tick labels:
import matplotlib.pyplot as plt
import numpy as np
from numpy.random import rand
import matplotlib.patches as mpatches
fig, ax = plt.subplots(1, 1)
ax.plot(rand(100), '^', color='r')
for label in ax.get_xticklabels():
label.set_bbox(dict(facecolor='orange'))
ax1 = ax.twinx()
ax1.plot(rand(100), 'o', color='b')
index_to_add_bbox = [2, 4]
ax1_labels = ax1.get_yticklabels()
for i in index_to_add_bbox:
ax1_labels[i].set_bbox(dict(boxstyle='Circle', facecolor='orange'))
plt.show()

For scatterplot with matplotlib how to include in the legend gradient for dot size and colour?

I create two scatterplots with matplotlib in python with this code, the data for the code is here:
import matplotlib.pyplot as plt
from matplotlib.colors import Normalize
fig = plt.figure(figsize=(20,12))
ax1 = fig.add_subplot(111)
ax3 = ax1.twinx()
norm = Normalize(vmin=0.95*min(arr), vmax=1.05*max(arr))
ax1.scatter(x, y1, s=20, c=arr, cmap='Blues_r', norm=norm, marker='x', label='bla1')
ax3.scatter(x, y2, s=(20*(1.1-arr))**3.5, c=arr, cmap='Reds_r', norm=norm, marker='^', label='bla1')
The created fig. looks like this:
So, the dot size (in ax3) and the dot colour (in ax1 and ax3) are taken from arrays containing floats with all kinds of values in the range [0,1]. My question: How do I create a legend that displays the corresponding y-values for, let's say 5 different dot sizes and 5 different colour nuances?
I would like the legend to look like in the figure below (source here), but with the colour bar and size bar put into a single legend, if possible. Thanks for suggestions and code!
# using your data in dataframe df
# create s2
df['s2'] = (20*(1.1-df.arr))**3.5
fig = plt.figure(figsize=(20,12))
ax1 = fig.add_subplot(111)
ax3 = ax1.twinx()
norm = Normalize(vmin=0.95*min(df.arr), vmax=1.05*max(df.arr))
p1 = ax1.scatter(df.x, df.y1, s=20, c=df.arr, cmap='Blues_r', norm=norm, marker='x')
fig.colorbar(p1, label='arr')
p2 = ax3.scatter(df.x, df.y2, s=df.s2, c=df.arr, cmap='Reds_r', norm=norm, marker='^')
fig.colorbar(p2, label='arr')
# create the size legend for red
for x in [15, 80, 150]:
plt.scatter([], [], c='r', alpha=1, s=x, label=str(x), marker='^')
plt.legend(loc='upper center', bbox_to_anchor=(1.23, 1), ncol=1, fancybox=True, shadow=True, title='s2')
plt.show()
There's no legend for p1 because the size is static.
I think this would be better as two separate plots
I used Customizing Plot Legends: Legend for Size of Points
Separate
fig, (ax1, ax2) = plt.subplots(nrows=2, figsize=(20, 10))
norm = Normalize(vmin=0.95*min(df.arr), vmax=1.05*max(df.arr))
p1 = ax1.scatter(df.x, df.y1, s=20, c=df.arr, cmap='Blues_r', norm=norm, marker='x')
fig.colorbar(p1, ax=ax1, label='arr')
p2 = ax2.scatter(df.x, df.y2, s=df.s2, c=df.arr, cmap='Reds_r', norm=norm, marker='^')
fig.colorbar(p2, ax=ax2, label='arr')
# create the size legend for red
for x in [15, 80, 150]:
plt.scatter([], [], c='r', alpha=1, s=x, label=str(x), marker='^')
plt.legend(loc='upper center', bbox_to_anchor=(1.2, 1), ncol=1, fancybox=True, shadow=True, title='s2')
plt.show()

figure with 3X3 subplots having shared x,y axes and labels?

I cannot add create 3x3 subplots with common axes and labels using the following code:
fig = plt.figure(figsize=(24, 12))
ax = fig.add_subplot(111) # The big subplot
fig.text(0.5, 0.04, 'Time (minutes)', ha='center')
fig.text(0.04, 0.5, 'Distance travelled (pixels)', va='center',
rotation='vertical')
# Turn off axis lines and ticks of the big subplot
ax.spines['top'].set_color('none')
ax.spines['bottom'].set_color('none')
ax.spines['left'].set_color('none')
ax.spines['right'].set_color('none')
ax.tick_params(labelcolor='w', top='off', bottom='off',
left='off', right='off')
ax1 = fig.add_subplot(331)
ax1.errorbar(Time, MD11, MD11err, capsize=3, ls='none',
color='red', elinewidth=0.5, capthick=1)
ax1.scatter(Time, S1, s=20, color = 'grey')
ax1.plot(Time, MD11, color = 'red', label="First 1ug/g
injection")
ax1.plot(Time, S1, color = 'grey', label="Saline")
ax1.spines['right'].set_visible(False)
ax1.spines['top'].set_visible(False)
ax1.title ('MDMA 1 ug/g ')
ax1.ylabel('First Injection', va='center', rotation='vertical')
ax2 = fig.add_subplot(332)
ax2.errorbar(Time, MD31, MD31err, capsize=5, ls='none',
color='red', elinewidth=1, capthick=2)
ax2.errorbar(Time, S4, S4err, capsize=5, ls='none',
color='gray', elinewidth=1, capthick=2)
ax2.scatter(Time, MD31,s=20, color = 'red')
ax2.scatter(Time, S4,s=20, color = 'grey')
ax2.plot(Time, MD31, color = 'red', label="First 3ug/g
injection")
ax2.plot(Time, S4, color = 'grey', label="Saline")
and so on till ax9. The above code just created the 331 subplot and not the other ones. I have defined all the variables properly. Please help.

python matplotlib plotting many subfigures with the same parameters

My plot is like the following
fig = plt.figure(figsize=(7,3))
ax1 = fig.add_subplot(1,3,1)
ax2 = fig.add_subplot(1,3,2)
ax3 = fig.add_subplot(1,3,3)
ax1.scatter(x11, y11, s=50, alpha=0.5, c='orange', marker='o')
ax1.scatter(x12, y12, s=50, alpha=0.5, c='blue', marker='s')
ax2.scatter(x21, y21, s=50, alpha=0.5, c='orange', marker='o')
ax2.scatter(x22, y22, s=50, alpha=0.5, c='blue', marker='s')
ax3.scatter(x31, y31, s=50, alpha=0.5, c='orange', marker='o')
ax3.scatter(x32, y32, s=50, alpha=0.5, c='blue', marker='s')
It seems kinda redundant to set s=50, alpha=0.5 over and over. Is there a way to set them once for all? Also for color and marker, is there a way to write them in one place so it's easier to modify?
You could do this:
fig = plt.figure(figsize=(7,3))
ax1 = fig.add_subplot(1,3,1)
ax2 = fig.add_subplot(1,3,2)
ax3 = fig.add_subplot(1,3,3)
xs = [x11, x12, x21, x22, x31, x32]
ys = [y11, y12, y21, y22, y31, y32]
cs = ['orange', 'blue']
ms = 'os'
for j in xrange(len(xs)):
ax1.scatter(xs[j], ys[j], s=50, alpha=0.5, c=cs[j % 2], marker=ms[j % 2])
I like organizing the data and styles, and then using that to organize the plotting. Generating some random data to make a runnable example:
import matplotlib.pyplot as plt
from numpy.random import random
fig, axs = plt.subplots(3, figsize=(7,3)) #axs is an array of axes
orange_styles = {'c':"orange", 'marker':'o'}
blue_styles = {'c':"blue", 'marker':'s'}
pts = []
for i in range(12):
pts.append(random(4))
orange_x = pts[0:3] # organized data is lists of lists
orange_y = pts[3:6]
blue_x = pts[6:10]
blue_y = pts[10:12]
for ax, x, y in zip(axs, orange_x, orange_y): #all the orange cases
ax.scatter(x, y, s=50, alpha=0.5, **orange_styles) # **kwds
for ax, x, y in zip(axs, blue_x, blue_y):
ax.scatter(x, y, s=50, alpha=0.5, **blue_styles)

Categories