add color legend to map subplots - python

For this example, I modified the dataset and code from https://plotly.com/python/map-subplots-and-small-multiples/ to add a column to plot it in colors.
What I want to do here and in my dataset is to add a legend with a color scale.
Here the range is the same (0-9) among maps, so, a general legend or a legend for each subplot would work. Here the general legend is wrong.
Related: Plotly contour subplots each having their own colorbar
import plotly.graph_objects as go
import pandas as pd
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/1962_2006_walmart_store_openings.csv')
df.head()
# new column
import numpy as np
df["counts"] = np.random.choice(range(0,10),df.shape[0])
data = []
layout = dict(
title = 'New Walmart Stores per year 1962-2006<br>\
Source: <a href="http://www.econ.umn.edu/~holmes/data/WalMart/index.html">\
University of Minnesota</a>',
# showlegend = False,
autosize = False,
width = 1000,
height = 900,
hovermode = False,
legend = dict(
x=0.7,
y=-0.1,
bgcolor="rgba(255, 255, 255, 0)",
font = dict( size=11 ),
)
)
years = df['YEAR'].unique()
for i in range(len(years)):
geo_key = 'geo'+str(i+1) if i != 0 else 'geo'
lons = list(df[ df['YEAR'] == years[i] ]['LON'])
lats = list(df[ df['YEAR'] == years[i] ]['LAT'])
mycolor = list(df[ df['YEAR'] == years[i] ]['counts']) # new
# Walmart store data
data.append(
dict(
type = 'scattergeo',
showlegend=False,
lon = lons,
lat = lats,
geo = geo_key,
name = int(years[i]),
marker = dict(
color = mycolor, # new
#color = "rgb(0, 0, 255)",
opacity = 0.5
,showscale=True # new
)
)
)
# Year markers
data.append(
dict(
type = 'scattergeo',
showlegend = False,
lon = [-78],
lat = [47],
geo = geo_key,
text = [years[i]],
mode = 'text',
)
)
layout[geo_key] = dict(
scope = 'usa',
showland = True,
landcolor = 'rgb(229, 229, 229)',
showcountries = False,
domain = dict( x = [], y = [] ),
subunitcolor = "rgb(255, 255, 255)",
)
z = 0
COLS = 5
ROWS = 9
for y in reversed(range(ROWS)):
for x in range(COLS):
geo_key = 'geo'+str(z+1) if z != 0 else 'geo'
layout[geo_key]['domain']['x'] = [float(x)/float(COLS), float(x+1)/float(COLS)]
layout[geo_key]['domain']['y'] = [float(y)/float(ROWS), float(y+1)/float(ROWS)]
z=z+1
if z > 42:
break
fig = go.Figure(data=data, layout=layout)
fig.update_layout(width=800)
config = {'staticPlot': True}
fig.show(config=config)

I had to build the coordinates for each colorbar:
import plotly.graph_objects as go
import pandas as pd
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/1962_2006_walmart_store_openings.csv')
df.head()
z1 = z = 0
COLS = 5
ROWS = 9
mylist = [[],[]]
for y in reversed(range(ROWS)):
for x in range(COLS):
mylist[0].append((float(x+1)/float(COLS))-.02)
mylist[1].append((float(y+1)/float(ROWS))-.05)
z1=z1+1
if z1 > 42:
break
# new column
import numpy as np
df["counts"] = np.random.choice(range(0,10),df.shape[0])
data = []
layout = dict(
title = 'New Walmart Stores per year 1962-2006<br>\
Source: <a href="http://www.econ.umn.edu/~holmes/data/WalMart/index.html">\
University of Minnesota</a>',
# showlegend = False,
autosize = False,
width = 1000,
height = 900,
hovermode = False,
legend = dict(
x=0.7,
y=-0.1,
bgcolor="rgba(255, 255, 255, 0)",
font = dict( size=11 ),
)
)
years = df['YEAR'].unique()
for i in range(len(years)):
geo_key = 'geo'+str(i+1) if i != 0 else 'geo'
lons = list(df[ df['YEAR'] == years[i] ]['LON'])
lats = list(df[ df['YEAR'] == years[i] ]['LAT'])
mycolor = list(df[ df['YEAR'] == years[i] ]['counts']) # new
# Walmart store data
data.append(
dict(
type = 'scattergeo',
showlegend=False,
lon = lons,
lat = lats,
geo = geo_key,
name = int(years[i]),
marker = dict(
color = mycolor, # new
#color = "rgb(0, 0, 255)",
opacity = 0.5,
showscale=True
,colorbar=dict(len=0.1
, x=mylist[0][i]
, y=mylist[1][i]
,thickness=5
)
)
)
)
# Year markers
data.append(
dict(
type = 'scattergeo',
showlegend = False,
lon = [-78],
lat = [47],
geo = geo_key,
text = [years[i]],
mode = 'text',
)
)
layout[geo_key] = dict(
scope = 'usa',
showland = True,
landcolor = 'rgb(229, 229, 229)',
showcountries = False,
domain = dict( x = [], y = [] ),
subunitcolor = "rgb(255, 255, 255)",
)
for y in reversed(range(ROWS)):
for x in range(COLS):
geo_key = 'geo'+str(z+1) if z != 0 else 'geo'
layout[geo_key]['domain']['x'] = [float(x)/float(COLS), float(x+1)/float(COLS)]
layout[geo_key]['domain']['y'] = [float(y)/float(ROWS), float(y+1)/float(ROWS)]
z=z+1
if z > 42:
break
fig = go.Figure(data=data, layout=layout)
fig.update_layout(width=800)
config = {'staticPlot': True}
fig.show(config=config)

Related

Combine entries in a single legend from Plotly subplots - python

The following plots two separate scatterplots using Plotly. I want to combine the points from each subplot into a single legend. However, if I plot the figure as is, there are some duplicate entries. On the other hand, if I hide a legend from a certain subplot, not all entries are displayed.
df = pd.DataFrame({'Type' : ['1','1','1','1','1','2','2','2','2','2'],
'Category' : ['A','D','D','D','F','B','D','A','D','E']
})
df['Color'] = df['Category'].map(dict(zip(df['Category'].unique(),
px.colors.qualitative.Dark24[:len(df['Category'].unique())])))
df = pd.concat([df]*10, ignore_index = True)
df['Lat'] = np.random.randint(0, 20, 100)
df['Lon'] = np.random.randint(0, 20, 100)
Color = df['Color'].unique()
Category = df['Category'].unique()
cats = dict(zip(Color, Category))
df_type_1 = df[df['Type'] == '1'].copy()
df_type_2 = df[df['Type'] == '2'].copy()
fig = make_subplots(
rows = 1,
cols = 2,
specs = [[{"type": "scattermapbox"}, {"type": "scattermapbox"}]],
vertical_spacing = 0.05,
horizontal_spacing = 0.05
)
for c in df_type_1['Color'].unique():
df_color = df_type_1[df_type_1['Color'] == c]
fig.add_trace(go.Scattermapbox(
lat = df_color['Lat'],
lon = df_color['Lon'],
mode = 'markers',
name = cats[c],
marker = dict(color = c),
opacity = 0.8,
#legendgroup = 'group2',
#showlegend = True,
),
row = 1,
col = 1
)
for c in df_type_2['Color'].unique():
df_color = df_type_2[df_type_2['Color'] == c]
fig.add_trace(go.Scattermapbox(
lat = df_color['Lat'],
lon = df_color['Lon'],
mode = 'markers',
name = cats[c],
marker = dict(color = c),
opacity = 0.8,
#legendgroup = 'group2',
#showlegend = False,
),
row = 1,
col = 2
)
fig.update_layout(height = 600, width = 800, margin = dict(l = 10, r = 10, t = 30, b = 10));
fig.update_layout(mapbox1 = dict(zoom = 2, style = 'carto-positron'),
mapbox2 = dict(zoom = 2, style = 'carto-positron'),
)
fig.show()
output: duplicate entries
if I use showlegend = False on either subplot, then the legend will not show all applicable entries.
output: (subplot 2 showlegend = False)
The best way to remove duplicate legends at this time is to use set() to remove duplicates from the created legend and update it with that content. I am saving this as a snippet. I am getting the snippet from this answer. I have also changed the method to use the color information set in the columns. I have also redesigned it so that it can be created in a single loop process without creating an extra data frame.
fig = make_subplots(
rows = 1,
cols = 2,
specs = [[{"type": "scattermapbox"}, {"type": "scattermapbox"}]],
vertical_spacing = 0.05,
horizontal_spacing = 0.05
)
for t in df['Type'].unique():
dff = df.query('Type ==#t')
for c in dff['Category'].unique():
dffc = dff.query('Category == #c')
fig.add_trace(go.Scattermapbox(
lat = dffc['Lat'],
lon = dffc['Lon'],
mode = 'markers',
name = c,
marker = dict(color = dffc['Color']),
opacity = 0.8,
),
row = 1,
col = int(t)
)
fig.update_layout(height = 600, width = 800, margin = dict(l = 10, r = 10, t = 30, b = 10));
fig.update_layout(mapbox1 = dict(zoom = 2, style = 'carto-positron'),
mapbox2 = dict(zoom = 2, style = 'carto-positron'),
)
names = set()
fig.for_each_trace(
lambda trace:
trace.update(showlegend=False)
if (trace.name in names) else names.add(trace.name))
fig.show()

How to increase planes' size in Plotly

Got the following code
import pandas as pd
import plotly.graph_objects as go
import numpy as np
df = pd.read_csv('https://raw.githubusercontent.com/tiago-peres/immersion/master/Platforms_dataset.csv')
fig = px.scatter_3d(df, x='Functionality ', y='Accessibility', z='Immersion', color='Platforms')
grey = [[0,'#C0C0C0'],[1,'#C0C0C0']]
zero_pt = pd.Series([0])
z = zero_pt.append(df['Immersion'], ignore_index = True).reset_index(drop = True)
y = zero_pt.append(df['Accessibility'], ignore_index = True).reset_index(drop = True)
x = zero_pt.append(df['Functionality '], ignore_index = True).reset_index(drop = True)
length_data = len(z)
z_plane_pos = 66.5*np.ones((length_data,length_data))
fig.add_trace(go.Surface(x=x, y=y, z=z_plane_pos, colorscale=grey, showscale=False))
fig.add_trace(go.Surface(x=x.apply(lambda x: 15.69), y=y, z = np.array([z]*length_data), colorscale= grey, showscale=False))
fig.add_trace(go.Surface(x=x, y= y.apply(lambda x: 55), z = np.array([z]*length_data).transpose(), colorscale=grey, showscale=False))
fig.update_layout(scene = dict(
xaxis = dict(nticks=4, range=[0,31.38],),
yaxis = dict(nticks=4, range=[0,110],),
zaxis = dict(nticks=4, range=[0,133],),),
legend_orientation="h",margin=dict(l=0, r=0, b=0, t=0))
that can be opened in Google Colab which produces the following output
As you can see, the planes are not filling up the entire axis space, they should respect the axis range. In other words, the planes
z=66.5 - should exist between [0, 31.38] in x and [0, 110] in y
x=15.59 - should exist between [0, 110] in y and [0, 133] in z
y=55 - should exist between [0, 31.38] in x and [0, 133] in z
How can that be done?
With this new adjustment,
import plotly.express as px
import pandas as pd
import plotly.graph_objects as go
import numpy as np
df = pd.read_csv('https://raw.githubusercontent.com/tiago-peres/immersion/master/Platforms_dataset.csv')
fig = px.scatter_3d(df, x='Functionality ', y='Accessibility', z='Immersion', color='Platforms')
grey = [[0,'#C0C0C0'],[1,'#C0C0C0']]
zero_pt = pd.Series([0])
z1 = np.arange(0, 134, 1)
print(z1)
y1 = np.arange(0, 111, 1)
print(z1)
x1 = np.arange(0, 32.38, 1)
print(z1)
z = zero_pt.append(df['Immersion'], ignore_index = True).reset_index(drop = True)
y = zero_pt.append(df['Accessibility'], ignore_index = True).reset_index(drop = True)
x = zero_pt.append(df['Functionality '], ignore_index = True).reset_index(drop = True)
print(zero_pt)
print(z)
test1 = pd.Series([133])
test = z.append(test1)
length_data1 = len(z1)
z_plane_pos = 66.5*np.ones((length_data1,length_data1))
length_data2 = len(y1)
y_plane_pos = 55*np.ones((length_data2,length_data2))
length_data3 = len(x1)
x_plane_pos = 15.69*np.ones((length_data3,length_data3))
fig.add_trace(go.Surface(x=x1, y=y1, z=z_plane_pos, colorscale=grey, showscale=False))
fig.add_trace(go.Surface(x=x.apply(lambda x: 15.69), y=y1, z = np.array([test]*length_data1), colorscale= grey, showscale=False))
fig.add_trace(go.Surface(x=x1, y= y.apply(lambda x: 55), z = np.array([test]*length_data1).transpose(), colorscale=grey, showscale=False))
fig.update_layout(scene = dict(
xaxis = dict(nticks=4, range=[0,31.38],),
yaxis = dict(nticks=4, range=[0,110],),
zaxis = dict(nticks=4, range=[0,133],),),
legend_orientation="h",margin=dict(l=0, r=0, b=0, t=0))
nearly having the job done but the planes x=15.59 and y=55 aren't going to the maximum 133 in Immersion
The issue was that the arrays I was plotting weren't the right shapes.
By properly splitting the bit where created the input arrays and the plotting, was able to discover this, and consequently made input arrays (for plotting) of the right size and appropriate content.
import plotly.express as px
import pandas as pd
import plotly.graph_objects as go
import numpy as np
df = pd.read_csv('https://raw.githubusercontent.com/tiago-peres/immersion/master/Platforms_dataset.csv')
zero_pt = pd.Series([0])
z1 = np.arange(0, 134, 1)
y1 = np.arange(0, 111, 1)
x1 = np.arange(0, 32.38, 1)
z = zero_pt.append(df['Immersion'], ignore_index = True).reset_index(drop = True)
y = zero_pt.append(df['Accessibility'], ignore_index = True).reset_index(drop = True)
x = zero_pt.append(df['Functionality '], ignore_index = True).reset_index(drop = True)
test1 = pd.Series([133])
test = z.append(test1)
length_data1 = len(z1)
z_plane_pos = 66.5*np.ones((length_data1,length_data1))
length_data2 = len(y1)
y_plane_pos = 55*np.ones((length_data2,length_data2))
length_data3 = len(x1)
x_plane_pos = 15.69*np.ones((length_data3,length_data3))
xvals = x.apply(lambda x: 15.69)
xvals2 = x1
yvals = y1
yvals2 = y.apply(lambda x: 55)
zvals = np.zeros((len(yvals), len(xvals)))
zvals[:, -1] = 133 # np.array([test]*length_data2)
zvals2 = np.zeros((len(yvals2), len(xvals2)))
zvals2[-1, :] = 133
fig = px.scatter_3d(df, x='Functionality ', y='Accessibility', z='Immersion', color='Platforms')
grey = [[0,'#C0C0C0'],[1,'#C0C0C0']]
fig.add_trace(go.Surface(x=x1, y=y1, z=z_plane_pos, colorscale=grey, showscale=False))
fig.add_trace(go.Surface(x=xvals, y=yvals, z = zvals, colorscale= grey, showscale=False))
fig.add_trace(go.Surface(x=xvals2, y=yvals2, z = zvals2, colorscale=grey, showscale=False))
fig.update_layout(scene = dict(
xaxis = dict(nticks=4, range=[0,31.38],),
yaxis = dict(nticks=4, range=[0,110],),
zaxis = dict(nticks=4, range=[0,133],),),
legend_orientation="h",margin=dict(l=0, r=0, b=0, t=0))
See it here.

Iterating over a list of DataFrame objects with a for loop

I have this error:
TypeError: list indices must be integers or slices, not DataFrame
divisasIndica is a list of DataFrame objects, and I have this code:
datachart=[]
def dchart ():
for i in divisasIndica[:]:
df=divisasIndica[i]
data = [ dict(
type = 'candlestick',
open = df.Open,
high = df.High,
low = df.Low,
close = df.Close,
x = df.index,
rsi=df.RSI,
SMA50=df.SMA50,
SMA200=df.SMA200,
SAR=df.SAR,
yaxis = 'y2',
name = tit,
increasing = dict( line = dict( color = INCREASING_COLOR ) ),
decreasing = dict( line = dict( color = DECREASING_COLOR ) ),
) ]
layout=dict()
fig = dict( data=data, layout=layout )
datachart.append(fig)
The question is can't I read a list of DataFrames with for?
The values of your list are already dataframes, no need to try to get them using an index. for i in divisasIndica gives you all the elements of divisasIndica directly, not their indexes. And there is no need to do divisasIndica[:].
Change your code to this:
datachart=[]
def dchart ():
for df in divisasIndica:
data = [ dict(
type = 'candlestick',
open = df.Open,
high = df.High,
low = df.Low,
close = df.Close,
x = df.index,
rsi=df.RSI,
SMA50=df.SMA50,
SMA200=df.SMA200,
SAR=df.SAR,
yaxis = 'y2',
name = tit,
increasing = dict( line = dict( color = INCREASING_COLOR ) ),
decreasing = dict( line = dict( color = DECREASING_COLOR ) ),
) ]
layout=dict()
fig = dict( data=data, layout=layout )
datachart.append(fig)
datachart=[]
def dchart (divisasIndica):
for df in divisasIndica:
data = [ dict(
type = 'candlestick',
open = df.Open,
high = df.High,
low = df.Low,
close = df.Close,
x = df.index,
rsi=df.RSI,
SMA50=df.SMA50,
SMA200=df.SMA200,
SAR=df.SAR,
yaxis = 'y2',
name = titu,
increasing = dict( line = dict( color = INCREASING_COLOR ) ),
decreasing = dict( line = dict( color = DECREASING_COLOR ) ),
) ]
layout=dict()
fig = dict( data=data, layout=layout )
datachart.append(fig)

