简体   繁体   中英

My first plot overlapping my second plot on nested for loop (Python/Plotly)

I'm having a hard time understanding this nested for-loop problem, I want to make automated plot using the nested for-loop in plotly, but my first graph resulted from first loop overlapping my second graph

Here is my code

#Read all the well log data
paths = sorted(glob.glob(os.path.join("well_contoh", "*.LAS")))
well_df = [0]*2
for i in range(len(paths)):
    well = lasio.read(paths[i])
    df = well.df()
    well_df[i] = df.reset_index()
well1, well2 = well_df #only 2 wells


#Automatic well log plots if any well log data comes in in the future
html_list = []
dataframe_well = {'Well 1F':well1, 'Well 2F':well2} #defining dataframe

wells = ['Well 1F','Well 2F'] #list of well for looping

#list of longitude and latitude for well 1 and well 2 respectively (a dummy coordinate)
Longitude = [96.083956, 96.356427]
Latitude = [5.456862, 5.328133]

#list of logs and their colors
logs = ['CALI', 'GR', 'RT', 'NPHI', 'RHOB', 'DT']
colors = ['black', 'green', 'red', 'royalblue', 'mediumaquamarine', 'goldenrod']

#plot
log_cols = np.arange(1,8)
logplot = make_subplots(rows=1, cols=len(logs), shared_yaxes = True, specs=[[{},{},{},{},{},{}]], 
                        horizontal_spacing=0.005)

for i in range(len(wells)):
    for j in range(len(logs)):
        if j == 2:
            logplot.add_trace(go.Scatter(x=dataframe_well[wells[i]][logs[j]], y=dataframe_well[wells[i]]['DEPTH'], name=logs[j], line_color=colors[j]), row=1, col=log_cols[j])
            logplot.update_xaxes(type='log', row=1, col=log_cols[j], title_text=logs[j], tickfont_size=12, linecolor='#585858')
        else:
            logplot.add_trace(go.Scatter(x=dataframe_well[wells[i]][logs[j]], y=dataframe_well[wells[i]]['DEPTH'], name=logs[j], line_color=colors[j]), row=1, col=log_cols[j])
            logplot.update_xaxes(col=log_cols[j], title_text=logs[j], linecolor='#585858')
    
    logplot.update_xaxes(showline=True, linewidth=2, linecolor='black', mirror=True, ticks='inside', tickangle=45)
    logplot.update_yaxes(tickmode='linear', tick0=0, dtick=250, showline=True, linewidth=2, ticks='outside', mirror=True, linecolor='black')
    logplot.update_yaxes(row=1, col=1, autorange='reversed')
    logplot.update_layout(height=700, width=800, showlegend=False)
    logplot.update_layout(
                 title_text="Example of " + '<b>' + str(wells[i]) + '</b>', #Add a chart title
                 title_font_family="Arial",
                 title_font_size = 25, title_x=0.5)

    logplot.write_html('fig'+str(wells[i])+'.html') # the plot is automatically saved as html

    #list html plots to show what pop up folium should show on the map
    html_list.append('fig'+str(wells[i])+'.html')

and the resulted plot for the second iterate, which Well 2F (overlapped image) , is this

重叠图像

the plot should be something like this (non-overlapping image)

非重叠图像

Well 2F plot seems to be overlapped by Well 1F plot, which is the problem here must be the nested loop that I use for

Here is the dummy data if someone wanna try it

https://drive.google.com/drive/folders/1DCnNpXpgqVCYNaMiD7FX6CpVqsOl3mkX?usp=share_link

Anyone has the idea how to solve this problem? Thanks!

The error seems to be caused by a problem with the log setting of the x-axis, so the log setting of the x-axis was set in a single row.

import plotly.graph_objects as go
from plotly.subplots import make_subplots

logplot = make_subplots(rows=1,
                        cols=len(logs),
                        shared_yaxes = False,
                        #specs=[[{},{},{},{},{},{}]], 
                        horizontal_spacing=0.08,
                        vertical_spacing=0.08
                       )

for i in range(len(wells)):
    for j in range(len(logs)):
        logplot.add_trace(go.Scatter(
            x=dataframe_well[wells[i]][logs[j]],
            y=dataframe_well[wells[i]]['DEPTH'],
            name=logs[j],
            line_color=colors[j]),
                          row=1, col=log_cols[j])

        logplot.update_xaxes(showline=True, linewidth=2, linecolor='black', mirror=True, ticks='inside', tickangle=45)
        logplot.update_yaxes(tickmode='linear', tick0=0, dtick=250, showline=True, linewidth=2, ticks='outside', mirror=True, linecolor='black')
        logplot.update_yaxes(row=1, col=1, autorange='reversed')
        logplot.update_layout(height=700, width=800, showlegend=False)
        logplot.update_layout(
                     title_text="Example of " + '<b>' + str(wells[i]) + '</b>', #Add a chart title
                     title_font_family="Arial",
                     title_font_size = 25, title_x=0.5)
        logplot.update_layout(xaxis3=dict(type='log')) # update
        logplot.write_html('fig'+str(wells[i])+'.html') # the plot is automatically saved as html

        #list html plots to show what pop up folium should show on the map
    html_list.append('fig'+str(wells[i])+'.html')
    logplot.show()

在此处输入图像描述

Found the solution, if you want to plot using Plotly and for-looping it to make it automated multiple plot by only using single code run, you have to define it as a new function and loop through your defined function, and you must clear the plot content before turn into second loop, otherwise the second plot will be overlapped by first plot

in the first loop, put this before entering the second loop

logplot.data = []

here is the full code

def wellplot(wellx, title): #Update (defined function)
    for j in range(len(logs)):
        if j == 2: #change to log for RT
            logplot.add_trace(go.Scatter(
                x=wellx[logs[j]], 
                y=wellx['DEPTH'], 
                name=logs[j], 
                line_color=colors[j]), 
                            row=1, col=log_cols[j])
            logplot.update_xaxes(type='log', row=1, col=log_cols[j], title_text=logs[j], tickfont_size=12, linecolor='#585858')
        else:
            logplot.add_trace(go.Scatter(
                x=wellx[logs[j]],
                y=wellx['DEPTH'], 
                name=logs[j], 
                line_color=colors[j]), row=1, col=log_cols[j])
            logplot.update_xaxes(col=log_cols[j], title_text=logs[j], linecolor='#585858')

    logplot.update_xaxes(showline=True, linewidth=2, linecolor='black', mirror=True, ticks='inside', tickangle=45)
    logplot.update_yaxes(tickmode='linear', tick0=0, dtick=250, showline=True, linewidth=2, ticks='outside', mirror=True, linecolor='black')
    logplot.update_yaxes(row=1, col=1, autorange='reversed')
    logplot.update_layout(height=700, width=700, showlegend=False)
    logplot.update_layout(
                title_text="Example of " + '<b>' + title + '</b>', #Add a chart title
                title_font_family="Arial",
                title_font_size = 25, title_x=0.5)
    
    logplot.write_html('fig'+title+'.html') # the plot is automatically saved as html
    #list html plots to show what pop up folium should show on the map
    html_list.append('fig'+title+'.html')
    logplot.show()

for i in range(len(wells)):
    logplot.data = [] #put this to clear the plot content (in order to make it non-overlapping)
    wellplot(dataframe_well[wells[i]], wells[i])

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM