How to do a chart like this one

hello guys i was trying in the past few days to learn plotly.py and i try to make plots i found on the internet with plotly one of these plots was this one

https://journals.plos.org/ploscompbiol/article/figure?id=10.1371/journal.pcbi.1003833.g004
my code trying to copy it

draft_template = go.layout.Template()
x = np.linspace(-np.pi, np.pi, 300)
fig=go.Figure()
fig.update_layout(template=draft_template
                 ,showlegend=True
                 ,xaxis=go.layout.XAxis(
                       range=[-np.pi-0.3, np.pi+0.3],
                       tickvals=[-np.pi,-np.pi/2, np.pi/2, np.pi],
                       ticktext=['$-\pi$', '$-\pi/2$', '$+\pi/2$', '$+\pi$'],
                       showgrid=False)
                 ,yaxis=go.layout.YAxis(
                        range=[-1.11, 1.11],
                       tickvals=[-1, 0, 1],
                       ticktext=['$-1$', '$0$', '$1$'],
                       showgrid=False)
                 ,legend=dict(x=.1, y=1
                             ,itemsizing='constant'))

fig.add_trace(go.Scatter(x=x
                        ,y=np.sin(x)
                        ,name='<b>sin</b>'
                        ,line=dict(color='red', width=4)))

fig.add_trace(go.Scatter(x=x
                        ,y=np.cos(x)
                        ,name='<b>cosine</b>'
                        ,line=dict(color='blue', width=4)))
fig.show()

i have a few problems with this one

  • i try to make xaxis and yaxis tick text in the middle

  • when i use <\b>’ to make tick text bold it doesn’t work for some reason

  • i can’t change the arrow properties like i can do in matplotlib

https://jakevdp.github.io/PythonDataScienceHandbook/04.09-text-and-annotation.htm

  • the red line become a blue after it went under zero how can i do this in plotly

and last sorry for my bad English

Welcome to Plotly @mahmoud,

To get that matplotlib plot, I suggest to use annotations instead of tickvals/ticktext:

import numpy as np
from numpy import pi, sin, cos
import plotly.graph_objects as go
import plotly.io as pio
pio.templates.default = "none"

x = np.linspace(-pi, pi,100)

cosgraph = go.Scatter(x=x, y=cos(x), 
                      mode='lines', 
                      line_width=2, line_color='blue', 
                      name='cosine')

singraph = go.Scatter(x=x, y=sin(x), 
                      mode='lines', 
                      line_width=2, line_color='red', 
                      name='sine')

dots = go.Scatter(x=[2*pi/3, 2*pi/3],
                  y=[-1/2, np.sqrt(3)/2],
                  mode='markers',
                  marker_color=['blue', 'red'], marker_size=6,
                  name='',
                  showlegend=False)

blue_line = go.Scatter(x= [2*pi/3, 2*pi/3],#blue dashed  line
                     y =[0, -1/2],
                     mode='lines',
                     line_width=1.5,
                     line_color='blue',
                     line_dash='dash',
                     showlegend=False)

red_line =go.Scatter(x=[2*pi/3, 2*pi/3],#red dashed line
                     y=[0, np.sqrt(3)/2],
                     mode='lines',
                     line_width=1.5,
                     line_color='red',
                     line_dash='dash',
                    showlegend=False)

#define data for annotations
xa = [-pi, -pi/2, 0, pi/2, pi]
textxa = ['$-\\pi$]', '$-\\pi/2$]', '$0$]', '$\\pi/2$]', '$\\pi$]']
ya =[-1,  1]

axis_style=dict(showline=False, zeroline=True, 
                showticklabels=False, ticks='', 
                showgrid=False)

annot_cos = '$\\cos\\left(\\displaystyle\\frac{2\\pi}{3}\\right)=-\\displaystyle\\frac{1}{2}$'
annot_sin = '$\\sin\\left(\\displaystyle\\frac{2\\pi}{3}\\right)=\\displaystyle\\frac{\\sqrt{3}}{2}$'

layout = go.Layout(width=600, height=450,
                   font_size=13,
                   xaxis = axis_style,
                   yaxis = axis_style,
                   hovermode='closest',
                   legend_x= 0,
                   legend_y=0.85,
                    annotations=[dict(x=xa[k],
                                    y=-0.1,
                                    xref="x",
                                    yref="y",
                                    text=textxa[k],
                                    showarrow=False) for k in range(len(xa))]+\
                                [dict(x=-0.15,
                                    y=ya[m],
                                    xref="x",
                                    yref="y",
                                    text=ya[m],
                                    showarrow=False) for m in range(len(ya))]+\
                                [dict(x= 2*pi/3,
                                    y = -1/2,
                                    xref="x",
                                    yref="y",
                                    text=annot_cos,
                                    showarrow=True,
                                    arrowhead=3,
                                    ax=-32,
                                    ay=40)]+\
                                [dict(x= 2*pi/3,
                                    y = np.sqrt(3)/2,   
                                    xref="x",
                                    yref="y",
                                    text=annot_sin,
                                    showarrow=True,
                                    arrowhead=3,
                                    ax=60,
                                    ay=-40)])

fig = go.Figure(data=[cosgraph, singraph, blue_line, red_line, dots], layout=layout)

img-sin-cos

I didn’t insert + in front of \pi/2, and \pi, because usually positive numbers are written without the sign β€˜+’.
Plotly draws only linear tails for arrows, not curved ones, too.

For more annotation attributes, print:

help(go.Layout.annotations).

1 Like