How to hide the x-axis values while subplotting with plotly

I'm using plotly to plot a large csv file (with a lot of data) and to subplot in line (which works actually) some charts.
The problem is that for each chart I get all of the date+time for each point on the x-axis resulting in a bad quality chart. How can I hide for the 5 first chart the values of the x-axis while keeping it for the last one to have a better vieaw of the charts ?
Here is my code : the problematic part start at line 125
import os
import pandas as pd
import plotly
import plotly.graph_objs as go
from tkinter import *
window = Tk()
window.title("Interface utilisateur")
consigne=Label(window, text="Merci de remplir les champs ci-dessous avant de cliquer sur start")
consigne.grid(column = 1,row=0)
consDateDEB=Label(window, text="Date de début de sélection (format JJMMAAAA)")
consDateDEB.grid(column=0,row=1)
DateDEB = Entry(window,width=25)
DateDEB.grid(column = 2,row=1)
consDateFIN=Label(window, text="Date de fin de sélection (format JJMMAAAA)")
consDateFIN.grid(column=0,row=2)
DateFIN = Entry(window,width=25)
DateFIN.grid(column = 2,row=2)
consPathIN=Label(window, text="Chemin d'accès aux fichiers (format C://user/dossier1/dossier2/)")
consPathIN.grid(column=0,row=3)
PathIN = Entry(window,width=50)
PathIN.grid(column = 2,row=3)
consPathOUT=Label(window, text="Chemin d'écriture des fichiers (format C://user/dossier1/dossier2/)")
consPathOUT.grid(column=0,row=4)
PathOUT = Entry(window,width=50)
PathOUT.grid(column = 2,row=4)
def click():
pathIN = PathIN.get()
pathOUT = PathOUT.get()
DateDebut = DateDEB.get()
DateFin = DateFIN.get()
tracer(DateDebut,DateFin,pathIN,pathOUT)
btn = Button(window, text='Start',command=click,width=30,height=2,activebackground='red')
btn.grid(column = 1,row=5)
window.mainloop()
def tracer(DateDebut,DateFin,pathIN,pathOUT):
# DateDebut=10052019
# DateFin=12052019
# pathIN='D://Clef64go/PJT/Logfiles/'
# pathOUT='D://Clef64go/PJT/OUT/'
Logfiles = os.listdir(pathIN)
def conversion(Logfile_JJMMAAAA):
nomFichierINT = int(Logfile_JJMMAAAA[12:16] + Logfile_JJMMAAAA[10:12] + Logfile_JJMMAAAA[8:10])
return nomFichierINT
def conversionInverse(AAAAMMJJ):
AAAAMMJJ = str(AAAAMMJJ)
nomFichierSTR = "Logfile_" + AAAAMMJJ[6:8] + AAAAMMJJ[4:6] + AAAAMMJJ[0:4]+".csv"
return nomFichierSTR
DateDebut = str(DateDebut)
DateFin = str(DateFin)
DebTempo = DateDebut[4:8]+DateDebut[2:4]+DateDebut[0:2]
FinTempo = DateFin[4:8]+DateFin[2:4]+DateFin[0:2]
DateDebut=int(DebTempo)
DateFin=int(FinTempo)
L_Selection=[]
for fichier in Logfiles:
Tempo=conversion(fichier)
if Tempo >= DateDebut and Tempo <= DateFin :
L_Selection.append(Tempo)
L_Selection = sorted(L_Selection)
L_Clean=[]
for fichier in L_Selection :
Tempo = conversionInverse(fichier)
L_Clean.append(Tempo)
#L_Log = os.listdir("D://Clef64go/PJT/TEST2/")
dfList=[]
colnames=['No.','Date','Time','Temp1','Unit','Temp2','Unit','Lux2','Unit','BP1','Humidité Relat','Unit','CO2','Unit','Présence','Temp1_EnO','Unit','Temp2_EnO','Unit','Temp3_EnO','Unit','RH3_EnO','Unit','Chauffage','test']
for filename in L_Clean:
filename = pathIN + filename
typefile=type(filename)
df=pd.read_csv(filename, sep = ';', error_bad_lines=False, encoding="ANSI")
dfList.append(df)
concatDf=pd.concat(dfList,axis=0)
concatDf.columns=colnames
pathOUT = pathOUT + "/" + str(DateDebut) +" a "+ str(DateFin) + ".csv"
concatDf.to_csv(pathOUT, sep = ';',index=False)
df = pd.read_csv(pathOUT,decimal=",",sep = ';', error_bad_lines=False, encoding="ANSI",names=colnames)
df['Temp1'] = [x.replace(',', '.') for x in df['Temp1']]
df['Temp2'] = [x.replace(',', '.') for x in df['Temp2']]
df['Temp1_EnO'] = [x.replace(',', '.') for x in df['Temp1_EnO']]
df['Temp2_EnO'] = [x.replace(',', '.') for x in df['Temp2_EnO']]
df['Temp3_EnO'] = [x.replace(',', '.') for x in df['Temp3_EnO']]
date = df['Date']+df['Time']
y1 = df['Temp1']
y2 = df['Temp2']
y3 = df['Temp3_EnO']
y4 = df['Humidité Relat']
y5 = df['CO2']
y6 = df['Présence']
#plotly.offline.plot({
# "data": [go.Scatter(x=x, y=y)],
# "layout": go.Layout(title="Température 1 en fonction du temps")
# }, auto_open=True)
temp1 = go.Scatter(
x=date,
y=y1,
name="Température 1 (°C)"
)
temp2 = go.Scatter(
x=date,
y=y2,
name="Température 2 (°C)"
)
temp3 = go.Scatter(
x=date,
y=y3,
name="Température 3 (°C)"
)
Humidite = go.Scatter(
x=date,
y=y4,
name="Humidité relative (%)"
)
dioxyde_de_carbone = go.Scatter(
x=date,
y=y5,
name="Taux C02 (ppm)"
)
presence = go.Scatter(
x=date,
y=y6,
name="Présence"
)
fig = plotly.tools.make_subplots(rows=6, cols=1)
fig.append_trace(temp1, 1, 1)
fig.append_trace(temp2, 2, 1)
fig.append_trace(temp3, 3, 1)
fig.append_trace(Humidite, 4, 1)
fig.append_trace(dioxyde_de_carbone, 5, 1)
fig.append_trace(presence, 6, 1)
fig['layout'].update(title='Représentation graphique des données')
plotly.offline.plot(fig, filename=str(DateDebut) +" a "+ str(DateFin) + ".csv", auto_open=True)
Here is what I get :
You can fix it with these two lines:
fig.update_xaxes(showticklabels=False) # hide all the xticks
fig.update_xaxes(showticklabels=True, row=6, col=1)
The other answers here are workarounds. Plotly offers the functionality you're looking for with the shared_xaxes parameter in the make_subplots method:
fig = plotly.subplots.make_subplots(rows=6, cols=1, shared_xaxes=True)
You can also choose to share the y axes as well with shared_yaxes=True. However if sharing both axes is your intent, you may find it easier to have a single plot and just add multiple traces to it (vs using subplots).
I started from Andrews comment. But the relevant source is this one:
trace0 = go.Scatter(
x = [0,1,1,0,0,1,1,2,2,3,3,2,2,3],
y = [0,0,1,1,3,3,2,2,3,3,1,1,0,0]
)
trace1 = go.Scatter(
x = [0,1,2,3],
y = [1,2,4,8],
yaxis = "y2"
)
layout = go.Layout(
width = 800,
height = 500,
title = "fixed-ratio axes",
xaxis = dict(
nticks = 10,
domain = [0, 0.45],
title = "shared X axis"
),
yaxis = dict(
scaleanchor = "x",
domain = [0, 0.45],
title = "1:1"
),
yaxis2 = dict(
scaleanchor = "x",
scaleratio = 0.2,
domain = [0.55,1],
title = "1:5"
))
Explanation
You need to define the xaxis once. For every other subplot you set scaleanchor = "x", so that every subplot shares the same xaxis. All the plots that share one xasis are automatically plotted as subplots, so you coul get rid of your present structure.
Required Edit
data = [temp1,temp2,temp3,Humidite, dioxyde_de_carbone, presence]
layout = go.Layout(
width = 800,
height = 500,
title = "fixed-ratio axes using 10 ticks",
xaxis = dict(
nticks = 10,
title = "shared X axis showing DATE"
),
yaxis = dict(
scaleanchor = "x",
title = "Temp"
),
yaxis2 = dict(
scaleanchor = "x",
title = "Humidity"
),
yaxis3 = dict(
scaleanchor = "x",
title = "ppm"
),
yaxis4 = dict(
scaleanchor = "x",
title = "presence"
),
showlegend= False
)
fig = go.Figure(data=data, layout=layout)
plotly.offline.plot(fig, filename=str(DateDebut) +" a "+ str(DateFin) + ".csv", auto_open=True)
fig = plotly.tools.make_subplots(rows=6, cols=1)

