Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -431,7 +431,7 @@ except ET.ParseError as e:
|
|
431 |
# -------------------------------
|
432 |
# Tabs for Different Views
|
433 |
# -------------------------------
|
434 |
-
tabs = st.tabs(["Raw XML", "DataFrame", "Diplomatic Edition", "Editor Edition", "Visualization"])
|
435 |
|
436 |
# -------------------------------
|
437 |
# Raw XML Tab
|
@@ -709,6 +709,162 @@ with tabs[4]:
|
|
709 |
place_desc = places_dict.get(row['Origin_ID'], {}).get('Description', "No description available.")
|
710 |
st.markdown(f"**Place Description**: {place_desc}")
|
711 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
712 |
# -------------------------------
|
713 |
# Footer
|
714 |
# -------------------------------
|
|
|
431 |
# -------------------------------
|
432 |
# Tabs for Different Views
|
433 |
# -------------------------------
|
434 |
+
tabs = st.tabs(["Raw XML", "DataFrame", "Diplomatic Edition", "Editor Edition", "Visualization", "Authority Connections"])
|
435 |
|
436 |
# -------------------------------
|
437 |
# Raw XML Tab
|
|
|
709 |
place_desc = places_dict.get(row['Origin_ID'], {}).get('Description', "No description available.")
|
710 |
st.markdown(f"**Place Description**: {place_desc}")
|
711 |
|
712 |
+
with tabs[5]:
|
713 |
+
st.subheader("Authority Connections")
|
714 |
+
|
715 |
+
# Define Authority Types
|
716 |
+
authority_types = ["Material", "Place"] # Extend this list if you include Titles in the future
|
717 |
+
|
718 |
+
# Select Authority Type
|
719 |
+
selected_authority_type = st.selectbox("Select Authority Type", authority_types)
|
720 |
+
|
721 |
+
# Based on selection, provide the corresponding options
|
722 |
+
if selected_authority_type == "Material":
|
723 |
+
# List all materials from materials_dict
|
724 |
+
material_names = [material['Name_EN'] for material in materials_dict.values()]
|
725 |
+
selected_material = st.selectbox("Select Material", sorted(material_names))
|
726 |
+
|
727 |
+
# Find the material ID based on the selected name
|
728 |
+
material_id = None
|
729 |
+
for id_, material in materials_dict.items():
|
730 |
+
if material['Name_EN'] == selected_material:
|
731 |
+
material_id = id_
|
732 |
+
break
|
733 |
+
|
734 |
+
if material_id:
|
735 |
+
# Filter inscriptions that reference this material
|
736 |
+
connected_inscriptions = df[df['Material_ID'] == material_id]
|
737 |
+
|
738 |
+
st.markdown(f"### Inscriptions using **{selected_material}**")
|
739 |
+
st.write(f"**Total Inscriptions:** {len(connected_inscriptions)}")
|
740 |
+
|
741 |
+
if not connected_inscriptions.empty:
|
742 |
+
# Display inscriptions in a table
|
743 |
+
st.dataframe(connected_inscriptions[['Number', 'Publisher', 'Origin', 'Language', 'Dating', 'Encoder']])
|
744 |
+
|
745 |
+
# Optional: Visualization - Number of Inscriptions per Year (Dating)
|
746 |
+
st.markdown("#### Inscriptions Over Time")
|
747 |
+
# Assuming 'Dating' is in a format that can be processed (e.g., single year or range)
|
748 |
+
# For simplicity, we'll extract the starting year
|
749 |
+
def extract_start_year(dating):
|
750 |
+
if isinstance(dating, str):
|
751 |
+
parts = dating.split('to')
|
752 |
+
try:
|
753 |
+
return int(parts[0].strip())
|
754 |
+
except:
|
755 |
+
return None
|
756 |
+
return None
|
757 |
+
|
758 |
+
connected_inscriptions['Start_Year'] = connected_inscriptions['Dating'].apply(extract_start_year)
|
759 |
+
year_counts = connected_inscriptions['Start_Year'].dropna().astype(int).value_counts().sort_index()
|
760 |
+
|
761 |
+
fig, ax = plt.subplots()
|
762 |
+
ax.bar(year_counts.index, year_counts.values, color='skyblue')
|
763 |
+
ax.set_xlabel('Year')
|
764 |
+
ax.set_ylabel('Number of Inscriptions')
|
765 |
+
ax.set_title(f'Number of Inscriptions Using {selected_material} Over Time')
|
766 |
+
st.pyplot(fig)
|
767 |
+
|
768 |
+
# Optional: Network Graph
|
769 |
+
st.markdown("#### Network Graph of Inscriptions and Materials")
|
770 |
+
G = nx.Graph()
|
771 |
+
|
772 |
+
# Add nodes
|
773 |
+
G.add_node(selected_material, type='Material')
|
774 |
+
for _, row in connected_inscriptions.iterrows():
|
775 |
+
inscription_node = f"Inscription {row['Number']}"
|
776 |
+
G.add_node(inscription_node, type='Inscription')
|
777 |
+
G.add_edge(selected_material, inscription_node)
|
778 |
+
|
779 |
+
# Define node colors based on type
|
780 |
+
color_map = []
|
781 |
+
for node in G:
|
782 |
+
if G.nodes[node]['type'] == 'Material':
|
783 |
+
color_map.append('lightblue')
|
784 |
+
else:
|
785 |
+
color_map.append('lightgreen')
|
786 |
+
|
787 |
+
# Draw the graph
|
788 |
+
plt.figure(figsize=(8, 6))
|
789 |
+
nx.draw(G, with_labels=True, node_color=color_map, node_size=1500, font_size=10, font_weight='bold')
|
790 |
+
st.pyplot(plt)
|
791 |
+
plt.close()
|
792 |
+
|
793 |
+
else:
|
794 |
+
st.info("No inscriptions found for the selected material.")
|
795 |
+
|
796 |
+
elif selected_authority_type == "Place":
|
797 |
+
# List all places from places_dict
|
798 |
+
place_names = [place['Name'] for place in places_dict.values()]
|
799 |
+
selected_place = st.selectbox("Select Place", sorted(place_names))
|
800 |
+
|
801 |
+
# Find the place ID based on the selected name
|
802 |
+
place_id = None
|
803 |
+
for id_, place in places_dict.items():
|
804 |
+
if place['Name'] == selected_place:
|
805 |
+
place_id = id_
|
806 |
+
break
|
807 |
+
|
808 |
+
if place_id:
|
809 |
+
# Filter inscriptions that originate from this place
|
810 |
+
connected_inscriptions = df[df['Origin_ID'] == place_id]
|
811 |
+
|
812 |
+
st.markdown(f"### Inscriptions from **{selected_place}**")
|
813 |
+
st.write(f"**Total Inscriptions:** {len(connected_inscriptions)}")
|
814 |
+
|
815 |
+
if not connected_inscriptions.empty:
|
816 |
+
# Display inscriptions in a table
|
817 |
+
st.dataframe(connected_inscriptions[['Number', 'Publisher', 'Material', 'Language', 'Dating', 'Encoder']])
|
818 |
+
|
819 |
+
# Optional: Visualization - Inscriptions Geographical Distribution
|
820 |
+
st.markdown("#### Geographical Distribution of Inscriptions")
|
821 |
+
map_df = connected_inscriptions[['Latitude', 'Longitude', 'Number']]
|
822 |
+
map_df = map_df.dropna(subset=['Latitude', 'Longitude'])
|
823 |
+
|
824 |
+
if not map_df.empty:
|
825 |
+
# Create a Folium map centered on the selected place
|
826 |
+
selected_place_coords = [places_dict[place_id]['Latitude'], places_dict[place_id]['Longitude']]
|
827 |
+
folium_map = folium.Map(location=selected_place_coords, zoom_start=8)
|
828 |
+
|
829 |
+
for _, row in map_df.iterrows():
|
830 |
+
folium.Marker(
|
831 |
+
location=[row['Latitude'], row['Longitude']],
|
832 |
+
popup=f"Inscription {row['Number']}"
|
833 |
+
).add_to(folium_map)
|
834 |
+
|
835 |
+
st_folium(folium_map, width=700, height=500)
|
836 |
+
else:
|
837 |
+
st.info("No geographical data available for these inscriptions.")
|
838 |
+
|
839 |
+
# Optional: Network Graph
|
840 |
+
st.markdown("#### Network Graph of Inscriptions and Places")
|
841 |
+
G = nx.Graph()
|
842 |
+
|
843 |
+
# Add nodes
|
844 |
+
G.add_node(selected_place, type='Place')
|
845 |
+
for _, row in connected_inscriptions.iterrows():
|
846 |
+
inscription_node = f"Inscription {row['Number']}"
|
847 |
+
G.add_node(inscription_node, type='Inscription')
|
848 |
+
G.add_edge(selected_place, inscription_node)
|
849 |
+
|
850 |
+
# Define node colors based on type
|
851 |
+
color_map = []
|
852 |
+
for node in G:
|
853 |
+
if G.nodes[node]['type'] == 'Place':
|
854 |
+
color_map.append('salmon')
|
855 |
+
else:
|
856 |
+
color_map.append('lightgreen')
|
857 |
+
|
858 |
+
# Draw the graph
|
859 |
+
plt.figure(figsize=(8, 6))
|
860 |
+
nx.draw(G, with_labels=True, node_color=color_map, node_size=1500, font_size=10, font_weight='bold')
|
861 |
+
st.pyplot(plt)
|
862 |
+
plt.close()
|
863 |
+
|
864 |
+
else:
|
865 |
+
st.info("No inscriptions found for the selected place.")
|
866 |
+
|
867 |
+
|
868 |
# -------------------------------
|
869 |
# Footer
|
870 |
# -------------------------------
|