Add multiple text labels from DataFrame columns in Plotly

The goal is to plot some data using plotly where the text param contains multiple columns.
Here is my DataFrame:
import pandas as pd
import numpy as np
import plotly as py
import plotly.graph_objs as go
np.random.seed(1)
df = pd.DataFrame({'Mean Age': np.random.randint(40,60,10),
'Percent': np.random.randint(20,80,10),
'Number Column': np.random.randint(100,500,10)},
index=list('ABCDEFGHIJ'))
df.index.name = 'Text Column'
df = df.sort_values('Mean Age')
Here is an example of how I plotted the data with text from one column to show on hover:
# trace for Percent
trace0 = go.Scatter(
x = df.index,
y = df['Percent'],
name = 'Percent',
text = df['Mean Age'], # text to show on hover from df column
mode = 'lines+markers',
line = dict(
color = ('rgb(0,0,255)'), # blue
width = 4)
)
layout = dict(title = 'Test Plot',
xaxis = dict(title = 'Text Column'),
yaxis = dict(title = 'Percent'),
)
data = [trace0]
fig = dict(data=data, layout=layout)
py.offline.plot(fig, filename = 'Test_Plot.html')
I am looking to add another column's data to the text param. I can accomplish this by doing some list comprehensions but is there an easier/more efficient way to do this?
I am looking for an output similar to what is below but in a more efficient way than using list comprehension:
# column values to list
num = list(df['Number Column'])
age = list(df['Mean Age'])
# trace for Percent
trace0 = go.Scatter(
x = df.index,
y = df['Percent'],
name = 'Percent',
# list comprehension to get the data to show
text = [f'Number Column: {x}; Mean Age: {y}' for x,y in list(zip(num, age))],
mode = 'lines+markers',
line = dict(
color = ('rgb(0,0,255)'), # blue
width = 4)
)
layout = dict(title = 'Test Plot',
xaxis = dict(title = 'Text Column'),
yaxis = dict(title = 'Percent'),
)
data = [trace0]
fig = dict(data=data, layout=layout)
py.offline.plot(fig, filename = 'Test_Plot_Output.html')
You could also do something along the lines of the following:
trace0 = go.Scatter(
x = df.index,
y = df['Percent'],
name = 'Percent',
# string concatenation in pandas
# also the <br> puts the data on a new line in the hover text
text = "Number Column: " + df["Number Column"].astype(str) + "<br>Mean Age: " + df["Mean Age"].astype(str),
mode = 'lines+markers',
line = dict(
color = ('rgb(0,0,255)'), # blue
width = 4)
)

Categories

Resources